Custom Access Control – Penetration testers may get distracted by technical issues thus forgetting that simple logical flaws could be the security breach cause. As penetration testers we have a tendency to get caught up in the latest exploit, or the most intricate piece of SQL injection or cross-site scripting, and so it is sometimes easy to forget that the most serious security breaches can be caused by very simple logical flaws in mechanisms designed to prevent exactly that. The following example represents a real world web application which I recently performed a web application test against. Note that URLs have been changed. While gathering information on the web application, prior to beginning the engagement, I noticed that, like many web applications, a robots.txt file was used to control indexing behaviour by the most common online search engines. An example of the content is shown below: User-agent: * Disallow: /webstats Disallow: /css Disallow: /components Disallow: /httpcontent Disallow: /includes Disallow: /js Disallow: /media Disallow: /modules Disallow: /PHPMailer Disallow: /website-admin Disallow: /templates Allow: / Now, as a penetration tester my interest was immediately attracted to the entry “Disallow: /website-admin”. So I fired up a web-browser and a local proxy (in this case I decided to go with Firefox and Fiddler2 but any browser and proxy combination would be just as effective) and manually entered a few choice phrases. Most came back with the obligatory 404 Page Not Found, but then the following URL presented me with an administrative login page: https://www.example.com/website-admin/users-admin.php Not entirely unexpected, after all there is no reason why an anonymous user should be able to access this page. On a hunch I examined the response traffic in Fiddler2 saw this, which was a little unexpected: HTTP/1.1 302 Moved Temporarily Location: login.php […]
[…][…][…] […][…][…] […][…][…] […][…][…] […][…][…]
In total the page referenced usernames and passwords for all 1400 test accounts on the web application. Once the issue had been confirmed and exploited, I contacted the client to inform them of this issue, and with some discussion with the development team we identified the root cause was the following piece of PHP server-side code, which made use of a custom “user” class, tied to the currently active session: Essentially, this code checks to see if the currently active session belongs to the user “admin”. If not, the “location” response header is modified to redirect to the login page. However, after this check the page content continues to render irrespective of the currently logged in user and is delivered in the response. On loading the response, most web browsers will follow the instruction to redirect to the login page, and so this issue would be easily missed by UAT testing. An attacker would likely spot this very quickly and so a simple oversight would give complete control over the application in a matter of minutes. As the website was designed to handle a large amount of sensitive and personal data, this issue could have caused a great deal of embarrassment to the client as well as creating potential legal complications. Following discussion of this issue, the access control mechanism was overhauled and a well-known application framework used instead. It is hoped that this will prevent similar vulnerabilities in future projects.