Cross-Site Request Forgery. Notes are heavily inspired by that on PortSwigger, Bug bounty reports, HackerOne, and Internet.
There are three conditions which should be in place for CSRF to work:
- Relevant action
- Cookie-based session handling (nothing other than cookies validating the user requests)
- assuming the SameSite Cookies defense are NOT in place (SameSite is a browser mechanism that determines when a website's cookies are included in a request). Chrome, by default, enforces so.
- No unpredictable params
<html>
<body>
<!-- sending the request to vulnerable website -->
<form action="https://vulnerable-website.com/email/change" method="POST">
<input type="hidden" name="email" value="[email protected]" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
CSRF defenses are applied both on the browser level and on the client side. Some of the most common defenses are
-
CSRF tokens (secrets shared by the server on the client side to make sure the requests come from the user)
- are they tied to the session token?
-
SameSite Cookies (whether or not should a browser send, Chrome used SameSite Cookie
Lax
by default) -
Referer-based Validation: This is where the referer of the request is checked but is less secure.
These are unpredictable tokens added to each sensitive request or action performed by the user.
Issues which arise because of flawed Validation (ref PortSwigger labs: bypassing token validation)
- Flaw1: the CSRF token validation is based on the GET/POST method
- Validation is based on whether or not the token is present
- CSRF token is not tied to the session token (any CSRF from the global pool, a hacker could login in to their own account and use that token to frame a CSRF attack)
- CSRF token is tied to a non-session token (this occurs because the session management and tokens work on different framework, if somehow attacker can set a cookie on the users browser, they can use their own cookie value and token to cause a CSRF) ex:
/?search=test%0d%0aSet-Cookie:%20csrfKey=YOUR-KEY%3b%20SameSite=None
- CSRF Cookie is simply a duplicate in the cookie (this mean no server side, check if you can set the cookie, you can bypass all CSRF defenses)
SameSite Cookie issues: SameSite Cookie problems
- Valid GET based operation or a method override like so
POST /sensitive/operation?_method=GET
- Vulnerable sister/domains
- Token refresh, as seen in the case of SSO
- Depends on whether or not the header exists
- Naive check on the header value
- Issue1: Simple CSRF issue (check issue:1) to read more about it.
- the `SameSite="Lax" only works for POST forms, if a website is vulnerable to CSRF through GET, it will still work (check issue2)
Either we can use csrf or use csrf-csrf or use helmet
Using the csrf package
- Package was published 4 years ago,
- OSS Scorecard score: 3.7,
- Snyk Package Advisor 68/100 (couldn't find badge support for Snyk)
- Sign-up functionality was completed read why 409 was used here: #42
- Haven't corrected the logic for the cookie check and user check (bad checks on
req.cookies.username
on api end-points)
- Use a better linter, and stick to a coding style
- GitHub action to post a comment on a new PR