As a red teamer or pen tester, you need to understand web application security and how to protect against common vulnerabilities. Two of the most common web application vulnerabilities are Cross-Site Request Forgery (CSRF) and Cross-Site Scripting (XSS). These vulnerabilities can be exploited by attackers to steal sensitive information or execute malicious code on the user’s browser. In this article, we’ll take a deep dive into CSRF and XSS vulnerabilities and explore effective ways to prevent them.

What is Cross-Site Request Forgery (CSRF)?

Cross-Site Request Forgery (CSRF) is a type of web application vulnerability that occurs when a malicious website or email sends a request to a web application on behalf of the user. This is possible because the web application relies on cookies or other authentication credentials to identify the user. The attacker tricks the user into visiting a malicious website or clicking on a malicious link, which then sends a request to the vulnerable web application. The request appears to be legitimate because it includes the user’s authentication credentials.

Here’s an example of a CSRF attack:

  1. The victim logs in to a vulnerable web application and receives a session cookie.
  2. The attacker sends an email to the victim with a link to a malicious website.
  3. The victim clicks on the link, which sends a request to the vulnerable web application.
  4. The vulnerable web application processes the request because it includes the victim’s session cookie.
  5. The attacker gains access to the victim’s account and can perform any action on behalf of the victim.

CSRF attacks can be prevented by implementing CSRF tokens. A CSRF token is a unique value that is generated by the server and included in the HTML form or URL. The server verifies the CSRF token before processing the request, which prevents the attacker from using a stolen session cookie to submit a forged request.

Here’s an example of how to implement CSRF protection in PHP:

<?php
session_start();

// Generate a CSRF token and store it in the session
if (!isset($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

// Include the CSRF token in the HTML form
echo '<form action="process.php" method="POST">';
echo '<input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '">';
echo '<input type="text" name="username">';
echo '<input type="password" name="password">';
echo '<input type="submit" value="Login">';
echo '</form>';

// Verify the CSRF token before processing the request
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
    die('Invalid CSRF token');
}

// Process the request
$username = $_POST['username'];
$password = $_POST['password'];
// ...
?>

In this example, we generate a random CSRF token and store it in the session. We include the CSRF token in the HTML form using a hidden input field. When the user submits the form, we verify that the CSRF token in the request matches the one in the session before processing the request.

What is Cross-Site Scripting (XSS)?

Cross-Site Scripting (XSS) is a type of web application vulnerability that occurs when an attacker injects malicious code into a web page viewed by other users. The attacker can inject the malicious code by exploiting a vulnerability in the web application, such as a lack of input validation or output encoding. When a user views the infected web page, the malicious code executes on the user’s browser, which can lead to sensitive information theft or the execution of arbitrary code.

Here’s an example of an XSS attack:

  1. The attacker injects a script tag into a vulnerable web application.
  2. When a user views the infected web page, the script tag executes on the user’s browser.
  3. The script tag can steal the user’s session cookies, redirect the user to a malicious website, or perform other malicious actions.

XSS attacks can be prevented by implementing input validation and output encoding. Input validation ensures that user input meets expected criteria, such as length or format. Output encoding ensures that any user-generated content displayed in the web page is properly sanitized and cannot be interpreted as executable code by the browser.

Here’s an example of how to prevent XSS vulnerabilities in PHP:

<?php
$username = $_POST['username'];

// Validate the input to prevent XSS attacks
if (!preg_match('/^[a-zA-Z0-9]+$/', $username)) {
    die('Invalid username');
}

// Encode the output to prevent XSS attacks
echo 'Welcome, ' . htmlspecialchars($username) . '!';
?>

In this example, we use regular expressions to validate the username input and ensure that it only contains alphanumeric characters. We also use the htmlspecialchars function to encode any user-generated content displayed in the web page. This function replaces any special characters with their corresponding HTML entities, which prevents the browser from interpreting them as executable code.

Defense Against the Dark Arts (or How to Prevent CSRF and XSS)

Defenses against Cross-Site Request Forgery (CSRF) and Cross-Site Scripting (XSS) attacks are essential in securing web applications. In this section, we will explore various defense techniques for preventing CSRF and XSS attacks.

Defense Against CSRF Attacks

Implementing CSRF Tokens

The use of CSRF tokens is an effective defense against CSRF attacks. A CSRF token is a unique value that is generated by the server and included in the HTML form or URL. The server verifies the CSRF token before processing the request, which prevents the attacker from using a stolen session cookie to submit a forged request.

Here’s an example of how to implement CSRF protection in ASP.NET Core:

[ValidateAntiForgeryToken]
public IActionResult SubmitForm([FromForm] User user)
{
    // Code to process form data
    return View();
}

In this example, the ValidateAntiForgeryToken attribute ensures that the request includes a valid CSRF token before processing the form data.

Here’s an example of how to implement CSRF protection in Ruby on Rails:

<%= form_with(url: '/submit_form', method: 'post') do |form| %>
  <%= form.hidden_field :authenticity_token, value: form_authenticity_token %>
  <%= form.text_field :username %>
  <%= form.text_field :password %>
  <%= form.submit %>
<% end %>

In this example, the form_with helper generates an HTML form with a hidden field for the CSRF token. The form_authenticity_token method generates a unique CSRF token that is included in the form.

Enforcing SameSite Cookies

The SameSite attribute is used to prevent CSRF attacks by limiting the scope of cookies. By setting the SameSite attribute to Strict, the browser will only send cookies on requests that originate from the same site as the web application, which prevents third-party websites from using stolen cookies to perform CSRF attacks.

Here’s an example of how to enforce SameSite cookies in PHP:

session_set_cookie_params([
    'samesite' => 'strict',
    'secure' => true,
    'httponly' => true,
]);
session_start();

In this example, we set the samesite attribute to strict to enforce SameSite cookies. We also set the secure and httponly attributes to ensure that the session cookie is only sent over HTTPS and cannot be accessed by JavaScript, respectively.

Using ReCAPTCHA

ReCAPTCHA is a free service provided by Google that helps protect web applications from automated attacks, including CSRF attacks. ReCAPTCHA generates a challenge-response test that verifies that the user is a human and not a bot. By adding ReCAPTCHA to your web application, you can prevent automated CSRF attacks.

Here’s an example of how to use ReCAPTCHA in JavaScript:

grecaptcha.execute(sitekey, { action: "submit_form" }).then(function (token) {
    // Submit the form with the token
});

In this example, we use the grecaptcha.execute function to generate a challenge-response test. When the user completes the test, the function returns a token that can be included in the form submission to verify that the user is a human.

Defense Against XSS Attacks

Input Validation

Input validation is a crucial defense against XSS attacks. Input validation ensures that user input meets expected criteria, such as length or format. Input validation can prevent malicious input from being processed by the web application and prevent the execution of malicious code.

Here’s an example of how to perform input validation in Python:

import re

def validate_username(username):
    if not re.match(r'^[a-zA-Z0-9]{4,20}$', username):
        raise ValueError('Invalid username')
    return username

username = input('Enter your username: ')
validated_username = validate_username(username)
print('Welcome, ' + validated_username + '!')

In this example, we use the re module to perform a regular expression match on the username input. The regular expression ensures that the username contains only alphanumeric characters and is between 4 and 20 characters in length.

Output Encoding

Output encoding is another crucial defense against XSS attacks. Output encoding ensures that any user-generated content displayed in the web page is properly sanitized and cannot be interpreted as executable code by the browser. Output encoding can prevent malicious scripts from being executed by the browser.

Here’s an example of how to perform output encoding in Java:

String username = request.getParameter("username");
String encodedUsername = HtmlUtils.htmlEscape(username);
out.println("Welcome, " + encodedUsername + "!");

In this example, we use the HtmlUtils.htmlEscape method to encode the username input. The htmlEscape method replaces any special characters with their corresponding HTML entities, which prevents the browser from interpreting them as executable code.

Content Security Policy (CSP)

Content Security Policy (CSP) is a security feature that allows web developers to control which sources of content are allowed to execute in the browser. By setting a strict CSP policy, web developers can prevent the execution of malicious scripts and protect against XSS attacks.

Here’s an example of how to implement a CSP policy in HTML:

<meta
    http-equiv="Content-Security-Policy"
    content="default-src 'self'; script-src 'self' https://trusted-cdn.com;"
/>

In this example, we use the Content-Security-Policy header to set a CSP policy. The policy allows scripts to be loaded only from the same origin (‘self’) or from a trusted CDN (https://trusted-cdn.com).

Real-World Examples

Let’s take a look at some real-world examples of CSRF and XSS vulnerabilities and how they were exploited.

  1. Twitter Cross-Site Scripting (XSS) Attack

    In 2010, a self-proclaimed “ethical hacker” named Mike Bailey discovered an XSS vulnerability in Twitter that allowed him to steal user session cookies. Bailey injected a malicious script into his Twitter bio and used it to steal the session cookies of anyone who visited his profile. The vulnerability affected all Twitter users and allowed the attacker to take over any Twitter account.

    Twitter quickly patched the vulnerability and awarded Bailey a $5000 bug bounty for his discovery.

  2. MySpace Cross-Site Request Forgery (CSRF) Attack

    In 2005, a group of hackers discovered a CSRF vulnerability in MySpace that allowed them to add themselves as friends of any MySpace user without their consent. The attackers created a website that included a hidden form that submitted a friend request to MySpace on behalf of the victim.

    The attackers then tricked MySpace users into visiting their website, which automatically submitted the friend request using the victim’s session cookies. The attack affected millions of MySpace users and caused widespread panic.

    MySpace quickly patched the vulnerability and offered a $100,000 reward for information leading to the arrest and conviction of the attackers.

Conclusion

In conclusion, CSRF and XSS attacks are serious web application vulnerabilities that can lead to the theft of sensitive information, the execution of malicious code, and other security risks. However, implementing proper defense techniques can help prevent these attacks and protect web applications from malicious activity.

Effective defense techniques for CSRF attacks include the use of CSRF tokens, enforcing SameSite cookies, and implementing ReCAPTCHA. Proper input validation, output encoding, and Content Security Policy (CSP) are effective defense techniques against XSS attacks.

As a web developer or security professional, it is essential to have a thorough understanding of these defense techniques and how to implement them effectively. By taking proactive measures to secure web applications, we can help ensure the safety and security of users’ sensitive data and protect against the harmful effects of CSRF and XSS attacks.