Coding standards
Security in ResourceSpace
Developer reference
Database
Action functions
Admin functions
Ajax functions
Annotation functions
API functions
Collections functions
Comment functions
Config functions
CSV export functions
Dash functions
Debug functions
Encryption functions
Facial recognition functions
File functions
General functions
Language functions
Log functions
Login functions
Message functions
Migration functions
Node functions
PDF functions
Plugin functions
Render functions
Reporting functions
Request functions
Research functions
Slideshow functions
Theme permission functions
User functions
Video functions
Database functions
Metadata functions
Resource functions
Search functions
Map functions
Job functions
Tab functions
Test functions

Overview

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)

User input may be used in different contexts, and it needs to be treated differently depending on the context that it will be used in, be it HTML, Javascript, SQL or LDAP.

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 by using prepared statements.

When prepared statements can't be used (e.g table name in the FROM clause) then make sure to sanitise the input.

Cross-Site Scripting (XSS)

There are three forms of XSS:

  • Reflected XSS: The application includes unvalidated and unescaped user input as part of HTML output. A successful attack can allow the attacker to execute arbitrary HTML and JavaScript in the victim's browser.
  • 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.
  • DOM XSS: JavaScript frameworks, single-page applications, and APIs that dynamically include attacker-controllable data to a page are vulnerable to DOM XSS.

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 escape();
    • IF the variables' type you  want to escape is an integer, then you can just cast it to an int. e.g: 
      <?php echo (int) $my_number; ?>
  • From v10+: If the text will be within quotes you can use escape_quoted_data(); (removed from v10.3+)
  • 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();
  • When manipulating untrusted data on the client side, use DOMPurify (added since revision #21792). e.g:
    let your_var = DOMPurify.sanitize(dirty);

OWASP maintains a better list of preventing XSS. For a better understanding and more comprehensive list, please see their Cross Site Scripting Prevention Cheat Sheet.

OS (command) Injection

OS injection is an attack in which the goal is the 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 type of attack, the actor-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.

General (OWASP) recommendations:

  • Avoid calling OS commands directly and use built-in language functions instead (e.g. mkdir)
  • Escape values added to the OS commands (e.g. escapeshellarg)
  • Parameterisation and Input Validation

Use structured mechanisms to automatically enforce the separation between data and command. These mechanisms should provide the relevant quoting and encoding.

The values for the commands and their relevant arguments should both be validated using an allowlist. The following metacharacters should be avoided:

; & | $ > < ` \ ! ' " ( ) including space

. Note: some of those metacharacters may occasionally be expected.

In ResourceSpace, when required, developers should:

  • Use the run_command function with the placeholders map (ie. params argument). This will automatically escape every placeholder value before using it in the command.
  • Ensure that each of the placeholders' value represents ONE argument value (highly contextual). Don't take user input directly!
  • Always validate the placeholders' values as needed (e.g. path, filename, image size formatted like "width:height")

Since version 10.4, a placeholders' value must be an instance of the CommandPlaceholderArg. Its default validator blocks all the metacharacters recommended by OWASP. ResourceSpace has a few other validators:-

  • is_valid_rs_path() - Check if a given file path is from a valid ResourceSpace accessible location
  • is_safe_basename() - Determine if a paths' base name is originating in ResourceSpace. Note: Use only when the dir name is already trusted (generated with hardcoded values)!
  • is_valid_contact_sheet_preview_size - Determine if the $contact_sheet_preview_size config is valid
  • is_valid_imagemagick_color - ImageMagick's color values (e.g. blue, #ddddff and rgb(255,255,255))