This is a discussion on Security in PHP within the PHP Programming forums, part of the Web Development category; Despite the similarities in name, cross-site request forgeries (CSRF) are an almost opposite style of attack. Whereas XSS attacks ...
| |||||||
| Register | FAQ | Members List | Calendar | Mark Forums Read |
| |||
| Despite the similarities in name, cross-site request forgeries (CSRF) are an almost opposite style of attack. Whereas XSS attacks exploit the trust a user has in a web site, CSRF attacks exploit the trust a web site has in a user. CSRF attacks are more dangerous, less popular (which means fewer resources for developers), and more difficult to defend against than XSS attacks.
__________________ With, J. Jeyaseelan Everything Possible |
| Sponsored Links |
| |||
| PHP Code:
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| Most PHP applications interact with a database. This usually involves connecting to a database server and using access credentials to authenticate: PHP Code:
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| Potential problems arise when this file is somewhere within document root. This is a common approach, because it makes include and require statements much simpler, but it can lead to situations that expose your access credentials. Remember that everything within document root has a URL associated with it. For example, if document root is /usr/local/apache/htdocs, then a file located at /usr/local/apache/htdocs/inc/db.inc has a URL such as http://example.org/inc/db.inc.
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| Combine this with the fact that most web servers will serve .inc files as plaintext, and the risk of exposing your access credentials should be clear. A bigger problem is that any source code in these modules can be exposed, but access credentials are particularly sensitive.
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| If you have no choice in the placement of your modules, and they must be within document root, you can put something like the following in your httpd.conf file (assuming Apache): Code: <Files ~ "\.inc$"> Order allow,deny Deny from all </Files>
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| My favorite method for protecting your database access credentials is described in the PHP Cookbook (O'Reilly) by David Sklar and Adam Trachtenberg. Create a file, /path/to/secret-stuff, that only root can read (not nobody): Code: SetEnv DB_USER "myuser" SetEnv DB_PASS "mypass" Code: Include "/path/to/secret-stuff"
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| Protecting against SQL injection is easy: Filter your data. This cannot be overstressed. With good data filtering in place, most security concerns are mitigated, and some are practically eliminated. Quote your data. If your database allows it (MySQL does), put single quotes around all values in your SQL statements, regardless of the data type. Escape your data. Sometimes valid data can unintentionally interfere with the format of the SQL statement itself. Use mysql_escape_string() or an escaping function native to your particular database. If there isn't a specific one, addslashes() is a good last resort.
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| Session security is a sophisticated topic, and it's no surprise that sessions are a frequent target of attack. Most session attacks involve impersonation, where the attacker attempts to gain access to another user's session by posing as that user.
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| The most crucial piece of information for an attacker is the session identifier, because this is required for any impersonation attack. There are three common methods used to obtain a valid session identifier: Prediction refers to guessing a valid session identifier. With PHP's native session mechanism, the session identifier is extremely random, and this is unlikely to be the weakest point in your implementation.
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| Capturing a valid session identifier is the most common type of session attack, and there are numerous approaches. Because session identifiers are typically propagated in cookies or as GET variables, the different approaches focus on attacking these methods of transfer. While there have been a few browser vulnerabilities regarding cookies, these have mostly been Internet Explorer, and cookies are slightly less exposed than GET variables. Thus, for those users who enable cookies, you can provide them with a more secure mechanism by using a cookie to propagate the session identifier.
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| Fixation is the simplest method of obtaining a valid session identifier. While it's not very difficult to defend against, if your session mechanism consists of nothing more than session_start(), you are vulnerable. In order to demonstrate session fixation, I will use the following script, session.php: PHP Code:
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| To demonstrate session fixation, first make sure that you do not have an existing session identifier (perhaps delete your cookies), then visit this page with ?PHPSESSID=1234 appended to the URL. Next, with a completely different browser (or even a completely different computer), visit the same URL again with ?PHPSESSID=1234 appended. You will notice that you do not see 1 output on your first visit, but rather it continues the session you previously initiated.
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| A simplistic attack such as this is quite easy to prevent. If there isn't an active session associated with a session identifier that the user is presenting, then regenerate it just to be sure: PHP Code:
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| To protect against this type of attack, first consider that session hijacking is only really useful after the user has logged in or otherwise obtained a heightened level of privilege. So, if we modify the approach to regenerate the session identifier whenever there is any change in privilege level (for example, after verifying a username and password), we will have practically eliminated the risk of a successful session fixation attack.
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| Quote:
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| Arguably the most common session attack, session hijacking refers to all attacks that attempt to gain access to another user's session. As with session fixation, if your session mechanism only consists of session_start(), you are vulnerable, although the exploit isn't as simple.
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| Rather than focusing on how to keep the session identifier from being captured, I am going to focus on how to make such a capture less problematic. The goal is to complicate impersonation, since every complication increases security. To do this, we will examine the steps necessary to successfully hijack a session. In each scenario, we will assume that the session identifier has been compromised.
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| With the most simplistic session mechanism, a valid session identifier is all that is needed to successfully hijack a session. In order to improve this, we need to see if there is anything extra in an HTTP request that we can use for extra identification. It is unwise to rely on anything at the TCP/IP level, such as IP address, because these are lower level protocols that are not intended to accommodate activities taking place at the HTTP level. A single user can potentially have a different IP address for each request, and multiple users can potentially have the same IP address.
__________________ With, J. Jeyaseelan Everything Possible |
| |||
| Imagine if we required the user to pass the MD5 of the User-Agent in each request. An attacker could no longer just recreate the headers that the victim's requests contain, but it would also be necessary to pass this extra bit of information. While guessing the construction of this particular token isn't too difficult, we can complicate such guesswork by simply adding an extra bit of randomness to the way we construct the token: PHP Code:
__________________ With, J. Jeyaseelan Everything Possible |