How SSG eliminates unsafe-inline at build time for perfect Lighthouse security scores.
Most static site generators use inline styles and scripts. Browsers need Content Security Policy (CSP) headers to block cross-site scripting (XSS) attacks. But CSP blocks inline code by default.
The common fix is unsafe-inline. This tells the browser to allow all inline code. It works, but it also allows injected malicious code. This defeats the purpose of CSP.
SSG takes a different approach. At build time, it extracts all inline styles and scripts into external files. Then it generates Subresource Integrity (SRI) hashes for each file.
The result: zero inline code in your HTML. Your CSP policy can be strict. No unsafe-inline needed.
The CSP plugin runs during the fused transform pipeline. For each HTML page:
- Finds all
<style>blocks - Extracts their content into
.cssfiles - Replaces the
<style>block with a<link>tag - Finds all inline
<script>blocks - Extracts their content into
.jsfiles - Replaces the
<script>block with a<script src="...">tag
After extraction, the asset fingerprint plugin generates SHA-384 hashes. Each <link> and <script> tag gets an integrity attribute.
<link rel="stylesheet"
href="/assets/style-a1b2c3.css"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8w">Browsers verify the hash before loading the file. If the file was tampered with, the browser blocks it.
With no inline code, your CSP header can be strict:
Content-Security-Policy: default-src 'self'; style-src 'self'; script-src 'self'
No unsafe-inline. No unsafe-eval. No nonces to manage.
Before SSG's CSP extraction:
- Security score: 70/100
- CSP header: requires
unsafe-inline
After SSG's CSP extraction:
- Security score: 100/100
- CSP header: strict, no exceptions
| SSG | Inline Extraction | SRI Hashes | Strict CSP |
|---|---|---|---|
| SSG | Build-time | Automatic | Yes |
| Hugo | Manual | No | Manual |
| Zola | No | No | Manual |
| Astro | Plugin needed | Plugin needed | Manual |
| Next.js | Nonce-based | No | Partial |
SSG is the only static site generator that handles CSP extraction and SRI hashing automatically at build time.
- Clone the repository:
git clone https://github.com/sebastienrousseau/static-site-generator.git
cd static-site-generator- Build the example site:
cargo run -- -c examples/content/en -o /tmp/csp-demo -t examples/templates- Check the output HTML for inline code:
grep -r '<style>' /tmp/csp-demo/ | wc -l
# Should output 0- Verify SRI hashes are present:
grep -r 'integrity=' /tmp/csp-demo/ | head -5The CSP plugin (src/csp.rs) implements the Plugin trait with has_transform() = true. This means it runs in the fused transform pipeline. Each HTML file is read once, transformed, and written once.
The plugin is idempotent. Running it twice produces the same output. This is important for incremental builds where some pages are reprocessed.
- No XSS via inline injection: All code comes from external files with verified hashes
- Tamper detection: SRI hashes catch any modification to CSS or JS files
- Defence in depth: CSP + SRI + external files create three layers of protection
- Zero configuration: Works out of the box with the default plugin pipeline