docs: add security documentation with trust model and CSP
Add Security section to README documenting: - Trust model (untrusted content, trusted binary) - HTML passthrough implications - URL escaping behavior Create docs/content/features/security.md with: - Detailed trust model table - Content processing security notes - CSP header recommendations - Platform-specific examples (Cloudflare, Netlify, Nginx) Closes audit recommendations 4 and 5.
This commit is contained in:
17
README.md
17
README.md
@@ -90,6 +90,23 @@ content/
|
||||
|
||||
Full documentation at [sukr.io](https://sukr.io) (built with sukr).
|
||||
|
||||
## Security
|
||||
|
||||
sukr processes content at **build time only** — there is no runtime attack surface.
|
||||
|
||||
**Trust Model:**
|
||||
|
||||
- **Untrusted:** Markdown content, frontmatter, third-party templates
|
||||
- **Trusted:** The compiled sukr binary, Tree-sitter grammars
|
||||
|
||||
**Security Implications:**
|
||||
|
||||
- Raw HTML in Markdown is passed through (CommonMark spec). If your content comes from untrusted sources, review it before building.
|
||||
- URLs in links and images are escaped to prevent attribute injection.
|
||||
- Templates use Tera's auto-escaping for variables; `{{ content | safe }}` is used intentionally for pre-rendered HTML.
|
||||
|
||||
For deployment-time security (CSP headers, etc.), see the [Security docs](https://sukr.io/security.html).
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
101
docs/content/security.md
Normal file
101
docs/content/security.md
Normal file
@@ -0,0 +1,101 @@
|
||||
---
|
||||
title: Security
|
||||
description: Content trust model and deployment security guidance
|
||||
weight: 90
|
||||
---
|
||||
|
||||
# Security
|
||||
|
||||
sukr is a **build-time only** compiler with no runtime attack surface. Security considerations focus on content processing and deployment.
|
||||
|
||||
## Trust Model
|
||||
|
||||
| Source | Trust Level | Rationale |
|
||||
| :------------------- | :--------------- | :--------------------------------------------------- |
|
||||
| Markdown content | **Untrusted** | May come from contributors, CMS, or external sources |
|
||||
| YAML frontmatter | **Untrusted** | Parsed from content files |
|
||||
| Templates | **Semi-trusted** | User-controlled but typically from known sources |
|
||||
| sukr binary | **Trusted** | Compiled from audited Rust code |
|
||||
| Tree-sitter grammars | **Trusted** | Compiled into the binary |
|
||||
|
||||
## Content Processing
|
||||
|
||||
### HTML Passthrough
|
||||
|
||||
Per the CommonMark specification, raw HTML in Markdown is passed through to output:
|
||||
|
||||
```markdown
|
||||
<script>alert('hello')</script>
|
||||
```
|
||||
|
||||
**If your content comes from untrusted sources**, review it before building. sukr does not sanitize HTML — this is intentional to preserve legitimate use cases.
|
||||
|
||||
### URL Escaping
|
||||
|
||||
Link and image URLs are escaped to prevent attribute injection attacks:
|
||||
|
||||
```markdown
|
||||
<!-- This is safe — quotes are escaped -->
|
||||
|
||||
[click me](<"%3E%3Cscript%3Ealert(1)%3C/script%3E>)
|
||||
```
|
||||
|
||||
Produces escaped output, not executable script.
|
||||
|
||||
### Template Auto-Escaping
|
||||
|
||||
Tera templates auto-escape variables by default:
|
||||
|
||||
- `{{ title }}` — escaped (safe)
|
||||
- `{{ page.description }}` — escaped (safe)
|
||||
- `{{ content | safe }}` — intentionally unescaped (pre-rendered HTML)
|
||||
|
||||
## Deployment Security
|
||||
|
||||
### Content Security Policy
|
||||
|
||||
For maximum protection when serving sukr-generated sites, configure CSP headers on your web server or CDN.
|
||||
|
||||
**Recommended policy for sukr sites:**
|
||||
|
||||
```
|
||||
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'none'; frame-ancestors 'none'
|
||||
```
|
||||
|
||||
This policy:
|
||||
|
||||
- ✅ Allows styles (including inline for syntax highlighting)
|
||||
- ✅ Allows images and data URIs (for Mermaid SVGs)
|
||||
- ✅ Blocks all JavaScript execution
|
||||
- ✅ Prevents clickjacking
|
||||
|
||||
### Platform-Specific Headers
|
||||
|
||||
**Cloudflare Pages** (`public/_headers`):
|
||||
|
||||
```
|
||||
/*
|
||||
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'none'
|
||||
X-Content-Type-Options: nosniff
|
||||
X-Frame-Options: DENY
|
||||
```
|
||||
|
||||
**Netlify** (`public/_headers`):
|
||||
|
||||
```
|
||||
/*
|
||||
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'none'
|
||||
X-Content-Type-Options: nosniff
|
||||
```
|
||||
|
||||
**Nginx**:
|
||||
|
||||
```nginx
|
||||
add_header Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'none'";
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-Frame-Options DENY;
|
||||
```
|
||||
|
||||
## Reporting Issues
|
||||
|
||||
Report security issues via [security@sukr.io](mailto:security@sukr.io) or GitHub Security Advisories.
|
||||
Reference in New Issue
Block a user