gila-astro-csp
v0.1.0
Published
Astro 5+ integration for SRI (Subresource Integrity) and CSP (Content-Security-Policy) with nginx support
Downloads
127
Maintainers
Readme
gila-astro-csp
Astro 5+ integration for automatic SRI (Subresource Integrity) and CSP (Content-Security-Policy) generation with nginx support.
Why gila-astro-csp?
Modern web security requires strict CSP headers to prevent XSS attacks. However, frameworks like Astro generate inline scripts that break when using CSP without unsafe-inline.
gila-astro-csp solves this by:
- Scanning all HTML files after build
- Calculating SHA-256 hashes for inline scripts and styles
- Adding
integrityattributes to HTML elements - Generating nginx-ready CSP configuration
Result: A+ security rating without unsafe-inline or unsafe-eval.
Installation
npm install gila-astro-cspQuick Start
Add to your astro.config.mjs:
import { defineConfig } from 'astro/config';
import { gilaCSP } from 'gila-astro-csp';
export default defineConfig({
integrations: [
gilaCSP()
]
});Run your build:
npm run buildThat's it! Check dist/_csp/ for the generated files.
Configuration
Full Example
import { gilaCSP } from 'gila-astro-csp';
export default defineConfig({
integrations: [
gilaCSP({
// Pre-configured external services
presets: ['google-analytics', 'cloudflare-insights', 'google-fonts'],
// Nginx output configuration
nginx: {
outputPath: './dist/_csp/nginx.conf',
includeComments: true,
},
// JSON output for custom integrations
json: {
outputPath: './dist/_csp/hashes.json',
pretty: true,
},
// Additional CSP directives
directives: {
'img-src': ["'self'", 'data:', 'https:'],
'connect-src': ['https://api.example.com'],
},
})
]
});Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| presets | string[] | [] | Pre-configured services (see below) |
| nginx | object \| false | { outputPath: './dist/_csp/nginx.conf' } | Nginx config output |
| json | object \| false | { outputPath: './dist/_csp/hashes.json' } | JSON output |
| directives | object | {} | Additional CSP directives |
Available Presets
| Preset | Description | Adds |
|--------|-------------|------|
| google-analytics | Google Analytics & GTM | script-src, connect-src |
| cloudflare-insights | Cloudflare Web Analytics | script-src, connect-src |
| google-fonts | Google Fonts | style-src, font-src |
Output Files
nginx.conf
Ready-to-include nginx configuration:
# Content-Security-Policy Header
# Generated by gila-astro-csp
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'sha256-abc123...' 'sha256-def456...'; style-src 'self' 'sha256-xyz789...'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; form-action 'self'; base-uri 'self'" always;hashes.json
JSON file for custom integrations:
{
"scripts": [
"sha256-abc123...",
"sha256-def456..."
],
"styles": [
"sha256-xyz789..."
],
"externalScripts": [
"https://www.googletagmanager.com"
],
"externalStyles": [
"https://fonts.googleapis.com"
],
"directives": {
"default-src": ["'self'"],
"script-src": ["'self'", "'sha256-abc123...'"]
}
}Usage with Nginx
Option 1: Include the generated file
server {
listen 443 ssl;
server_name example.com;
include /path/to/dist/_csp/nginx.conf;
# ... rest of config
}Option 2: Use with nginx-proxy (Docker)
Copy to your vhost.d folder:
cp dist/_csp/nginx.conf /etc/nginx/vhost.d/example.com_locationAutomation Script
Create a script to update nginx after build:
#!/bin/bash
# scripts/update-csp.sh
CSP_CONF="./dist/_csp/nginx.conf"
VHOST_DIR="/etc/nginx/vhost.d"
# Extract CSP line
CSP_LINE=$(grep 'add_header Content-Security-Policy' "$CSP_CONF")
# Update vhost files
for file in "$VHOST_DIR/example.com" "$VHOST_DIR/example.com_location"; do
if [ -f "$file" ]; then
sed -i '/^add_header Content-Security-Policy/c\'"$CSP_LINE" "$file"
fi
done
# Reload nginx
nginx -s reloadHow It Works
Build Process
┌─────────────────────────────────────────────────────────────┐
│ Astro Build │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 1. Scanner │
│ - Find all HTML files in dist/ │
│ - Extract inline <script> and <style> content │
│ - Detect external scripts (https://) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 2. Hasher │
│ - Calculate SHA-256 hash for each inline element │
│ - Format as 'sha256-{base64}' │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 3. Injector │
│ - Add integrity="sha256-..." to HTML elements │
│ - Update HTML files in place │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 4. Generator │
│ - Merge hashes with presets and custom directives │
│ - Generate nginx.conf with CSP header │
│ - Generate hashes.json for custom use │
└─────────────────────────────────────────────────────────────┘Security Benefits
| Without gila-astro-csp | With gila-astro-csp |
|------------------------|---------------------|
| script-src 'unsafe-inline' | script-src 'sha256-...' |
| Vulnerable to XSS | Protected against XSS |
| Security grade: C/D | Security grade: A+ |
Examples
Basic Static Site
// astro.config.mjs
import { gilaCSP } from 'gila-astro-csp';
export default defineConfig({
integrations: [
gilaCSP()
]
});With Google Analytics
import { gilaCSP } from 'gila-astro-csp';
export default defineConfig({
integrations: [
gilaCSP({
presets: ['google-analytics'],
})
]
});With Multiple Services
import { gilaCSP } from 'gila-astro-csp';
export default defineConfig({
integrations: [
gilaCSP({
presets: ['google-analytics', 'cloudflare-insights', 'google-fonts'],
directives: {
'img-src': ["'self'", 'data:', 'https:', 'blob:'],
'connect-src': ['https://api.myservice.com'],
},
})
]
});Custom Output Paths
import { gilaCSP } from 'gila-astro-csp';
export default defineConfig({
integrations: [
gilaCSP({
nginx: {
outputPath: '../nginx/csp.conf',
includeComments: false,
},
json: {
outputPath: '../config/csp-hashes.json',
},
})
]
});Disable JSON Output
import { gilaCSP } from 'gila-astro-csp';
export default defineConfig({
integrations: [
gilaCSP({
json: false, // Only generate nginx config
})
]
});TypeScript Support
Full TypeScript support with exported types:
import { gilaCSP } from 'gila-astro-csp';
import type { GilaCSPOptions, PresetName, CSPDirectives } from 'gila-astro-csp';
const options: GilaCSPOptions = {
presets: ['google-analytics'] as PresetName[],
directives: {
'img-src': ["'self'", 'data:'],
} as Partial<CSPDirectives>,
};
export default defineConfig({
integrations: [gilaCSP(options)]
});Troubleshooting
Scripts still blocked after build
- Clear browser cache
- Verify nginx reloaded:
nginx -s reload - Check CSP header in DevTools > Network > Response Headers
Hash mismatch errors
Hashes are calculated from exact content. If you see mismatches:
- Ensure no post-build modifications to HTML
- Check for whitespace differences
- Rebuild:
npm run build
External scripts not working
Add the domain to presets or directives:
gilaCSP({
directives: {
'script-src': ['https://cdn.example.com'],
},
})Contributing
Contributions are welcome! Please read our contributing guidelines.
# Clone
git clone https://github.com/petryx/gila-astro-csp.git
# Install
npm install
# Test
npm test
# Build
npm run buildLicense
MIT License - see LICENSE for details.
Credits
Developed by Gila Security - Cybersecurity specialists helping companies protect their digital assets.
Need help securing your web application? Contact Gila Security for professional cybersecurity services.
