Subresource monitoring with Compute
One of the more vexing web application and API protection (WAAP) challenges for app operators and users alike is attackers messing with the resources on which a website depends in order to skim payment information, steal passwords, or install malware.
With this pain point in mind, we wanted to see if we could come up with a solution for monitoring subresources to reduce our customers’ headaches in dealing with resource modification and manipulation. This post provides an overview of the problem area and our solution, using our serverless compute environment, Compute.
What is a resource (or sub-resource)?
“A resource can be anything that has an identity. Familiar examples include an electronic document, an image, a service (e.g., “today’s weather report for Los Angeles”), and a collection of other resources.” -- RFC 2396, August 1998
A subresource is a resource that is loaded as part of another resource; for the purposes of this project, we define it as anything with a uniform resource identifier, or URI (of which URLs are one type). If a user requests a webpage (a resource) to be loaded in their browser, the CSS file that determines the look of the page and the JavaScript file that contains necessary functionality are subresources that must be loaded, too. These subresources can be — and often are — loaded from a third party specialized in delivering content quickly and reliably to users, such as a content delivery network, or CDN.
Because it's built on top of our CDN, Compute presents the perfect place to monitor these subresources: with our edge computing network, developers can execute custom logic directly on our globally distributed, edge cloud platform.
What if an attacker modifies a subresource?
If an attacker modifies a subresource, they can cause a few different types of issues, but all of them are under the banner of modifying script dependencies.
Most modern websites require at least one JavaScript file to deliver their intended functionality to users. These necessary JavaScript files are often referred to as script dependencies. A classic case of attackers abusing script dependencies is Magecart, in which attackers inject JavaScript code into online payment forms in order to skim credit cards.
Attackers typically target a third-party dependency to modify the original script, but there’s also the possibility of the long con, in which an attacker could appear to be a legitimate script maintainer and later switch to being malicious.
Modifying script dependencies facilitates cross-site scripting (XSS) and cross-site request forgery (CSRF), too:
XSS attacks hijack a user’s account or web-browsing session, which allows the attacker to steal payment information or passwords and potentially install malware, too.
CSRF attacks force users to submit a request in a web app (without their knowledge or consent), allowing the attacker to manipulate the web app’s state to do things like change passwords, transfer money, make purchases, and perform other abuses of app functionality.
What are defenses against subresource modification?
Typically, you defend against subresource modification by taking inventory of any scripts, stylesheets, and other resources required in your application and then leveraging Subresource Integrity (SRI). SRI is an optional (but highly recommended!) attribute for script and stylesheet link tags that browsers enforce by verifying that resources are delivered from origin servers or CDNs without unintended or unauthorized modification. Any violations can then be reported to a specified endpoint using Content Security Policy header(s).
However, SRI won’t save your web app if an attacker injects a malicious script; attackers quite unfortunately won’t help you out by providing an integrity attribute on their script, so the browser won’t have anything to enforce. With that said, Content Security Policy can prevent this case if you implement a strict policy (i.e. no unsafe-inline, etc.).
How can we defend even better against subresource modification?
There are neat defenses we can implement from the edge. Compute allows us to implement a proxy that tracks subresources and automatically monitors violations of Content Security Policies. Let’s explore how this works in more detail.
Implementing a proxy in Compute allows us to keep track of all the subresources seen in responses to client requests. That way, if the proxy sees a new subresource for a particular website, it can send an alert to the service owner to let them know about these unauthorized changes to external scripts and CSS files. At a high level, the proxy process looks like this:
For example, if a customer is serving their website’s index.html through Fastly, the proxy in Compute will detect all the script sources in the response from the origin server that haven’t been seen before. We can use this information to generate an alert or surface a notification in the UI, so website owners can learn when there are unexpected subresources being detected by the proxy, such as, https://sketchcdn.attacker.com/js/bootstrap.bundle.min.js
in the screenshot below.
We can also add the Content-Security-Policy-Report-Only header to the proxy implemented in Compute to facilitate automatic monitoring of policy violations. For example, if an attacker tries to modify a script at a known URI, we can also provide a reporting endpoint via Compute that allows the browser to report violations that can then be forwarded to the customer (by leveraging our existing real-time log integrations).
Conclusion
Our project leveraged the power and position of Compute to implement a proxy that monitors for subresource modification by attackers. From here, we could, for example, create an out-of-browser equivalent of browser integrity checks by using a separate process to fetch third-party resources and hash them on a periodic basis for comparison, alerting the site owner to resource integrity changes.
If you’re interested in seeing what else Compute can do, it’s now available to all and includes free credits for you to experiment without commitment. Try it out.