Exploring An Application's Past & Future
Years ago, when I started building web applications I would simplistically imagine them as a 2D graph of assets. It didn’t take long before I started running into race conditions, time zone discrepancies and caching issues, which made me become aware of the crucial dimension of time in which an application evolves. As I started becoming familiarized with security issues, I realized that vulnerabilities often occur at the boundaries of an application’s assets, where references to past/future assets (subdomains, links, libraries, 3rd party services etc) are often left dangling, outdated or become actual vulnerabilities themselves. What follows are some findings I stumbled upon while keeping this perspective in mind.
Digging up the past
I found that The Wayback Machine from Archive.org is a great tool for quickly surveying the public assets of a domain, allowing anyone to browse historical snapshots.
The viewer groups the site by years and shows all assets in radial-tree graph
The image above reveals a
?pagename= parameter, which already hints to local file inclusion vulnerability.
Waybackurls is a tool for quickly fetching URLs from the Wayback Machine, which can give a feel of how the application is built.
Although mostly used for fuzzing, I like wfuzz because of it’s nicely structured output. This scan quickly reveals which URLs are still available, 404s and redirects, already hinting at some potential attacks
For more a more in-depth perspective, wayback_machine_downloader can be used to fetch a copy of all the historical snapshots of a website.
An interesting find: emails & reset password links.
…and activation links.
Password reset and activation links get indexed by crawlers or get leaked to 3rd parties via the Referrer header and, to make matters worse, expiration policies vary from framework to framework or has bugs, so they can occasionally be reused. Since the image above also reveals user emails, this paves the way for a targeted phishing campaign.
The Wayback Machine also stores error pages and redirects; 40* and 50* pages can provide insight into the configuration of the application’s stack while 30* redirects, conveniently highlighted, open the way to potential subdomain takeovers.
Comparing different versions of error pages can reveal when an application’s infrastructure has changed.
Modern web frameworks concatenate, minify and fingerprint assets for performance and caching purposes. This can sometimes make it hard to spot changes made to client-side code. Since it’s easy to get a list of all previously generated assets from The Wayback Machine, it becomes easy to spot different versions of the same file based on their file size.
Even though their names are obscure, similar sizes point to the same files.
Learning from others mistakes
“The future is already here — it’s just not very evenly distributed” claims William Gibson, the sci-fi author who also coined the term “cyberspace”. While the quote can be dismissed as abstract, the reality in software development is that incomplete features often get released to production - both intentional and unintentionally. Some of these features quickly get reverted. But these reversals are not always atomic operations. Artefacts get left behind, i.e. comments, which can be a treasure-trove of development credentials, sensitive links, library versions, S3 buckets.
In order to safely deploy features according to a marketing timeline feature flags are used, which provide the opportunity to test the features incrementally to selected audiences, in case anything breaks. Feature flags is why many unreleased features from popular products become leaked to the public long before their official launch. Giants like Facebook & Google implement their own feature flag service, while other websites used 3rd party services. Building on what we have explored until now, we can get insight into how a feature flag implementation may evolve.
The initial implementation is importing a local config file, while the newer implementation if fetching the configuration with an AJAX call to an external service.
The future becomes the past
In the context of web application security, an assumption I sometimes find myself making is that once a security issue is fixed, things tend to move forward and that class of bugs will not surface again. This, ofcourse, is false. From my previous work in web development, conscious and consistent effort has to be put into setting up proper testing and maintaining code quality. A high code coverage percentage is the pride and joy of any seasoned developer, but that doesn’t prevent security bugs from sipping through.
A recent XSS was made possible in Google Search because the sanitizer was modified – essentially becoming more lenient – because of interface design issues.
Since Google’s frontend is open source, we can take a look at what exactly happened.
The commit message for the fix notes that tests were added and updated. While automated tests vouch for a programmer’s correctness at the level at which the test was introduced (unit, integration, system) and guard against violations of the application’s architecture and business logic, they do not always vouch for the overall security of the application.
We can see that the fix is actually a rollback, essentially bringing the code to a previous point in time.
To sum it up, application code moves back and forth, inherently producing side effects which can be exploited. Hacking is about finding the right time to act… and the right time to stop.