Astro Security Skill
Security patterns for lead generation sites.
Core Rules (Non-Negotiable)
| Violation | Result |
|---|---|
| Production form without Turnstile + honeypot | FAIL |
| Secret exposed client-side | FAIL |
| User input stored without server validation | FAIL |
| Indexable staging environment | FAIL |
| Missing security headers | FAIL |
| Cookie banner missing before analytics | FAIL |
Form Security (Required)
Every form must have:
| Protection | Implementation |
|---|---|
| Turnstile | Cloudflare captcha (invisible mode) |
| Honeypot | Hidden field, reject if filled |
| Rate limit | Max 5 submissions/IP/hour |
| Validation | Server-side Zod, never trust client |
| Sanitize | Strip HTML, trim whitespace |
See references/forms.md.
Security Headers (Required)
CSP Rules:
- •MUST disallow inline scripts unless hashed
- •MUST restrict script-src to required domains only
- •MUST test in report-only before enforcement
Add to _headers:
code
X-Content-Type-Options: nosniff X-Frame-Options: DENY X-XSS-Protection: 1; mode=block Referrer-Policy: strict-origin-when-cross-origin Permissions-Policy: camera=(), microphone=(), geolocation=() Content-Security-Policy: [see references] Strict-Transport-Security: max-age=31536000; includeSubDomains
Environment Variables
code
# .env.example (commit this) TURNSTILE_SITE_KEY= TURNSTILE_SECRET_KEY= RESEND_API_KEY= GOOGLE_SHEETS_ID= # .env (never commit) # Add to .gitignore
Rules:
- •Never expose secrets client-side
- •Use
import.meta.envfor public vars only - •Validate all env vars on build
Bot Protection
Cloudflare (free tier):
- •Bot Fight Mode: ON
- •Security Level: Medium
- •Challenge Passage: 30 minutes
Application level:
- •Turnstile on all forms
- •Honeypot fields
- •Rate limiting per IP
- •Block empty referrer (optional)
Third-Party Scripts
- •Use SRI (integrity hash) for CDN scripts
- •Load async/defer
- •Minimize scripts
- •Review GTM tags regularly
GDPR Compliance
Required:
- •Cookie banner (before non-essential cookies)
- •Privacy policy page
- •Form consent checkbox (if marketing)
- •Data retention policy
- •Right to deletion process
Cookie categories:
| Type | Consent | Examples |
|---|---|---|
| Necessary | No | Session, CSRF |
| Analytics | Yes | GA4, Hotjar |
| Marketing | Yes | Meta Pixel, Google Ads |
See references/gdpr.md.
Input Validation
Never: Trust client-side alone, store raw input, render unsanitized HTML.
See forms.md for Zod schemas.
File Uploads
If needed: Max 5MB, whitelist types, rename files, store outside webroot.
Staging Protection
Password protect OR Cloudflare Access. Add noindex, block in robots.txt.
Error Handling
- •Error messages MUST NOT reveal stack traces or internals
- •API errors MUST return generic messages (
Something went wrong) - •Detailed errors allowed ONLY in development
- •404/500 pages must not leak tech stack info
Dependencies
- •Minimize third-party scripts
- •Remove unused dependencies before launch
- •Review third-party access quarterly
- •Prefer self-hosted over CDN when possible
Definition of Done
Security requirements before launch:
- • Turnstile on all forms
- • Honeypot fields added
- • Rate limiting configured
- • Security headers set
- • HTTPS enforced
- • .env in .gitignore
- • No secrets in client code
- • Cookie banner working
- • Privacy policy linked
- • Staging protected
- • Error pages don't leak info
References
- •forms.md — Form security patterns
- •headers.md — CSP and headers
- •gdpr.md — GDPR compliance