Skip to main content

Lack of data validation - Non Sanitized Variables

Need

Implementation of proper input validation and sanitization

Context

  • Usage of PHP for server-side scripting and web development
  • Usage of PHP for server-side scripting and web development

Description

Non compliant code

<?php
$command = 'ls ' . $_GET['dir'];
system($command);
?>

The above PHP code is vulnerable to a form of attack known as command injection. This vulnerability arises from the fact that the code is directly using the user-provided input ($_GET['dir']) in the construction of a system command without any form of sanitization or validation.

In this case, the $_GET['dir'] variable is being appended to the ls command, which lists files and directories in a specified directory. If a malicious user were to provide an input such as ; rm -rf /, the constructed command would become ls ; rm -rf /, effectively deleting all files in the root directory.

This is a severe security vulnerability, as it allows an attacker to execute arbitrary commands on the system with the permissions of the user running the PHP script. This could lead to unauthorized access, data loss, or even a complete system takeover.

To fix this vulnerability, the application should validate and sanitize all user inputs before using them in system commands. This can be done using built-in PHP functions or Laravel's validation and sanitization methods.

Steps

  • Validate the input: Ensure that the input matches a certain pattern or set of rules. For example, if the input is expected to be a directory name, ensure that it only contains valid characters for a directory name.
  • Sanitize the input: Remove or replace any characters or sequences of characters that could be used to inject malicious commands. This could include characters like semicolons, ampersands, and other special characters.
  • Use built-in functions: Instead of constructing system commands manually, use built-in PHP functions that can perform the same tasks. These functions are designed to handle inputs safely and are less likely to be vulnerable to injection attacks.
  • Limit permissions: Run the PHP script with the minimum necessary permissions. This can limit the damage that can be done if an attacker is able to inject malicious commands.
  • Use prepared statements: If you are interacting with a database, use prepared statements instead of concatenating user input into SQL queries. This can prevent SQL injection attacks.

Compliant code

<?php
$dir = $_GET['dir'];

// Validate the input
if (!preg_match('/^[a-zA-Z0-9-_]+$/', $dir)) {
die('Invalid directory name');
}

// Sanitize the input
$dir = escapeshellarg($dir);

// Use built-in function
$command = 'ls ' . $dir;
system($command);
?>

The updated code includes several measures to prevent command injection attacks:

  1. Input Validation: The preg_match function is used to ensure that the input only contains alphanumeric characters, hyphens, and underscores. This is a common pattern for directory names. If the input does not match this pattern, the script stops execution with the die function.

  2. Input Sanitization: The escapeshellarg function is used to sanitize the input. This function adds single quotes around a string and escapes any existing single quotes, making it safe to use in a shell command.

  3. Use of Built-in Function: The system function is a built-in PHP function that can execute shell commands. By using this function instead of manually constructing commands, we can reduce the risk of command injection attacks.

Note: This code assumes that the PHP script is run with limited permissions, which is a good security practice. If an attacker is able to inject a malicious command, the damage they can do is limited by the permissions of the PHP script.

Also, if this code was interacting with a database, it would be recommended to use prepared statements to prevent SQL injection attacks. However, as this code is not interacting with a database, this measure is not included in the code.

References