cspresso.cafe/src/content/docs.html
Miguel Jacq 6fc9e6f8c1
All checks were successful
CI / test (push) Successful in 1m42s
Update my GPG key
2026-03-11 12:01:12 +11:00

155 lines
8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "cspresso Docs"
description: "Docs for cspresso: crawl a site with headless Chromium and generate a draft Content-Security-Policy; evaluate candidates in Report-Only mode."
---
<main class="py-5">
<div class="container">
<div class="row g-4">
<div class="col-lg-3">
<div class="sticky-lg-top" style="top: 90px;">
<div class="fw-semibold mb-2">On this page</div>
<div class="list-group small">
<a class="list-group-item list-group-item-action" href="#install">Install</a>
<a class="list-group-item list-group-item-action" href="#run">Run</a>
<a class="list-group-item list-group-item-action" href="#output">Output</a>
<a class="list-group-item list-group-item-action" href="#inline">Inline scripts &amp; styles</a>
<a class="list-group-item list-group-item-action" href="#evaluate">Evaluate (Report-Only)</a>
<a class="list-group-item list-group-item-action" href="#flags">Flags</a>
</div>
<div class="mt-3 small text-secondary">
Prefer canonical docs? See the <a class="link-secondary" href="https://git.mig5.net/mig5/cspresso#readme" target="_blank" rel="noreferrer">README</a>.
</div>
</div>
</div>
<div class="col-lg-9">
<header class="mb-4">
<div class="kicker mb-2"><i class="bi bi-journal-text"></i> Docs</div>
<h1 class="display-6 fw-800 mb-2">Usage</h1>
<p class="text-secondary mb-0">
cspresso crawls up to <code>--max-pages</code> same-origin pages in Chromium, observes what loads, and emits a draft CSP.
</p>
</header>
<section id="install" class="mb-5">
<h2 class="section-title fw-bold">Install</h2>
<div class="row g-3">
<div class="col-lg-7">
<div class="codeblock">
<button class="btn btn-sm btn-outline-secondary copy-btn" data-copy-target="#docinst"><i class="bi bi-clipboard"></i> Copy</button>
<pre class="terminal mb-0"><code id="docinst"># Recommended
pipx install cspresso
# Or plain pip (use a venv)
pip install cspresso
# An AppImage is also available on the
# git repo Releases page.
</code></pre>
</div>
</div>
<div class="col-lg-5">
<div class="callout p-4 h-100">
<div class="fw-semibold mb-2">Python + Playwright</div>
<div class="text-muted">
You need Python 3.10+ and Playwrights Chromium. cspresso can auto-install Chromium if missing.
</div>
<hr>
<div class="small text-secondary">
Verify Releases artifacts with the mig5 key:
<a class="link-secondary" href="https://mig5.net/static/mig5.asc" target="_blank" rel="noreferrer">https://mig5.net/static/mig5.asc</a>
(fingerprint <code>54A91143AE0AB4F7743B01FE888ED1B423A3BC99</code>).
</div>
</div>
</div>
</div>
</section>
<section id="run" class="mb-5">
<h2 class="section-title fw-bold">Run</h2>
<div class="codeblock">
<button class="btn btn-sm btn-outline-secondary copy-btn" data-copy-target="#docrun"><i class="bi bi-clipboard"></i> Copy</button>
<pre class="terminal mb-0"><code id="docrun">cspresso https://example.com --max-pages 10</code></pre>
</div>
<div class="mt-3 text-secondary">
The crawl stays on the same origin (it follows internal links) and will wait for <code>networkidle</code> plus a small “settle”
delay to catch late fetches.
</div>
</section>
<section id="output" class="mb-5">
<h2 class="section-title fw-bold">Output</h2>
<p class="text-secondary">
Default output prints visited URLs as comments and then the proposed header line.
Use <span class="chip">--json</span> for machine-readable output.
</p>
<div class="codeblock">
<button class="btn btn-sm btn-outline-secondary copy-btn" data-copy-target="#docjson"><i class="bi bi-clipboard"></i> Copy</button>
<pre class="terminal mb-0"><code id="docjson">cspresso https://example.com --json</code></pre>
</div>
</section>
<section id="inline" class="mb-5">
<h2 class="section-title fw-bold">Inline scripts &amp; styles</h2>
<div class="callout p-4">
<div class="fw-semibold mb-2">Why this is hard</div>
<div class="text-muted">
If the page uses nonces, you must generate a new nonce per HTML response and inject it into both the CSP header and the HTML tags.
Hashes only work when inline content is stable byte-for-byte. For <code>style="..."</code> and <code>on*</code> attributes,
browsers require <code>'unsafe-hashes'</code> for hashes to apply.<br/>Not to worry, cspresso will detect these and generate the hashes
in its response, offering them as <code>style-src-attr</code> options or with <code>unsafe-hashes</code> for older browsers.
</div>
</div>
</section>
<section id="evaluate" class="mb-5">
<h2 class="section-title fw-bold">Evaluate (Report-Only)</h2>
<p class="text-secondary">
Provide a CSP string to <span class="chip">--evaluate</span> and cspresso will inject it as
<code>Content-Security-Policy-Report-Only</code> on HTML responses during the crawl. If any violations are detected, it exits with code <code>1</code>.
</p>
<p class="text-secondary">This is a great way of testing a cspresso-brewed CSP before actually adding it to your site.</p>
<div class="codeblock">
<button class="btn btn-sm btn-outline-secondary copy-btn" data-copy-target="#doceval"><i class="bi bi-clipboard"></i> Copy</button>
<pre class="terminal mb-0"><code id="doceval">cspresso https://example.com \
--bypass-csp \
--evaluate "default-src 'self'; script-src 'self' https://cdn.jsdelivr.net;" \
--json</code></pre>
</div>
<div class="mt-3 small text-secondary">
Recommendation: use <code>--bypass-csp</code> with <code>--evaluate</code> so existing CSP enforcement doesnt change the pages behaviour during testing.
</div>
</section>
<section id="flags">
<h2 class="section-title fw-bold">Flags</h2>
<p class="text-secondary">A condensed reference of the most-used options:</p>
<div class="row g-3">
<div class="col-md-6"><div class="callout p-4 h-100">
<div class="fw-semibold mb-2">Crawling</div>
<div class="text-muted"><span class="chip">--max-pages</span> <span class="chip">--timeout-ms</span> <span class="chip">--settle-ms</span> <span class="chip">--headed</span></div>
</div></div>
<div class="col-md-6"><div class="callout p-4 h-100">
<div class="fw-semibold mb-2">Policy shaping</div>
<div class="text-muted"><span class="chip">--include-sourcemaps</span> <span class="chip">--upgrade-insecure-requests</span> <span class="chip">--allow-blob</span> <span class="chip">--unsafe-eval</span></div>
</div></div>
<div class="col-md-6"><div class="callout p-4 h-100">
<div class="fw-semibold mb-2">Playwright</div>
<div class="text-muted"><span class="chip">--browsers-path</span> <span class="chip">--no-install</span> <span class="chip">--with-deps</span></div>
</div></div>
<div class="col-md-6"><div class="callout p-4 h-100">
<div class="fw-semibold mb-2">Evaluation</div>
<div class="text-muted"><span class="chip">--bypass-csp</span> <span class="chip">--evaluate</span> <span class="chip">--ignore-non-html</span> <span class="chip">--json</span></div>
</div></div>
</div>
</section>
</div>
</div>
</div>
</main>