Claude-skill-registry astro-security
Security patterns for Astro lead generation websites on Cloudflare. Forms, headers, bot protection, GDPR. Use for any production lead gen site.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/astro-security" ~/.claude/skills/majiayu000-claude-skill-registry-astro-security && rm -rf "$T"
manifest:
skills/data/astro-security/SKILL.mdsource content
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:
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
# .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
for public vars onlyimport.meta.env - 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