Top 10 PHP Vulnerabilities You Need to Know: Beyond SQL Injection, XSS, and CSRF
The second article shifts focus to vulnerabilities that can alter server-side logic. We discuss Server-Side Template Injection (SSTI), where attackers exploit server template features to execute arbitrary code; Insecure Direct Object References (IDOR) that allow unauthorized access to objects; and Mass Assignment, a vulnerability that can overwrite object properties without proper filtering.
Server-Side Template Injection (SSTI)
Server-Side Template Injection (SSTI) is a critical vulnerability that occurs when user input is improperly sanitised and directly embedded into server-side templates, allowing attackers to execute arbitrary code.
Vulnerable Code:
$loader = new Twig_Loader_String();
$twig = new Twig_Environment($loader);
echo $twig->render($_GET['template'], $_GET['data']);
Explanation: The vulnerable code renders a Twig template based on user-supplied input ($_GET['template']
and $_GET['data']
). Attackers can exploit this to execute arbitrary code on the server.
Prevention:
$loader = new Twig_Loader_Array(array());
$twig = new Twig_Environment($loader);
$template = $_GET['template'];
$data = $_GET['data'];
// Validate and sanitize user input
if (preg_match('/^[a-zA-Z0-9_]+$/', $template) && is_array($data)) {
echo $twig->render($template, $data);
} else {
echo "Invalid input.";
}
Explanation: The prevention code validates and sanitizes the user input ($template
and $data
) before rendering the Twig template. It checks if $template
matches a safe pattern (alphanumeric and underscore) and ensures $data
is an array. This prevents SSTI by restricting the ability to execute arbitrary code.
Conclusion
SSTI vulnerabilities allow arbitrary code execution via template engines. Use secure loaders and validate inputs to prevent this.
Insecure Direct Object References (IDOR)
IDOR occurs when an application exposes internal object references (such as files, directories, database records) to users without proper access controls.
Vulnerable Code:
$userId = $_GET['id'];
$sql = "SELECT * FROM users WHERE id = $userId";
Explanation: In the vulnerable code, the script directly uses an ID parameter ($userId
) from the URL without proper authorisation checks, allowing unauthorised access to user data.
Prevention:
$userId = $_GET['id'];
// Validate authorization before accessing the user data
if ($userId == $_SESSION['user_id']) {
$sql = "SELECT * FROM users WHERE id = $userId";
// Execute SQL query securely
} else {
echo "Unauthorized access";
}
Explanation: In the prevention code, proper authorization checks are implemented (if ($userId == $_SESSION['user_id'])
) before accessing user data. This prevents IDOR by ensuring that the user can only access their own data.
Conclusion:
IDOR vulnerabilities can lead to unauthorised data access. Implement proper authorisation checks to prevent this.
Mass Assignment
Mass Assignment is a security vulnerability that occurs when an application blindly assigns user input to model attributes or object properties. This can lead to unintended modifications, privilege escalation, or unauthorized access to sensitive data. Understanding how to identify and prevent this vulnerability is crucial for maintaining the security of PHP applications.
Vulnerable Code:
class User {
public $id;
public $name;
public $email;
public $role; // Should be controlled internally, not by the user
public function __construct($data) {
foreach ($data as $key => $value) {
$this->$key = $value;
}
}
}
// Simulating user input
$userData = $_POST;
// Creating a new User object with user-supplied data
$user = new User($userData);
// Saving user to database (pseudo-code)
// saveToDatabase($user);
Vulnerable Request:
POST /register
Content-Type: application/x-www-form-urlencoded
name=alice&email=alice@example.com&role=admin
Explanation: An attacker adds a role=admin
parameter, gaining unauthorised admin access.
Prevention:
class User {
public $id;
public $name;
public $email;
private $role; // Restricted attribute
// Constructor with a whitelist of allowed fields
public function __construct($data) {
$allowedFields = ['name', 'email'];
foreach ($allowedFields as $field) {
if (isset($data[$field])) {
$this->$field = $data[$field];
}
}
}
// Method to set the role internally, with proper checks
public function setRole($role) {
if ($this->isValidRole($role)) {
$this->role = $role;
}
}
private function isValidRole($role) {
$validRoles = ['user', 'admin']; // Example valid roles
return in_array($role, $validRoles);
}
}
// Simulating user input
$userData = $_POST;
// Creating a new User object with user-supplied data
$user = new User($userData);
// Setting the role internally
$user->setRole('user'); // Default role
// Saving user to database (pseudo-code)
// saveToDatabase($user);
Explanation: Only assign user-supplied values to specific, intended attributes.
Prevention Techniques
To prevent mass assignment vulnerabilities, follow these secure coding practices:
- Whitelist Allowed Fields: Only assign user-supplied values to specific, intended attributes.
- Use Access Control Lists (ACLs): Implement ACLs to control what properties can be modified by different user roles.
- Use a Framework’s Built-in Protection: Many frameworks offer mechanisms to prevent mass assignment (e.g., Laravel’s
$fillable
property).
Conclusion
Mass Assignment vulnerabilities can have severe consequences, including unauthorised access and data manipulation. By implementing proper validation, explicitly defining mass assignable fields, and avoiding direct assignment of user inputs, developers can mitigate the risk of such vulnerabilities. Following these best practices ensures the integrity and security of your PHP applications.
Conclusion:
Exploring SSTI, IDOR, and mass assignment has shown us how attackers exploit server-side logic vulnerabilities. Developers must adopt rigorous validation and sanitation measures to guard against such sophisticated intrusions.
Conclusion Continuity:
Having secured the server-side logic, we will next shift our focus to vulnerabilities that interact directly with the user interface and networking layers of web applications.