Skip to main content

Stored cross-site scripting (XSS)

Need

Prevention of persistent cross-site scripting attacks

Context

  • Usage of PHP for server-side scripting and web development
  • Usage of Request for making HTTP requests
  • Usage of Item for representing and manipulating individual items or objects

Description

Non compliant code

public function store(Request $request)
{
$data = $request->all();
$item = new Item;
$item->name = $data['name'];
$item->description = $data['description'];
$item->save();
return redirect()->back();
}

This code is vulnerable to Stored XSS attacks. When a new Item is being created, the application is taking the user input from the request and directly saving it to the database without any sanitization or encoding. This means that if an attacker can control the value of name or description, they can inject arbitrary JavaScript code. When other users view this Item, the malicious JavaScript code will be executed in their browser.

For example, an attacker could submit the following values:

{
"name": "<script>/* malicious JavaScript code */</script>",
"description": "<script>/* malicious JavaScript code */</script>"
}

When other users view this Item, the malicious JavaScript code will be executed in their browser, leading to potential session theft, defacement of the website, or distribution of malicious software.

Steps

  • Sanitize input data: Use Laravel's built-in validation methods to sanitize the input data. This will ensure that any script tags or other potentially harmful input is stripped out before it is saved to the database.
  • Encode output: When displaying the data, make sure to use Laravel's built-in methods for encoding output. This will ensure that any potentially harmful scripts are not executed when the data is displayed.
  • Use prepared statements: When interacting with the database, use prepared statements. This will help to prevent SQL injection attacks.
  • Implement Content Security Policy (CSP): This is a security layer that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks.
  • Regularly update and patch your systems: Ensure that all your systems, including your Laravel framework, are regularly updated and patched. This will help to protect against known vulnerabilities.

Compliant code

public function store(Request $request)
{
$request->validate([
'name' => 'required|string|strip_tags',
'description' => 'required|string|strip_tags',
]);

$item = new Item;
$item->name = e($request->input('name'));
$item->description = e($request->input('description'));
$item->save();

return redirect()->back();
}

The above code fixes the stored cross-site scripting (XSS) vulnerability by implementing the following changes:

  1. Input Validation: The validate method is used to sanitize the input data. The required|string|strip_tags validation rule ensures that the 'name' and 'description' fields are required, should be of string type, and any HTML tags are stripped out before the data is processed further.

  2. Output Encoding: The e function is used to encode the output. This function runs htmlspecialchars over the input, which converts special characters to their HTML entities. This means that if a user tries to input a script tag, it will be displayed as plain text rather than being executed as JavaScript.

  3. Use of Prepared Statements: Laravel's Eloquent ORM uses prepared statements in the background. This means that when we're interacting with the database, we're already protected against SQL injection attacks.

  4. Content Security Policy (CSP): Implementing CSP is beyond the scope of this code snippet, but it's a good practice to add it in your application's headers. CSP helps to detect and mitigate certain types of attacks, including XSS and data injection attacks.

  5. Regular Updates and Patches: While not shown in the code, it's important to regularly update and patch your systems, including your Laravel framework. This will help to protect against known vulnerabilities.

References