This post is going to talk about source code reviewing PHP and demonstrate how a relatively small chunk of code can cause you lots of problems.
The Code
In this article we are going to analyze the code displayed below. The code displayed below might seem innocent for some , but obviously is not. We are going to assume that is used by some web site to de-validate the user credentials and allow the users to logout securely.
1: <?php
2: require_once 'common.php';
3: if (isset($_SESSION['username']))//Insecure source
4: {
5: session_unset();// In properly destroyed session.
6: }
7: header('Location: index.php'); ?>
I you look carefully the code you will se that the code is vulnerable to the following issues:
- NULL De-Authentication Bypass
- No Proper Session Termination
NULL De-Authentication Bypass
Exploitation:
An adversary may on purpose exploit this vulnerability possibly without the need of developing any costume tools (but needs a good understanding of PHP design flaws). More specifically an adversary can manipulate the cookie parameter and de-‐validate the logout process by injecting a NULL value in the begging of the username (after the authentication). This would result into maintaining the user Web resources available for the specific session-‐id even after the logout is performed.
Vulnerable Code:
if (isset($_SESSION['username']))// Malicious de-validation cancel
Assuming that the target username is user12 potential malicious payloads that could exploit the
vulnerability displayed above would be user[space]12 , %4e%55%4c%4c,user12, user12[space],
%20user12, [space] [space]user12 [space],user12 , user12, user12,, user12NULL NULLuser12
etc. This is applicable due to the fact that if multiple parameters are supplied then the isset will return
TRUE only if all of the parameters are set. Evaluation goes from left to right and stops as soon as an
unset variable is encountered. The attack should occur after the user successfully authenticates her
self.Note1: At this point it should be noted that when on, register_globals (which is on by default in PHP < 5.3.0), will allow an adversary to populate the cookie username variable from various user input such request variables from HTML hidden form fields, Web Application URL’s etc. which translates into working as a vulnerability amplifier! Also this might lead into allowing POST to GET interchanges, promoting CSRF like attacks (e.g. the web app does not distinguish POST from GET).
Note2: This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
Remedial Code:
1: //the filter makes sure the username has no spaces. if (strpos($username, " ") !== false){
2: // De-‐validate the session
3: }
2nd Code Chunk:
1: trim("^$", $username)//Not recommended to process malicious payloads, only identify.
Note: The NULL value translates into an empty string when validations come.
No Proper Session Termination
An adversary may on purpose exploit this vulnerability without the need of developing any costume tools. This attack might be used to perform vertical/horizontal user escalation (e.g. the cookie session-‐ id is assigned to a new user, and the new user automatically gains access to previous user Web resources, assuming that the Web Apps makes access control decisions by using only the session-‐id. Another attack scenario would be that the session is leaked though a blog post and the adversary makes use of the non de-‐validated leaked session to gain access to the Web Application user resources etc.).
Vulnerable Code:
Note2: The variable session_unset is considered to be deprecated code that does not use $_SESSION.
Remedial Code:
References:
1. http://php.net/manual/en/security.globals.php
2. https://www.owasp.org/index.php/Unvalidated_Input
3. http://php.net/manual/en/function.isset.php
4. http://php.net/manual/en/function.trim.php
No Proper Session Termination
An adversary may on purpose exploit this vulnerability without the need of developing any costume tools. This attack might be used to perform vertical/horizontal user escalation (e.g. the cookie session-‐ id is assigned to a new user, and the new user automatically gains access to previous user Web resources, assuming that the Web Apps makes access control decisions by using only the session-‐id. Another attack scenario would be that the session is leaked though a blog post and the adversary makes use of the non de-‐validated leaked session to gain access to the Web Application user resources etc.).
Vulnerable Code:
1: session_unset(); // Improper handling of the session.
Note1: The function shown above does not properly de-‐validate the session. The session_unset
function just clears the $_SESSION variable. It’s equivalent to doing $_SESSION = array(); So this does
only affect the local $_SESSION variable instance, but not the session data in the session storage,
everything else remains unchanged (including the session identifier). In this occasion the
session_unset is used to destroy/reset the session instead of the session_destroy function in the logout
page. The session_destroy() function destroys all of the data associated with the current session.Note2: The variable session_unset is considered to be deprecated code that does not use $_SESSION.
Remedial Code:
1: function destroySession() {
2: $params = session_get_cookie_params(); setcookie(session_name(), '', time() -‐ 42000,
3: $params["path"], $params["domain"],
4: ... );
5: session_destroy(); }
References:
1. http://php.net/manual/en/security.globals.php
2. https://www.owasp.org/index.php/Unvalidated_Input
3. http://php.net/manual/en/function.isset.php
4. http://php.net/manual/en/function.trim.php