Can we prevent a security incident like Loom’s?

On March 7, 2023, Loom experienced a security incident caused by a settings change in their CDN. Even with extensive internal testing, the nature of the problem caused it to go unnoticed until the change landed in production. Their incident report is a great explanation of the issue itself, so I won’t reiterate much of it here, but what I will look at is a related issue, and how static code analysis tools integrated into development pipelines could have prevented the issue.

Multiple factors for the same problem

In Loom’s case, changes to their CDN settings triggered the incident, but the underlying issue involved attaching session cookies to static assets. When paired together, a single user’s session was cached with static assets that all users—within the specified cache time—had access to.

This second issue is something we can look for in the codebase, and to prove it we built a new rule into Bearer to check for it.

Preventing the issue in Express

Express uses a middleware system to execute code, modify requests and responses, and perform other tasks whenever a network action takes place. The order you define these middleware matters. From the Express documentation:

The order of middleware loading is important: middleware functions that are loaded first are also executed first.

This is the problem we can look for. Here’s an example of what not to do:

app.use(session());
app.use(express.static(__dirname + '/public'));

In this case, the session handler is initialized before returning a static asset. This is bad, and can lead to the issue Loom experienced.

Instead, we want to confirm that the static asset middleware, express.static is set prior to the session middleware.

app.use(express.static(__dirname + '/public'));
// any other middelware
app.use(session());

This will serve static assets as expected, but not apply the session middleware to them since it is defined later.

Building a new rule into Bearer

When our team saw the Twitter thread and incident report from Loom, we checked to see if it was something our open-source SAST tool could help prevent. There wasn’t an existing rule to trigger, but our engineers used our custom rule system to look for the usage pattern above. Depending on when you’re reading this, it may be live already or part of the next release. You can view the static_asset_with_session rule yaml file to see how our team built it, and view the test files to see safe and unsafe scenarios.

How would you even know this is a problem?

This incident could result in unauthorized access to resources. The OWASP Top 10 A01:2021 covers it pretty clearly, along with Common Weakness Enumeration IDs CWE-668 and CWE-352. By exposing the session to a cached static asset, an attacker can gain access to resources meant for the cached user.

This is one of those edge cases in Express that isn’t very well known. Even when considering the order of middleware execution, seasoned developers may fail to realize the implication of starting with the session—especially when combined with cached assets. This is a perfect example of the benefits of scanning against a set of shared best practices, and it’s part of the reason we continue to add new built-in rules to Bearer. A scan with Bearer would not have caught a configuration change in the CDN’s settings, but from this point forward it will catch the flawed middleware order in Express apps.