Jit- announcement icon

How can AppSec teams empower development orgs to deliver more secure code? We asked 150 developers.

Read the survey report

In this article

XSS vs. CSRF

Charlie Klein - Director of Product Marketing at Jit
By Charlie Klein

Updated February 7, 2025.

a purple background with the words how to protect against csrf and xss

Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF) attacks may operate quietly, but their impact is anything but subtle. If your web applications aren’t secure, these attacks can compromise user sessions, leak sensitive data, and escalate into large-scale breaches. And no industry is beyond their reach. 

Earlier in 2024, Ticketmaster's breach exposed sensitive data on 560 million customers. The stolen data included names, emails, addresses, phone numbers, ticket sales, and order details, and was put on sale for $500,000.

Vulnerabilities such as XSS and CSRF can significantly harm your organization and undermine user trust. To combat this, DevSecOps teams must understand these threats and prioritize security from the beginning of the development process. 

a man kneeling down next to a black and white floor


Source

What is XSS (Cross-Site Scripting)?

Cross-site scripting (XSS) is a vulnerability that lets attackers inject malicious scripts into web pages, which then execute in users’ browsers. By embedding JavaScript or HTML into trusted pages, attackers can steal session cookies, hijack login credentials, or access sensitive data without direct user interaction. Since these scripts run under the site’s trusted domain, they bypass typical security controls.

XSS attacks come in three primary forms:

  •  Stored XSS occurs when an attacker embeds malicious scripts into a target website’s database, delivered to users when they access specific pages. 
  • Reflected XSS works by embedding the script in a URL or a form submission. The script is then “reflected” back to the user as part of the webpage content. 
  • DOM-based XSS occurs when client-side JavaScript code processes data from an attacker-controlled source (like URL parameters or fragment identifiers) and passes it to a dangerous sink function (like innerHTML, eval, or document.write) without proper sanitization. Unlike server-side XSS variants, the malicious payload in DOM-based XSS is processed entirely by the client's browser without server involvement. For example, if your code uses JavaScript to read from window.location.hash and insert it into the DOM, an attacker could craft a URL that injects malicious scripts that execute in users' browsers.



A recent example from October 2024 involved hackers exploiting an XSS vulnerability in Roundcube Webmail, targeting government agencies in CIS countries. Attackers embedded malicious scripts into emails that triggered upon opening, allowing unauthorized access to sensitive data within the victims’ accounts.

a diagram of the xss example


Source

The Consequences of XSS Attacks and Why Prevention Matters

At their core, XSS attacks exploit trust, tricking users into thinking they’re interacting with legitimate content when, in reality, malicious scripts are being executed in their browsers. These scripts can hijack user sessions, allowing attackers to impersonate users, swipe sensitive data, or even escalate privileges within an application. For example, the 2021 Netgear router XSS vulnerability (CVE-2021-34991) allowed attackers to hijack administrative sessions by exploiting stored XSS in the router's web interface, potentially affecting millions of home and small business networks. 

In high-stakes apps like banking or healthcare, one XSS vulnerability can lead to severe breaches, exposing users and organizations to substantial financial and regulatory fallout. The risk of leaving XSS vulnerabilities unpatched is well-documented, with studies consistently ranking XSS among the most pervasive threats to web applications. 

For example, XSS vulnerabilities constitute up to 18% of all bug bounties on platforms like HackerOne. Unpatched XSS flaws allow repeated exploitation, eroding user trust and exposing applications to multiple attack cycles.

What is CSRF (Cross-Site Request Forgery)?

CSRF manipulates the trust a web application places in an authenticated user’s session, tricking the server into executing unauthorized actions on behalf of the user. Because the site trusts the user’s session, it processes the request without any additional checks, letting the attacker perform actions as if they were the user – often without the user even realizing it.

There are two main types of CSRF attacks:

1. State-Changing CSRF: Exploits how browsers automatically include cookies with requests

Example attack flow:   

- User logs into bank.com

- Visits malicious-site.com containing

<form action='bank.com/transfer' method='POST' hidden>
      	<input name='amount' value='1000'>
      	<input name='to' value='attacker'>
 </form>
  <script>document.forms[0].submit()</script>
- Form auto-submits with user's valid session cookie 

- Bank processes transfer due to valid session

2. Login CSRF: Forces user authentication to attacker-controlled account

Example attack flow:

  1. Attacker creates account on legitimate site

  2. Crafts malicious login form pointing to legitimate site

  3. When victim submits form, they're logged into attacker's account

Prevention for Login CSRF requires both anti-CSRF tokens and origin validation.

cross - site request for a bank account


For example, TeamCity's OAuth implementation vulnerability (CVE-2022-24065) allowed attackers to manipulate the OAuth state parameter during GitHub authentication flow. By injecting crafted query parameters in the callback URL, attackers could bind victim TeamCity accounts to attacker-controlled GitHub accounts. This vulnerability demonstrated how improper OAuth state validation can lead to account hijacking despite using standard OAuth 2.0 flows.

CSRF Attacks: The Risks and Importance of Prevention

Applications assume that authenticated requests are safe once a user is logged in. By piggybacking on this trust, attackers can send malicious requests that appear to come from the user’s session, leading to actions like account changes, unauthorized transfers, or sensitive data exposure. 

In enterprise environments, CSRF vulnerabilities can compromise access control by allowing attackers to issue high-privilege requests, potentially disrupting system operations or exposing internal data.

CSRF prevention is critical for preserving the integrity of high-stakes user actions and minimizing business impact, particularly in applications managing financial data, personal information, or elevated permissions.

a diagram of a process that shows the process of using a web application


Source

Key Differences Between XSS and CSRF

XSS and CSRF attacks work on two very different trust assumptions within web applications. XSS injects malicious scripts into trusted web pages. It relies on users assuming the site is safe and trusting the content they see on the page. In contrast, CSRF takes advantage of the server’s trust in the authenticated user, tricking the server into accepting unauthorized requests as legitimate.

Here's how they compare in a few other areas:

  • User Interaction: XSS typically needs user engagement, like clicking a link, to execute in the browser. CSRF requires that only the user be logged in.
  • Session Requirement: CSRF relies on the user being authenticated and using session cookies to issue requests. XSS can operate with or without a session, although an active session increases its reach.
  • Scope of Actions: XSS gives attackers direct control over the browser environment, allowing them to alter content, lift cookies, or access local storage – essentially anything on the page. CSRF is more limited, only executing actions that the authenticated user is allowed to perform.
  • Attack Initiation: Attackers embed XSS  in the site and usually inject it through input fields or manipulated URLs. CSRF comes from an external source, such as a crafted link or form on another site.
  • Risks: XSS poses a high risk of data theft and session hijacking in web applications, including those built with frameworks like Angular, single-page applications (SPAs), and dynamic platforms. CSRF’s primary risks lie in unauthorized actions, such as transferring funds or altering user settings.
a table with two different types of data


Source

Preventing XSS and CSRF in Modern DevOps Pipelines

In the fast-moving DevOps pipeline, constant code changes can create prime opportunities for XSS and CSRF vulnerabilities if you don’t embed security at every stage. Such vulnerabilities often slip through in code due to assumptions about input safety and trust in authenticated sessions. 

Framework-specific Security Features

Each modern web framework provides specific security features that must be properly implemented to prevent XSS and CSRF attacks. Here's how to leverage them effectively:

React applications should use JSX's built-in HTML escaping and never bypass it with dangerouslySetInnerHTML unless the HTML is from a completely trusted source. For dynamic content:

  • Use JSX curly braces for content insertion:

    <div>{userContent}</div>

  • For HTML content, use DOMPurify:

    <div dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(userHtml)}} />

  • Never concatenate user input into inline script tags

Django provides automatic XSS protection through template escaping and CSRF middleware:

  • Templates automatically escape HTML:

    {{ user_content }}

  • Forms require csrf_token:

    {% csrf_token %}

  • APIs need:

    @csrf_protect decorator

Rails similarly includes built-in protections that must be properly configured:

  • html_safe must only be used for trusted content

  • csrf_meta_tags required in layouts

  • protect_from_forgery needed in controllers

Content Security Policies (CSPs)

Content Security Policies provide crucial defense-in-depth against XSS attacks by controlling which resources can load and execute. Here's how to implement CSP effectively:

1. Start with a strict base policy:

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com; object-src 'none'

This policy:

  • Restricts all resources to your domain ('self')

  • Allows scripts only from your site and a trusted CDN

  • Blocks plugin content entirely

2. For inline scripts, use nonces instead of unsafe-inline:

Content-Security-Policy: script-src 'nonce-random123' <script 
nonce="random123">console.log('safe')</script>

3. Enable reporting while testing:

Content-Security-Policy-Report-Only: <your-policy> report-uri /csp-violations"

CSP Implementation Requirements:

1. Base configuration:

  • default-src 'self': Restrict resources to same origin

  • script-src: Specify allowed JavaScript sources

  • style-src: Control CSS sources

  • img-src:style-src: Define valid image sources

  • connect-src: Limit XHR/Fetch destinations

2. Nonce-based Script Control

  • Generate per-request nonce

  • Include in script-src directive

  • Add nonce attribute to legitimate scripts

3. Reporting:

  • Configure report-uri/report-to

  • Monitor violation reports

  • Adjust policy based on legitimate needs

a diagram of a computer security policy


Source

CSP Implementation Best Practices

1. Progressive Enhancement

   - Start with a permissive policy in report-only mode

   - Analyze violation reports to identify legitimate sources

   - Gradually tighten restrictions based on application needs

2. Common Gotchas

   - Avoid 'unsafe-inline' and 'unsafe-eval'

   - Be cautious with wildcard (*) sources

   - Consider impact on third-party integrations

3. Performance Considerations

   - Use nonce-based approach for dynamic scripts

   - Cache policy headers appropriately

   - Monitor policy size and evaluation overhead

For CSRF protection, implement double-submit cookie pattern using cryptographically secure tokens. Generate a random token using a secure algorithm (like SHA-256), store it in both a cookie and a hidden form field or custom header, then validate both values match server-side. Set cookie attributes SameSite=Lax (minimum) and HttpOnly. Critical for all state-changing requests including POST, PUT, DELETE operations. While GET requests should be idempotent by HTTP specification, they still need CSRF protection if they return sensitive data to prevent information disclosure attacks.

Automating security checks is a great way to verify that other best practices remain intact as code changes and new deployments roll out. Jit’s Open ASPM platform integrates tools like Semgrep and OSV-Scanner directly into your CI/CD pipeline, so you can catch issues as your application evolves. Semgrep scans for vulnerable patterns tied to XSS and CSRF – such as unsanitized fields or absent CSRF tokens – with every code push. 

Dependencies also handle user input or session management, so it’s vital not to overlook them. OSV-Scanner checks these libraries for known vulnerabilities, helping catch issues that might otherwise let XSS or CSRF exploits sneak into production.

Testing Security Controls

Here are some steps to take in order to validate XSS and CSRF protections:

Automated Testing:

  • Unit tests for input sanitization functions
  • Integration tests for CSRF token validation
  • API endpoint security validation

Manual Testing Scenarios:

  • Test all user input fields with XSS payloads
  • Verify CSRF token presence and validation
  • Check security header configurations

Production Monitoring

  • Enable CSP violation reporting
  • Monitor for unusual token validation failures
  • Track sanitization bypasses

Build Resilience Against XSS and CSRF with Jit

Regarding XSS and CSRF, the risks are anything but hypothetical – they’re entry points for real threats that can turn minor oversights into massive breaches. For DevSecOps teams, embedding strong security early is a safeguard against these attacks' very real financial and operational impact.

Jit helps teams tackle this by integrating tools like Semgrep and OSV-Scanner directly into CI/CD workflows, turning each code push into an opportunity to catch and mitigate risks tied to XSS and CSRF. With intelligent prioritization, Jit can help your team zero in on what matters, making security feel manageable even in fast-paced development environments.

Ready to secure your pipeline? Visit Jit.io to learn more.