Security best practices specifically for static HTML/CSS websites on GitHub Pages
license
Apache-2.0
Static Site Security Skill
🔴 AI FIRST Quality Principle
Apply the AI FIRST principle: never accept first-pass quality. Minimum 2 iterations. Read all output, improve every section. No shortcuts.
Purpose
Comprehensive security practices for static websites, leveraging their inherent security advantages while addressing remaining risks.
Security Advantages of Static Sites
Eliminated Attack Vectors
✅ No SQL Injection: No database to inject into
✅ No Server-Side XSS: No server-side rendering
✅ No CSRF: No state management or forms processing
✅ No Session Hijacking: No sessions to hijack
✅ No Remote Code Execution: No server-side code
✅ No File Upload Vulnerabilities: No upload functionality
✅ No Authentication Bypass: No authentication system
Reduced Attack Surface
Traditional Web App Attack Surface:
- Web server vulnerabilities
- Application code vulnerabilities
- Database vulnerabilities
- Server OS vulnerabilities
- Third-party libraries
- Session management
- File system access
- Network services
Static Site Attack Surface:
- CDN security (GitHub Pages)
- DNS hijacking
- Content integrity
- Dependency vulnerabilities (minimal)
Transport Layer Security
HTTPS Configuration
✅ Required:
- HTTPS-only (TLS 1.3)
- Automatic HTTPS redirect
- Valid SSL/TLS certificate
- Perfect Forward Secrecy (PFS)
For GitHub Pages:
- Enforced HTTPS in repository settings
- Automatic Let's Encrypt certificates
- TLS 1.3 support by default
<!-- ✅ Good: SRI for stable, versioned external resources --><scriptsrc="https://cdn.example.com/script.v1.2.3.js"integrity="sha384-..."crossorigin="anonymous"
></script><!-- ⚠️ Google Fonts: dynamic content, SRI not reliable unless you self-host --><!-- Either self-host the font CSS with SRI, or omit SRI for the dynamic URL: --><linkrel="stylesheet"href="https://fonts.googleapis.com/css2?family=Inter"crossorigin="anonymous"
><!-- ❌ Bad: No integrity check on a static, versioned asset --><scriptsrc="https://cdn.example.com/script.v1.2.3.js"></script>
Dependency Management
✅ Best practices:
1. Minimize external dependencies
2. Use trusted CDNs only (Google Fonts, etc.)
3. Implement SRI for CDN resources
4. Regular dependency scanning
5. Prefer self-hosted over CDN when possible
6. Document all external dependencies
HTML Injection Prevention
<!-- Even static sites can have issues if using templates --><!-- ❌ Bad: Unsafe data in HTML --><div>{{ userData }}</div><!-- ✅ Good: Escaped/sanitized --><div>{{ userData | escape }}</div><!-- ✅ Best: Static content only --><div>Hardcoded safe content</div>
Access Control Security
GitHub Repository Security
✅ Required access controls:
- MFA enabled for all contributors
- SSH keys with passphrase
- GPG commit signing required
- Branch protection on main/master
- Required pull request reviews
- Status checks must pass
- Restrict who can push
- Restrict force pushes
GitHub Pages Security
✅ Configuration:
- Enforce HTTPS enabled
- Source branch restricted (main only)
- Custom domain with DNSSEC (optional)
- Repository visibility: Public (for open source)
Secrets Management
✅ Never commit:
- API keys
- Passwords
- Private keys
- OAuth tokens
- Any credentials
✅ Use instead:
- GitHub Secrets for CI/CD
- Environment variables
- Secure credential stores
- GitHub Apps (not PATs when possible)
CDN and Hosting Security
GitHub Pages Security Model
✅ GitHub provides:
- Global CDN with DDoS protection
- Automatic TLS certificates
- High availability (99.9% SLA)
- Infrastructure security
- Regular security updates
⚠️ User responsibilities:
- Content security
- Access control
- Dependency management
- Security monitoring
DNS Security
✅ Best practices:
- Use DNSSEC if supported
- CAA records for certificate authority
- Monitor DNS for hijacking
- Use reputable DNS provider
Example CAA record:
example.com. CAA 0 issue "letsencrypt.org"
Immediate actions:
1. Disable GitHub Pages if compromised
2. Revoke exposed credentials
3. Block malicious IP addresses (if applicable)
4. Revert to last known good state
Recovery
Steps:
1. Identify root cause
2. Fix vulnerability
3. Test fix thoroughly
4. Deploy patched version
5. Verify security restored
6. Monitor for recurrence
# Security-hardened deployment workflowname:Deployon:push:branches: [main]
permissions:contents:read# Least privilegejobs:deploy:runs-on:ubuntu-lateststeps:-uses:step-security/harden-runner@SHAwith:egress-policy:audit-uses:actions/checkout@SHA-name:SecurityScanrun:|
# HTML validation
htmlhint *.html
# Link checklinkinator.--recurse# Dependency checknpmaudit-name:Deployif:success()run:echo"Deploy to GitHub Pages"
Rollback Procedures
✅ Ensure capability to:
1. Revert to previous commit (git revert)
2. Redeploy last known good version
3. Disable site temporarily if needed
4. Restore from backup if necessary
RTO (Recovery Time Objective): < 15 minutes
RPO (Recovery Point Objective): Last commit