Skip to Main Content
March 14, 2024

Failure to Restrict URL Access: It’s Still a Thing

Written by Geoff Walton
Application Security Assessment

Here are some brief thoughts about an old issue. If you are a full-time application security professional, stop reading. You know all about this, you know probably five different ways to describe and talk about this, and you no doubt have a kit of favorite tools ready to go to for exploring this type of issue in every kind of application you come up against.

If you are doing security work that is application adjacent, like penetration testing or trying to assess your own security posture, here are some ideas on how to identify issues in a common vulnerability category for modern web applications.

Many moons ago, finding parts of applications that were missing access control was often simple. The names of some of these techniques were forced-browsing, Google-Dorks, deeplink discovery, etc. The tools were DirBuster, Burp Suite’s “Discover Content”, Google, Nikto, and find/grep. Some of those tools are still used regularly as well as some more recent iterations like Gobuster, and ffuf.

It was also possible to just change /login to /home or simply try throwing additional components like /admin, or /util onto the end of paths. With luck, Apache or IIS was configured to help an attacker out by providing a directory index.

Figure 1 - Unauthenticated Time Card Records

Testers might think that the discovery these things is out of reach in contemporary applications. Testers may be telling themselves things such as:

  • Applications don’t have separate pages anymore, so I can’t just put /admin onto the end of a path and expect any result other than a 404 response.
  • The REST API, unless it is just GETs with a path parameter, means I’ll never get anywhere without knowing some secret JSON incantation.
  • SOAP is completely opaque.

Without visiting snopes.com, let me go ahead and rate the above “mostly false.”

Applications might not be your bread and butter, but they still represent a good deal of attack surface. Before testers shrug their shoulders and say, “Looks new, I am going to move on”, applications should be given a closer look. The goal here is to quickly spot missing authorization controls without getting deep into the weeds. A lot can still be done with a just a web browser and the built-in developer tools; however, intercept proxies like Burp Suite will be an advantage especially for searches across multiple files/URLs.

Path Hunting

This example is a bit contrived, but is one that can be shared and comes from Portswigger’s labs. A real application will probably have the JavaScript bundle in a separate file and it will be minified, but those transforms won’t stand in the way of using regex pull out anything that looks like a path! 

Link: https://portswigger.net/web-security/access-control/lab-unprotected-admin-functionality-with-unpredictable-url

Figure 2 - Path Hunting for Administrative Resources

The interesting files might have some framework generated name like 4f44a1bf1b35c2c4f326.js but will most likely be served from the same host/domain because of CORS and other browser security controls. For this reason, it is likely alright to move past third-party script includes quickly. Scanning through blobs can be done efficiently with a regular expression like:

 (\'|"|`)[A-z0-9_\(\)\?\&\[\]\#\-\~]*\/[A-z0-9_\(\)\?\&\[\]\#\-\~\/]*(\'|"|`)

The expression won’t find every path that could be legal in a URL nor is it free of false positive matches on strings which are not paths. It does work to make the job of sifting through a big file approachable. A couple Burp Extensions that will do some of that work for you are JS Link Finder and JS Miner. 

JS Link Finder

Link: https://portswigger.net/bappstore/0e61c786db0c4ac787a08c4516d52ccf 

JS Miner

Link: https://portswigger.net/bappstore/0ab7a94d8e11449daaf0fb387431225b

Armed with some possible path information, different strategies can be employed. Accessing the items in the application itself might be as simple appending path components to URL fragments.

Example:

HTTPS://example.com/onlineStoreApp/#/searchProducts/byCatagory becomes HTTPS://example.com/onlineStoreApp/#/administration/mangeUsers

This is as easy ever! The application will do all the handwork of formatting the API requests etc. Incidentally, URL fragments are not sent to the server. Trying some of these out should go undetected, at least until some functionality is successfully triggered.

Returning to skimming through the client-side code, for applications using REST, there is a good chance the paths or path components will be nearby to code that is responsible of calling the service. Even if you are not a JavaScript wizard, the code may be fairly easy to understand, additional keywords to watch for are XMLHttpRequest and fetch().

Feature Sleuthing

It might not always be that easy as just looking for paths. Some examination of the application logic could be required. It is likely that a good deal of discovery can still be performed without having to peer to deeply into any JavaScript quagmire. This is really going to only make sense in the context of applications where the tester has some access; However, having some access isn’t uncommon (For example, any application that allows self-registration).

 To target features at the quick flyover level, start by looking at what is on the screen. If there are functional areas of the application like, ‘Manage Profile’, or ‘Product Lookup’, they might exist as things that can be recognized in feature flags. Next, start looking at API responses. For SOAP or something else, it may be necessary to dig though some XML, but for REST, the interesting item is likely to be a response to something obvious like /users/me or /users/{someIdAssignedToYourAccount}. Other watch words here are 'account', 'subscription', 'features', 'security', and 'roles'. The HTTP response to search for might look something like the one below.

Figure 3 - REST-style Feature Flags Response

This is really the ideal case. No guesses are required, and all that may be needed is to simply invert some of the Booleans. Finding additional features could be a little more difficult if a response like the one below is located.

Figure 4 - REST-Style Feature Flags Response

In this case, the best strategy is usually to search for the flags observed and see if similar patterned names show up in code nearby. There is no real need to understand the JavaScript that is being sifted through, only to spot some patterns. In this case, if there are buttons in the application labeled “Customer Service” and “Manage Profile” the response above indicates that code should be searched for strings that match an expression similar to:

FN_[MT]_[A-Z]+\w

Once some feature flags have been identified, it is time to add or change them. The most obvious way for users of Burp Suite is to utilize the “Match and replace rules” in proxy settings.

Figure 5 - Burp Match and Replace

This method has some obvious drawbacks. Specifically, the pattern being replaced might show up in code elsewhere and could cause the application to fail to load or not execute properly. 

Some great Burp Suite plugins will provide the ability to take a more targeted approach. One objective might be ensuring only a response to a specific request is modified. Some applications might have tens of roles or permission assignments, and it would be helpful to be able to programmatically enable them all without writing a match rule for each. Reshaper is one example of a plugin that can help here. It is a very flexible tool; However, with flexibility comes great complexity. Learning to work with some of these tools if you don’t use them frequently can take some time. Some alternatives that might be quicker to get started with are HTTP Mock and my own Response Tinker.

Reshaper

Link: https://portswigger.net/bappstore/7bcec7656b5746e9a85c427f243e6d5a

HTTP Mock

https://portswigger.net/bappstore/42680f96fc214513bc5211b3f25fd98b

Response Tinker

Link: https://trustedsec.com/blog/more-options-for-response-modification-with-responsetinker

These are some quick strategies for finding areas in application that might be missing authorization controls, or cases where authorization is only performed on the front-end while individual API endpoints are ripe for abuse. Experience tells us that there is a good deal of low-hanging fruit out there waiting to be found. Happy hunting!