PHP Security

Written in

by

A reference book that gives snippets on how to secure your PHP application

Input Validation

Possible input abuses:

  • Input of metacharacters (e.g. [! $ ^ & * ( ) ~ [ ] \ | { } ‘ ” ; < > ? – `])
  • Input of the wrong type of data
  • Input of the wrong length of data
  • Input of unexpected commands
    • SQL commands, JavaScript commands, PHP commands etc.
  • Submitting data through hidden fields or hidden interfaces
    • Hidden interfaces are layers within your application that was not intended to be accessed by the user, but through custom crafted HTTP request, they could define those variables.

Remediation:

  • Turn off Global Variables, and explicitly declare all variables
    • Within php.ini, turn off register_globals variable, which would allow attackers to set variables which could coincide with branching logics (e.g. setting is_admin=True globally)
    • Explicitly declare all variables to have a default value (.e.g "" or False)
  • Check the inputs for type, length and format
    • Always apply is_string(), is_int(), is_long() and the likes on user input
  • Sanitize all values passed to other systems/functions
    • PHP has some inbuilt escape functions such as mysql_real_escape_string() for database queries, or escapeshellarg()

Preventing SQL Injection

Remediation:

  • Demarcate all values in your queries (e.g. $name)
    • $query = "SELECT * FROM tables WHERE name = '$name'";
  • Check for input types
    • is_int(), is_string(), gettype() etc.
  • Escaping characters
    • Do not use magic_quotes_gpc or addslashes(), but rather mysql_real_escape_string()

Preventing XSS

Remediation:

  • Encode HTML Entities in all Non-HTML outputs
    • Use htmlentities() to translate all characters with HTML entity equivalents, rendering them harmless
    • Do not use the more limited htmlspecialchars()
  • Sanitize All User-Submitted URIs
    • Use parse_url() to split the input, and inspect the user given schema
  • Use Tried and Proven XSS filters
  • Design Private APIs for Sensitive Transactions
    • e.g. bank.example.com, which accepts POST requests, while example.com only accepts GET requests

Preventing RCE

Possible Vectors of Attack:

  • include()
  • require()
  • eval()
  • preg_replace() with -e option

Remediation:

  • Limit Allowable Filename Extensions for Uploads
    • e.g. disallow uploading of *.php, *.exe, *.py, *.cgi etc. files
    • But this is still susceptible to wrong mime type attacks, where the the user intercepts the data and edits the contents
  • Store Uploads Outside of the Document Root
    • Place all uploaded files in another separated directory, which has limited execution permissions
  • Sanitize all inputs going into eval() or the likes
  • Properly Escape All Shell Commands
    • Use escapeshellarg() to add single quotes around input strings
    • Use escapeshellcmd() to escape special characters

Preventing Temporary File Abuse

Overview:

  • Temporary files are usually created at /tmp or /var/tmp
  • These files are supposed to be deleted after the application that created them closes, but under some circumstances, it does not
  • These files end up existing in these folders that could have wrongly configured permissions, as they were meant to be temporary

Remediation:

  • Make locations difficult to guess with random folder names
  • Make permissions of the folders restrictive
    • Do not give them world-rwx permissions
  • Read/Write to known files only
    • There is a possibility of the attacker creating many filenames with malicious code in them, and your application simply reads it because it is there
    • You should only write to files you have explicitly created by checking for the first time of access if its empty

Preventing Session Hijacking

Overview:

  • PHPSESSID stores an ID that is associated with persistent data at the backend
  • The PHPSESSID value could be stolen via MITM, Accidental Exposure, Phishing or Session Fixation

Remediation:

  • Use SSL to encrypt the value of PHPSESSID over the network
  • Use Cookies instead of $_GET variables
    • This automatically overrides and ignores transparent session IDs, which are IDs passed through the URI
  • Use Session Timeouts to constantly refresh the Session IDs
  • Regenerate Session IDs for every change of state
    • Logging in, logging out, checking out etc.

Securing REST APIs

Remediation:

  • Restricting Access to Resources and Formats
  • Enforce Quotas and Rate Limitations
  • Use SSL to encrypt data transfer

Tags

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: