SPB Git

spb/ultra-sharp-agent-skills Public

Ultra-Sharp Agent Skills — a research-first skill-authoring system + 72 production-ready skills for AI agents.

Python 100%
4.1 KB · 119 lines markdown
Rendered Raw Blame History
1<!--2Author: Simon-Pierre Boucher3Contact: contact@spboucher.ai4-->56# Patterns — Securing Backend Services78## Contents9- Security-headers middleware10- SSRF-safe URL fetcher11- CSRF setup12- Problem+json error mapper13- Secrets loading14- Dependency scanning in CI15- Gotchas1617## Security-headers middleware1819```python20SECURITY_HEADERS = {21    "Strict-Transport-Security": "max-age=31536000; includeSubDomains",22    "X-Content-Type-Options": "nosniff",23    "Content-Security-Policy": "default-src 'self'; frame-ancestors 'none'",24    "Referrer-Policy": "strict-origin-when-cross-origin",25    "Cache-Control": "no-store",          # for API responses carrying user data26}2728@app.middleware("http")29async def add_security_headers(request, call_next):30    resp = await call_next(request)31    for k, v in SECURITY_HEADERS.items():32        resp.headers.setdefault(k, v)     # setdefault: edge/proxy may own some33    return resp34```3536## SSRF-safe URL fetcher3738```python39import ipaddress, socket40from urllib.parse import urlparse4142ALLOWED_HOSTS = {"api.partner.example"}   # allowlist beats any blocklist4344def assert_public(host: str):45    for info in socket.getaddrinfo(host, None):46        ip = ipaddress.ip_address(info[4][0])47        if ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved:48            raise ValueError(f"blocked address {ip}")4950def safe_fetch(url: str):51    p = urlparse(url)52    if p.scheme != "https" or p.hostname not in ALLOWED_HOSTS:53        raise ValueError("destination not allowed")54    assert_public(p.hostname)             # resolve NOW, at request time55    return requests.get(url, timeout=10, allow_redirects=False)  # re-check per hop if following56```5758## CSRF setup5960```python61# Use the framework middleware — do not hand-roll token comparison.62# Django: CsrfViewMiddleware (default). Flask: flask-wtf CSRFProtect(app).63# FastAPI cookie-auth: double-submit cookie via starlette-csrf.64# Token in a custom header (X-CSRF-Token) read from a non-HttpOnly cookie;65# SameSite=Lax remains as defense-in-depth, not the defense.66```6768## Problem+json error mapper6970```python71@app.exception_handler(Exception)72async def unhandled(request, exc):73    cid = request.state.correlation_id74    logger.exception("unhandled error cid=%s", cid)      # full detail → logs75    return JSONResponse(status_code=500, content={       # zero detail → client76        "type": "about:blank", "title": "Internal error",77        "status": 500, "correlation_id": cid,78    })79```8081## Secrets loading8283```python84import os8586class Settings:87    def __init__(self):88        self.db_url = self._req("DATABASE_URL")89        self.signing_key = self._req("SIGNING_KEY")9091    @staticmethod92    def _req(name: str) -> str:93        val = os.environ.get(name)94        if not val:95            raise RuntimeError(f"missing required secret {name}")  # fail fast, no defaults96        return val97```9899Pre-commit guard: `gitleaks protect --staged` blocks accidental secret commits.100101## Dependency scanning in CI102103```yaml104# GitHub Actions105- run: pip install pip-audit && pip-audit --strict     # Python106- run: npm audit --audit-level=high                    # Node107# Fail the build on criticals; schedule a weekly run so quiet repos still alert.108```109110## Gotchas111112- **HSTS on a domain still serving plain HTTP paths** locks users out for max-age; deploy HTTPS fully first, then add the header, then preload.113- **CSP `report-only` left on forever** — attackers are unaffected by reports; graduate to enforcing after a week of clean reports.114- **SSRF via DNS rebinding** — validate the resolved IP at request time (as above), not in a separate pre-check the attacker can race.115- **`allow_redirects=True` after an allowlist check** — the first hop is allowed, the redirect goes to the metadata IP; disable or re-validate per hop.116- **Rotating a secret without invalidating derived artifacts** — old JWTs signed with the leaked key stay valid; rotate key AND revoke issued tokens.117- **One shared "backend" IAM role** — a compromise anywhere is a compromise everywhere; one identity per service.118- **Error middleware ordered after routers** — exceptions in earlier middleware bypass the mapper; register it outermost.119