Injection attacks refer to a broad class of attack vectors. Injection flaws occur when an attacker can send hostile data to an interpreter as part of a command or query. In turn, this alters the execution of that program.
The most common injection flaws are:
- Cross-Site Scripting (XSS)
- SQL injections (SQLi)
- Command injections which can lead to remote code execution (RCE) vulnerabilities
- LDAP injections
How to enforce
In general, preventing injection requires keeping data separate from commands and queries and using "whitelist" server-side input validation. (Source: OWASP Top 10)
Developers should validate data on input. This involves checking data types, ranges, lengths and expected values. The purpose of validation is to make sure that we receive what we expect to receive. Data should be further sanitized on output depending on context. Sanitization involves transforming the data to be safe in the output context.
Please read further to find out how to prevent specific cases of injection in ResourceSpace.
SQL injection (SQLi)
In ResourceSpace SQL injections can be prevented using escape_check($text) function. For escape_check() to be effective, all parameters included in SQL queries should be enclosed within single quotes, even if numeric.
Exemple #1: escape_check()
Imagine ResourceSpace uses untrusted data from the user (ie. getval()) to build the following SQL query:
$resource = sql_query("SELECT * FROM resource WHERE ref = '$ref'");
If the attacker would pass a ref value of ' or '1'='1 then the query would become:
SELECT * FROM resource WHERE ref = '' or '1'='1'
which will return all resources.
The solution is to escape_check() the $ref variable like so:
$resource = sql_query("SELECT * FROM resource WHERE ref = '" . escape_check($ref) . '");
Exemple #2: escape_check_array_values()
Whenever you need to use the values of an array inside a SQL statement, always use escape_check_array_values(array $unsafe_array). Please note, you will still have to ensure each value is wrapped within single quotes.
# Having an array like: $resource_types = array(1, 2, 3, "'SQLi possible"); # which will be used in a SQL statement as follows (NOTE: wrapping single quotes): $sql_filter .= "resource_type IN ('" . join("', '", escape_check_array_values($resource_types)) . "')";
Cross-Site Scripting (XSS)
There are three forms of XSS:
- Stored XSS: The application stores unsanitized user input that is viewed at a later time by another user or an administrator. Stored XSS is often considered a high or critical risk.
Preventing XSS requires separation of untrusted data from active browser content.
In ResourceSpace, we have agreed to apply the following rules:
- When echoing text to the screen that should not include html (e.g. $lang elements, error messages) then use htmlspecialchars();
- If the text you are outputting to screen can include valid html (e.g. rich text field metadata values) then use strip_tags_and_attributes();
OWASP maintains a better list of preventing XSS. For a better understanding and more comprehensive list, please visit the A7-Cross-Site Scripting (XSS) from Top 10.
Command injection is an attack in which the goal is execution of arbitrary commands on the host operating system via a vulnerable application. Command injection attacks are possible when an application passes unsafe user supplied data (forms, cookies, HTTP headers etc.) to a system shell.
In this attack, the attacker-supplied operating system commands are usually executed with the privileges of the vulnerable application.
Command injection attacks are possible largely due to insufficient input validation.
In ResourceSpace, developers should use the run_command($command, $geterrors = false, array $params = array()) function which, if used with the params argument it will automatically escapeshellarg() every single one of them before using it in the command.