CSRF
Cross-site request forgery (CSRF) is a web vulnerability that allows an attacker to induce users to perform actions that they do not intend to perform.
Tools and Resources
CSRF PoC Generator: https://csrf-poc-generator.vercel.app/
Setting an Attacker HTTP Server
To perform any CSRF exploitation, we need to host a webserver over HTTPS. To do that, you need a self-signed certificate for your server, which you can generate with:
openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodesModern browsers won't allow loading resources on a misconfigured HTTPS webserver using a self-signed certificate. This setup is just of testing purposes.
Then, you'll need a simple Python HTTPS server that configures CORS for incoming OPTIONS requests to enable POST requests from our payloads, and additionally logs incoming requests:
from http import server
import ssl
class CustomRequestHandler(server.SimpleHTTPRequestHandler):
def do_OPTIONS(self):
self.send_response(200)
self.send_header("Access-Control-Allow-Origin", "*")
self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
self.send_header("Access-Control-Allow-Headers", "Content-Type")
self.end_headers()
def do_GET(self):
super().do_GET()
def do_POST(self):
length = int(self.headers.get('Content-Length', 0))
body = self.rfile.read(length)
if body:
self.log_message("[i] POST body: %s", body.decode("utf-8", errors="replace"))
self.send_response(200)
self.end_headers()
print("Serving HTTPS on 0.0.0.0 port 443 (https://0.0.0.0:443/) ...")
httpd = server.HTTPServer(('0.0.0.0', 443), CustomRequestHandler)
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile='./server.pem')
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
httpd.serve_forever()Basic Payloads
Send a GET request to https://yourtarget.com/vulnerable.php?param1=value1
Send a POST request to https://yourtarget.com/vulnerable.php with param1=value1
Send a POST request with two JSON parameters
Leveraging CORS Misconfigurations
Arbitrary Origin Reflection
The Access-Control-Allow-Origin header contains the origins allowed to bypass the Same-Origin policy, making the browser allow the origin to access the web app's response.
Identifying the misconfiguration
To identify a CORS misconfiguration that reflects arbitrary origins, edit your request and add any arbitrary domain to the request's Origin header, then, send the request and check if the domain is included in the Access-Control-Allow-Origin response header.
The header can be set to a wildcard (*), which results in all origins being granted a Same-Origin policy bypass. Notice that, for security reasons, the wildcard origin cannot be combined with the Access-Control-Allow-Credentials: true
Note: A combination of origin and wildcard, such as https://*.example.com is not valid!
To exploit this misconfiguration, you will need to host the following payload on your attacker server:
You don't need to set the Origin header: the browser will automatically set it to your attacker server's domain.
Then, supposing a victim is authenticated to the misconfigured-cors web application, and navigates to your server's page where the payload is hosted, they will automatically send a request to the vulnerable web application and you will receive a request containing a base64 value corresponding to the web application's response.
If the server's Access-Control-Allow-Credentials header is set to true, you can potentially make authenticated requests in the victim's context, potentially gaining access to sensitive user-related information and allowing actions to be performed on behalf of the victim.
Trusted null origin
The Access-Control-Allow-Origin header not only supports a trusted origin and a wildcard but also the value null, which indicates the null origin. Although this should not be used in practice, some web applications may implement it due to a misconception of its meaning.
An attacker can employ various methods to force a null origin on a cross-origin request, which is subsequently trusted, resulting in a Same-Origin policy exception.
To exploit this, check whether the null Origin is reflected. If it works, you can enforce a null origin using a sandboxed iframe
Targeting internal Assets
Even if the web application does not configure CORS to allow credentials, an attacker might still be able to target web applications running in a local network behind a firewall, reverse proxy, or NAT that are not publicly accessible.
Data exfiltration may be possible if these do not require authentication and contain a CORS misconfiguration that trusts the attacker's origin.
The next payload can work if the victim opening it is in the same internal network as the internal asset:
Bypassing CSRF Tokens
If CORS is misconfigured to allow cross-origin requests with credentials (Access-Control-Allow-Credentials: true) and reflects an attacker-controlled origin via the Access-Control-Allow-Origin header, CSRF token protections can be bypassed, provided that the userβs session cookies are set with SameSite=None and Secure.
This allows an attacker to issue an authenticated cross-origin request to an endpoint that generates a valid CSRF token, read the token from the response, embed it into a subsequent state-changing cross-origin request, and successfully perform the action on behalf of the victim.
Since all requests are executed within the victimβs authenticated session, the CSRF token remains valid even if it is properly tied to the user session.
Other Misconfigurations
Bypassing SameSite Cookies
The SameSite cookie attribute is sent according to the request's source site attribute, instead of using the origin that is normally considered by the Same Origin Policy.
The key difference between site and origin is that the port and subdomain are not considered part of the site, meaning that two domains are considered the same site, even if the port and subdomain differ.
Bypassing Lax SameSite cookies
You can leverage the Lax declaration to circumvent restrictions imposed by SameSite cookies.
Lax SameSite cookies are only sent with safe requests, such as GET requests.
If the web application contains any endpoints that are state-changing and are accessed with GET requests, the SameSite protection is ineffective to prevent CSRF attacks.
Bypassing Strict SameSite cookies
Client-side redirections are initiated by the starting site, meaning that the redirection is considered SameSite and allows sending the victim's cookies with the request, even if they are set as Strict SameSite.
If you can redirect the victim to a misconfigured endpoint that accepts GET requests for state-changing operations, you can execute a successful CSRF attack.
Weak CSRF Tokens
Simple bypasses to weak tokens can occur when:
the CSRF token is not tied to a user session: In that case, an attacker accessing the vulnerable web application can add a valid CSRF token to the cross-origin request from their own session.
CSRF tokens are not entirely random, or the generation algorithm is predictable: depending on how token is created, we might be able to guess it in a single attempt or brute-force it. For example, some tokens may be generated based on the current Unix Timestamp.