Server-Side Security

  • Focus: Remote Attacker
    • Target the server
  • Goal: Compromise remote system
  • Possibly malicious input to remote web server:
    • Form fields (hidden + visible)
    • GET/POST parameters
    • Cookies
    • HTTP Headers

../_images/web-server-input.png

SQL Injection

  • SQL used for relational databases for
    • Extraction (SELECT)
    • Insertion (INSERT INTO)
    • Updating (UPDATE)
    • Deletion (DELETE FROM)
  • Problem: Mixing of code + data
    • SQL Queries are often generated on-the-fly with user input
  • Attacks:
    • End literal expression with '
    • Comment rest of query -- /#
    • Comment range /* ... */ (two injection points required)
    • Leak data with UNION statements
      • Respect union-compatibility
      • ' UNION (SELECT 1 FROM ...)
    • Add tautology: a' OR 'a'='a/' OR 1#
  • Column reference
    • Name‌ (e.g., id)
    • Index (e.g., 1)
  • Guess number of columns:
      1. Try ORDER BY <columns> until no error occurs
      1. Try UNION SELECT <columns> until no error occurs
    • e.g., x' ORDER BY 1,2 --
  • Schema Information
    • MySQL/PostgreSQL
      • Contained in table information_schema.*
      • .schemata: contains schemata (for MySQL: databases, for PostgreSQL: schemata)
      • .tables: accessible tables
      • .columns: Accessible columns
    • SQLite PRAGMA <cmd>
      • stats
      • table_info(<table>)
  • Examples:
    • mysql_query("SELECT 1 FROM users WHRE name='".$_GET["name"]."' ...;");
    • a' UNION SELECT table, column FROM information_schema.columns--

Drupageddon

  • Real-world example (2014)
  • Problem: Attack used Dict instead array (['code' => 1]) and bypassed the automatic enumeration of the array
  • Vulnerable line:
    • foreach ($data as $i => $value)
    • Bypass with $data = ['fakeKey' => 1]
  • Better: array_values($array): return array values

Blind SQL Injection

  • Situation:
    • Query does not return output but amount of rows matched or binary result (blind)
    • e.g., OK and NOT OK
  • Attack: Exfiltrate information from DB
  • Functions:
    • MID(str, pos, len): Extract len characters from str starting at position pos
    • ORD(str): ASCII code for first char in str
    • LIKE:
      • % for arbitrary amount of chars
      • _ single char
    • IF(condition, then, else):
      • Return then if condition is true, else otherwise
      • e.g., SELECT IF(ORD(str) = 40, 1, 0) FROM ...
    • SLEEP(n): Sleep n seconds
  • Approaches:
    • Brute-forcing every single char: \( O(nm) \)
      • Length \( n \)
      • \( m \) possible characters
    • Binary search:
      • Char to ASCII value
      • e.g., ORD(str)
      • Apply binary search \( O(n\log m) \)
    • Reduce character set with LIKE
      • e.g., password LIKE '%a%'
    • Timing-based:
      • Exploit timing behavior (if database answer doesn’t change)
      • e.g., use IF with sleep()
      • e.g., IF(cond, sleep(2), 0)
  • Prevention:
    • Main problem: Insecure usage of attacker-controlled data
    • Prepared statements
      • Separated code/data
      • Increased performance (query-planner already optimized)
      • $prepared = $mysqli->prepare("INSERT INTO test(id) VALUES (?)");
      • $prepared->bind("i", $i) ("i" means integer)
      • $prepared->execute()
    • Sanitization/escaping
      • Caution: Error-prone
      • Escaping function: mysqli_real_escape_string()
    • Database permissions (protection)
  • Example:
    • bob' AND password LIKE 'a%' #
    • bob' AND (SELECT IF(MID(password, 1, 1) = 'a', SLEEP(1), 0) FROM users WHERE user='bob')#

NoSQL Injection

  • Not Only SQL
  • Database types:
    • Document-based (MongoDB, CouchDB)
    • Key-value (Redis, BerkeleyDB)
    • Graph database (Neo4J)
  • Mostly custom query format
    • e.g., db.employees.find({lastname: "Stick"})
    • e.g., Negation: db.employees.find({name: {$ne: "Stick}})
    • e.g., Regex: db.employees.find({name: /tic/})
    • e.g., Greater: db.employees.find({age: {$gt: 30}})
  • Note: Parsing GET parameters in PHP:
    • PHP takes last definition (e.g., GET)
    • ?foo[]=bla&foo[]=bar enforces array foo = [bar, bla]
  • Attack: Inject conditions
    • Using the parsing behavior of PHP for HTTP parameters
    • e.g., ?user=bob&password[$regex]=.
  • Defense:
    • Type enforcement (e.g., for a string)
      • PHP: (string) $_GET['name']
      • Python str(request.GET['name'])

../_images/nosql.png

Code Execution Flaws

Command Injection

  • Scenario: App executes OS command directly with user input
  • Known problem: Data and code not separated
  • Example:
    • os.system("htpasswd -b .htpasswd %s %s" % (username, password))
  • Attack: Inject malicious parameters into bash
    • cmd1; cmd2: Execute cmd1 and cmd2
    • cmd1 && cmd2: Execute cmd2 if cmd1 worked
    • cmd1 | cmd2: Pipe result of cmd1 into cmd2
    • cmd1 $(cmd2): cmd2 result to cmd1
  • Problem: Command and arguments are not separated
  • Solutions:
    • Separation of command and argument
      • Python: subprocess.call([...])
    • Escape shell arguments:
      • PHP: escapeshellarg(string $arg)

Path Traversal

  • Scenario:
    • PHP script reads from storage with user input or copies a certain file
    • e.g., return read("downloads/" . $_GET['fn']);
    • e.g., move_uploaded_file(...)
  • Use ../ to move on file system
  • Attack:
    • Leak information (/etc/passwd, .htpasswd)
    • Overwrite information (e.g., PHP file)
  • Preventions:
    • Sanitize path/input (focus on . and /)
    • Access rights

../_images/path-traversal.png

File Inclusion

  • PHP Parsing:
    • PHP is HTML preprocessor
    • Execute code between <?php ... ?>
    • Include-statements:
      • include: Include, warning if not found
      • require: Include, die if not found
  • Scenario:
    • Application code is split across multiple files
    • include call uses user input
    • e.g., include($_GET['page'])
  • Attack:
    • Include other files on server
      • Denial of service: Include loop (include(index.php))
    • Code Injection: Include remote files (disabled by default)
  • Prevention:
    • Use allow-list with allowed files
    • Sanitize path (e.g., basename() resolves traversals)
    • Restrict directories with open_basedir (all files outside this directory are inaccessible)
    • Use mapping from site ID to include file

Unrestricted File Upload

  • Scenario: App allows file upload
  • Attack: Upload file for remote code execution
  • Types:
    • Upload HTML to be display with JavaScript (XSS by upload)
    • SVG images can contain JavaScript
    • PHP file being executed
    • Flash files
    • .htaccess: Overwrite webserver configuration (AddType adds executable to server)
  • Real-life attack: GIFAR
    • Combination of GIF and JAR
    • GIF type information at beginning (bypass content sniff)
    • JAR information at the end (ignores first bytes)
    • Upload GIFAR to server and send link to uploaded file to user
  • Prevention:
    • Type checking/Content sniffing (explicit or implicit)
    • Images: Remove non-image content/clear meta data (using libraries)
    • Separate domain for upload

Deserialization Issues

  • Scenario:
    • Non-string data often exchanged between entities by using Serialization
    • e.g., pickle, serialize
  • Property Oriented Programming (POP) attack
    • Idea: Chain together properties of different objects
    • Attacker controls properties of de-serialized object
    • Attacker chains together different magic functions
  • Serialization in Python
    • pickle.loads() / pickle.dumps()
    • loads() calls __reduce__
    • Attack example:
      • Server calls pickle.loads() on Cookie value
      • Use pickled object with malicious __reduce__ function as Cookie value
      • Attacker sends malicious Cookie to server
      • e.g. class Foo: def __reduce__(self): subprocess.call()
  • Countermeasures
    • Avoid serialization of complete objects
    • Serialize using JSON
    • Sign Cookies sent by the server (attack can not inject malicious code)
  • Real-world attack: vBulletin 5.x
    • Attacker could pass code into eval()

Template Injection

  • Template Systems:
    • Idea: Separate logic (controller) and rendering (view)
    • MVC architecture
    • PHP: Twig, Smarty
    • Python: Django/Jinja2
  • Attack:
    • Template is combined with parameters, then rendered
    • Execute code on server side
      • Read/modify environment variables
    • Example:
      • $twig->render("Hello {first_name}", array('first_name' => ...));
      • first_name = lambda x: ...
  • Prevention:
    • Prohibit user-provided input in generation of templates

XML (In)security

XML

  • Well-structured markup language
  • Consists of elements
  • Elements may have attributes
  • Validity by Document Type Definition (DTD)
    • DTD defines valid elements
      • <!ELEMENT img EMPTY>
      • <!ATTLIST img src  %URI; #REQUIRED>
    • Specifies elements
    • Defines custom entities
      • Entity: Mapping from element to value
      • Example:
        • <!ENTITY age "Alter">
        • Usage: %age;: 32 -> Alter: 32
  • Document Type (<!DOCTYPE ...>)
    • Defined by DTD
    • Refers to DTD (can be external file)
    • e.g., <!DOCTYPE Name [ <!ELEMENT Name (#CDATA)> ]>
    • SYSTEM for external entities
      • Even within the entity definition
      • <!DOCTYPE Name SYSTEM "http://.../name.dtd">
      • <!ENTITY passwd SYSTEM "file:///etc/passwd">

Attacks

  • Abusing XML External Entities (XXE)
    • Goal: Information disclosure (Confidentiality)
    • Attacker must control XML file (e.g., for login protocol)
    • Attacker includes sensitive files in SYSTEM
    • <!ENTITY xxe SYSTEM "file:///etc/passwd">
  • Denial of Service (Availability)
    • Define entities recursively
    • XML Billion Laughs
  • XPath Injection
    • Scenario: Database is stored in XML
    • XPath Injection (attacker could inject XPath query)
    • Problem: Mixing code and data

../_images/09-xxe.png ../_images/09-billion-laughs.png ../_images/09-xpath.png

Countermeasures

  • Entity attacks:
    • Disable entity loader (libxml in PHP)
    • Python: etree, xmlrpc, minidom, defusedxml are safe
  • Injection attacks:
    • Whitelisting of characters
    • Use programmatic checks

HTTP Parameter Pollution

  • HTTP Parameters
    • Series of name=value
    • Separator: &
    • Escaping (percent-encoding):
      • & = ; / ? : # @ + $ ,
      • Hex-value of ASCII value
    • e.g., ?attr=123&foo=bar
  • Attack: Multiple parameters with same same
  • Problem:
    • Web server + application differ in interpretation of parameters
    • e.g., Result of ?a=1&a=2?
      • Keep first: a=1?
      • Keep last: a=2?
      • Array: a=[1, 2]?
      • Concatenation: a=12?
  • Attacks
    • Problem: Multiple instances interpret the data
    • SQL Injection
    • XSS
    • ?page=SELECT 1,&page=2,3
  • Real-world example: blogger.com
    • Attacker added herself in the author’s list
    • Author was checked on first parameter
    • Target block was checked on second parameter
  • Countermeasure
    • Python: Double-check types of parameters (e.g., string vs. list)
    • General: Ensure proper encoding

HTTP Header Injection

  • Attacker inserts headers into HTTP response
  • Problem:
    • Headers are concatenated with user input
    • e.g., modify Cookies
    • Insert new headers by line break
    • Insert malicious content with line breaks
    • e.g., \nLocation: attacker.com\nFoo: bar
  • HTTP Response Splitting:
    • Inject attacker-controlled response into the actual response (which is cut off)
    • e.g., \n\n<html><script>attack()</script></html>
  • Countermeasure:
    • Ensure: No new line character allowed
    • PHP: Only one header per function call

Server-Side Request Forgery (SSRF)

  • Use Case:
    • Preview of resources ensuring privacy for the client
    • e.g., Twitter shows preview of images, does not deliver original URL to user
  • Three parties:
    • Client (C)
    • Middle server (S)
    • External server (ES)
  • Middle server (e.g., firewall, proxy) sends request to external server (target)
  • Problems:
    • Attack external server anonymously (attacker’s identity is not revealed)
    • Access private resources behind a firewall (on the middle server)
    • Deliver malicious content from the external server to client with the origin of the middle server
  • Possible attacks:
    • Server-side Request Forgery:
      • Client wants to attack the external server which is behind a firewall
      • e.g., http://10.0.1.1:1234/...
      • Problem: URL parsing is not consistent
    • DNS Rebinding
      • Client attacks external server
      • Request (with IP) must be executed twice
      • First time: Check if hostname is allowed
      • Second time: Rebind DNS to target resource
      • Time-to-check-to-time-of-use attack
    • Web Origin Laundering (WOL)
      • Middle server is acting as proxy
      • Malicious content is sent from attacker server to client with the origin of the middle server
      • May bypass the CSP (if host names are used)
  • Countermeasure:
    • Whitelist server
      • By the same component as taking the request
      • Due to different parsing rules
    • Content-Disposition: attachment, do not display file inline (mitigate WOL)
    • DNS pinning (against DNS rebinding)

../_images/09-ssrf.png ../_images/09-wol.png

Execution after Redirect

  • Problem: Bad programming
  • Check permissions using PHP
    • If no permissions exist, set redirect header
    • Problem: Redirect only at end of script and not immediate (actions can be executed after setting the header)
  • Finish script using die()

../_images/09-execution.png