Wednesday, October 3, 2012

Case of Session Identifier not Updated


Rational AppScan is an automated web testing tool that can be used to produce reports of web application vulnerabilities. So we usually use it to ensure our apps well protected before releasing them to the wild internet.

The problem

The problem with detection tools is that it sometimes raises a false alarm - such as when it declared that session identifier not updated :

[1 of 2]  Session Identifier Not Updated
Severity: High
Test Type:  Application
Vulnerable URL: name/  
Remediation Tasks: Do not accept externally created session identifiers
Variant 1 of 1  [ID=26]
The following may require user attention:
 My normal reaction, because the app is a Yii framework-based PHP application, is that I should add Yii::()-app->session->regenerateID() call during login action.

Imagine my surprise that upon retesting using Rational AppScan, it spits errors like these :
Stopping scan due to out of session detection
I vaguely recall that the reason for errors like this is that the session ID in the HTTP header are unlike what the tool expected.


So I opened Firefox, and started to check for the HTTP Header anomalies. Examining Firebug's output, it seems that during each login there are two session ID header issued in the HTTP Response by the PHP application. Both of them are different from the session ID sent in the HTTP Request. So the Rational AppScan is confused when there are two session ID header issued.
Further search reveals that Yii framework's login mechanism already issue regenerateID calls, doubling my effort in the actionLogin function.
If the application already regenerate the session ID, why on earth it reports that session ID not changed ?
Then I realize.. the application is being tested twice, first without logging in and second with a login. So during the first phase the tool don't know what user/password should be tried to login, and it naively apply blank username and blank password. And naively expecting that session ID be regenerated. Which doesn't happen because the login is not successful...

The Cure ..(Updated)

For now, I will add a regenerateID call IF the login _failed_. Lets see tomorrow whether it could shut up the testing tool. UPDATE : Seems that it is not the case. It still complains that the session ID is not regenerated. Debugging alternative flow paths in the controller shows that blank username and password makes $_POST['LoginForm'] empty.
So I add another regenerateID call even if the $_POST['LoginForm'] is empty. This do the trick.