Commit b558781
feat: AutoCSP + Trusted Types compatibility testing with browser
## Summary
This PR introduces a new feature to automatically apply a strict Content Security Policy (CSP) to the generated web applications and report any violations that arise in the browser.
While we have some *static analysis* checks for potential injection patterns-- we also rely on these powerful runtime defenses in 1p Google apps to provide a powerful guarantee that the injection-prone code will specifically not run. Therefore, we have in the past discussed the usefulness of a browser-based runtime check for compatibility with these runtime-based injection defenses as a complementary signal to our code-scanning raters.
## Motivation
AutoCSP-- transformation of the HTML to load all `<script>` tags with `src` attributes with a dynamic inline loader script, and then make sure there is a [hash-only CSP](https://github.com/google/strict-csp) enforced on the site-- is a zero-config approach to systematically protect against injection attacks (XSS) with a strong runtime guarantee.
AutoCSP is also a feature that is available in clientside Angular and a practice we would like to generalize. Compatibility with autoCSP-- especially violations arising from automatically generated code patterns-- is an important metric that we would like to collect to not only prove the robustness of the current autoCSP approach available in Angular but also to further promote this approach across the entire TS/JS frontend ecosystem as a best practice.
## High-level Approach
1. Define a new environment that can specify whether we will turn on autoCSP
2. If enabled, intercept the responses seen during the Puppeteer testing of the page so that we can attempt to add an autoCSP
3. Use the [strict-csp](https://github.com/google/strict-csp) NPM package to transform/rewrite the HTML to include hash-based CSPs and dynamic loader scripts. In the future, we can also figure out a sustainable way to bring in Angular's implementation of the autoCSP transformation to test for feature parity. (As of now, that logic is not exported as a separate package.)
4. Include the autoCSP as a `Content-Security-Report-Only` *header* in the intercepted/modified Puppeteer response. This has an advantage that the JS execution will not halt on the first violation, allowing us to collect as many violation reports in the interaction with the app as possible. Furthermore, sending the report-only header as a header rather than a `<meta>` tag allows us to specify a `report-uri` to collect this data.
5. Puppeteer will intercept all requests to the `report-uri` endpoint to collect the violation data.
6. A rater (only pulled in to our new environment that enables autoCSP) will count how many CSP and TT violations we have encountered.
In the future, we hope to plug in the data from 6 to attempt a LLM auto-repair of the code and repeat this process.
## Additions
* **Automated CSP Injection:** A new `auto-csp.ts` module has been created. This module leverages the `strict-csp` library to dynamically generate a strict, hash-based CSP for the application. It uses Puppeteer's request interception to inject the `Content-Security-Policy-Report-Only` header into the main HTML document response.
* **Violation Reporting:** The system is configured to send CSP violation reports to a local endpoint (`/csp-report`), which is also intercepted by Puppeteer. These reports are collected and included in the final build results.
* **Source Code Snippets:** To improve the actionability of the violation reports, the tool uses the Chrome DevTools Protocol to access the source code of the scripts that cause violations. It then includes a relevant code snippet in the report, making it easier to pinpoint the source of the issue. We will use this information to implement a future feature to attempt LLM auto-repairing of CSP + TT incompatibilities.
* **Configuration:** The feature can be enabled or disabled on a per-environment basis using the new `enableAutoCsp` flag in the environment's configuration file.
* **Dependencies:** Added `strict-csp` for CSP generation and `node-fetch` to handle server-side fetching of the initial HTML document to be used in the puppeteer intercept-and-autoCSP flow
Co-authored-by: Aaron Shim <aaronshim@users.noreply.github.com>1 parent a42917b commit b558781
File tree
15 files changed
+551
-16
lines changed- runner
- builder
- orchestration
- ratings
- built-in-ratings
- reporting
15 files changed
+551
-16
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
| 55 | + | |
55 | 56 | | |
56 | 57 | | |
57 | 58 | | |
58 | 59 | | |
| 60 | + | |
59 | 61 | | |
60 | 62 | | |
61 | 63 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
0 commit comments