Community编程与开发github.com

安全应用脚手架

用于启动、搭建或重构一个遵循安全设计原则(ANSSI/CIS/FBI/OWASP ASVS)的Web应用程序,或用于添加身份验证、授权、文件上传、审计日志、管理功能、Docker/Podman部署或MCP端点。生成无根TypeScript前端 + Python后端 + 强化版PostgreSQL技术栈,内置零信任输入、对象级授权、列级加密、幂等写入、OIDC/LDAPS/WebAuthn、防篡改审计日志、蜜罐令牌、签名镜像、双重扫描(Trivy + OpenSCAP)以及预投产清理流程。

安全应用脚手架 是什么?

这是一个高度专业化的AI辅助脚手架工具,专门用于生成符合ANSSI、CIS、FBI和OWASP ASVS Level 2标准的“安全优先”Web应用。它适用于启动新项目、添加关键安全功能或对现有架构进行安全重构。该工具支持在Docker和Podman(无根模式)上部署,遵循严格的零信任原则,默认采用拒绝策略。其核心功能包括:自动生成威胁模型、实施对象级和功能级授权(防止IDOR/BOLA)、对PII进行列级AES-256-GCM加密、使用链式哈希实现抗篡改审计日志、集成OIDC/LDAPS/WebAuthn单点登录、以及包含蜜罐令牌、签名镜像、Trivy + OpenSCAP双重扫描的主动防御机制。该脚手架通过强制性规则(如无子进程、无硬编码密钥、依赖锁定、CSP兼容代码、输入验证等)强制执行安全编码规范,并内置了预投产清理流程,确保应用不会携带可被利用的默认配置或测试数据。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/SkouedLabs/SkouedSkills/tree/HEAD/.claude/skills/secure-app-scaffolder

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

安全应用脚手架 是做什么的?

生成符合ANSSI、CIS、FBI和OWASP ASVS Level 2标准的安全优先应用:TypeScript前端、Python后端、强化版PostgreSQL。

布局、README和UI遵循 project-blueprint 技能。本技能中的安全规则优先于任何便捷性或UX规则。

参考文件(生成匹配产物时读取)

使用时机

  • 启动、搭建或架构新的Web应用或服务。
  • 需求中提及ANSSI、CIS、FBI、OWASP、强化、无根、合规性。
  • 添加身份验证、授权、文件上传、审计日志、管理功能、部署文件或MCP端点。

部署目标: 仅限Docker和无根Podman。除非用户明确要求,否则不要生成Kubernetes、Helm或其他编排器清单。

0. 威胁模型

  • 创建 docs/security/threat-model.md(≤1页):包含资产、信任边界、角色、主要风险(STRIDE)以及缓解每个风险的控制措施。当出现新的信任边界(如上传、Webhook、LLM、MCP)时更新。

1. 容器与运行时

  • 无根模式: 每个镜像都以数字 USER(例如 USER 10001:10001)结尾,包括Web服务器(nginxinc/nginx-unprivileged,端口 > 1024)。
  • 最小化、固定版本镜像: 多阶段构建;运行阶段为distroless或精简镜像,无shell、编译器或包管理器;排除开发依赖。基础镜像按摘要固定。使用最新的稳定版Python。
  • 强化: 启用 read_only、为可写路径挂载 tmpfs、cap_drop: [ALL]、no-new-privileges、使用运行时默认seccomp配置文件(从不使用 unconfined)、设置 pids_limit、内存限制、健康检查、禁用核心转储(ulimits: core: 0)。只有反向代理发布端口;数据库网络设置为 internal: true。永不挂载Docker/Podman套接字。
  • 无子进程: 不使用 subprocess、os.system、shell=True。通过以下方式强制执行:镜像中无shell、SAST规则、以及每个工作进程启动后加载的进程内seccomp过滤器,阻止 execve/execveat(容器级别的拒绝会阻止入口点本身启动)。
  • 首次运行保证: 在干净的克隆上,docker compose up(也包括 docker-compose up 和 podman compose up)首次即可工作:无需 .env、无需手动步骤、除容器引擎外无其他先决条件。镜像自动构建(build:),仅使用Docker Compose v2和podman-compose支持的Compose Specification功能,不使用仓库外的主机路径,发布端口 > 1024,不设置CPU限制(在无根cgroup设置中不可用)。make up 是同一命令的轻量级包装。
  • 无硬编码密钥: 一次性 init 服务将密钥生成到命名卷(0600)中,通过 *_FILE 变量消费。在生产环境中,密钥从文件而非环境变量读取。
  • 隔离环境: 所有JS/CSS/字体/图标均为本地打包;无CDN、运行时下载或遥测。离线构建时,依赖来自内部镜像仓库(Nexus、Artifactory、devpi、Verdaccio)。
  • Vault就绪: 单一密钥提供者抽象(默认为 file,生产环境使用 vault/sops)。
  • 内部TLS: 后端 ↔ 数据库之间使用TLS;服务之间可选mTLS。

2. 供应链与扫描

  • 锁定依赖: 提交锁定文件;使用 npm ci、uv sync --frozen 或 pip install --require-hashes。配置 .npmrc 使用 ignore-scripts=true,除非某个包需要安装脚本(使用白名单)。
  • 预构建门禁: npm audit --audit-level=high 和 pip-audit 在退出码 > 0 时使构建失败。
  • SAST与密钥扫描: pre-commit钩子使用 ruff、bandit/semgrep、eslint(+ eslint-plugin-security)、gitleaks。
  • 镜像扫描(make scan): trivy image(CVE + 密钥 + 错误配置)、在Dockerfile和Compose文件上执行 trivy config、针对基础操作系统的CIS配置集执行 oscap-podman(或 oscap-docker)。
  • SBOM与签名(make sbom): CycloneDX SBOM(使用Trivy或Syft生成),使用 cosign 签名镜像(离线环境使用密钥),SBOM作为认证附加;部署时验证签名。
  • DAST(可选,推荐): 在CI中针对运行中的堆栈执行OWASP ZAP基线扫描。
  • 更新: 在固定节奏上使用Renovate/Dependabot(或等效的离线审查)。

3. 前端(TypeScript)

  • 位置: /frontend 目录,包含自己的 Dockerfile,构建为静态资源,由非特权Nginx提供服务。
  • CSP兼容代码: 无内联 <script>、无 eval/new Function、无运行时CSS-in-JS注入不带nonce的 <style>。优先使用编译后的CSS。启用Trusted Types(require-trusted-types-for 'script')。
  • 零信任输入: 每个表单使用类型化Zod模式,与API类型共享。不对不可信数据使用 dangerouslySetInnerHTML/v-html;如果富文本无法避免,则使用DOMPurify。
  • 幂等性: API客户端为每个POST/PUT/PATCH/DELETE请求附加一个 Idempotency-Key(UUIDv4),每个用户操作生成一次,重试时重用。
  • CSRF防护: 自定义头(X-Requested-With)+ CSRF令牌;后端还检查 Origin/Sec-Fetch-Site。CORS仅限白名单,绝不对携带凭据的请求使用 *。
  • 开放重定向防护: 登录后的 next/returnUrl 仅接受以单个 / 开头的相对路径。
  • 捆绑包中无密钥; 生产中无源码映射;localStorage/sessionStorage 中不存储敏感数据。

4. 后端(Python)与数据库

  • 验证: 每个请求体、查询参数、路径参数和请求头均由Pydantic验证,包含最大长度和 extra="forbid"(防止批量赋值:role、owner_id、is_admin 永远不能从输入中绑定)。
  • 资源限制: 最大请求体大小、最大JSON深度/数组长度、最大分页大小(例如100)、服务端超时。用户输入的正则表达式需有界或使用线性时间引擎(re2)以避免ReDoS。
  • 安全解析: 不使用 pickle、marshal、yaml.load(使用 yaml.safe_load)、eval。XML使用 defusedxml。模板源码中不包含用户输入(SSTI)。文件路径需解析并对照基目录检查(路径遍历)。
  • 幂等性存储: (user_id, key) -> request_hash, status, response,TTL为24小时。相同key + 相同hash返回存储的响应;不同hash返回 422。这防止了重复请求;重放防护来自TLS、CSRF令牌和短会话。
  • SQL: 仅使用ORM或参数化查询;动态标识符(ORDER BY、列名)通过白名单控制。
  • 列级加密: PII在应用内部使用AES-256-GCM加密,采用信封加密(每条记录的DEK由来自密钥提供者的主密钥包裹),设置 key_version 列用于轮换,对可搜索字段使用HMAC-SHA256盲索引。主密钥绝不存储在数据库或数据库备份中。
  • 数据库强化: 最小化PostgreSQL,使用 scram-sha-256 认证、TLS、两个角色(迁移所有者、运行时仅DML角色)、应用无超级用户权限、Alembic迁移、运行时角色设置 statement_timeout。
  • SQL控制台(如果有): 只读角色、仅允许单条 SELECT、设置 statement_timeout、行数限制、锁定配置。
  • 加密与后量子: 静态AES-256-GCM具有量子抗性。后量子就绪性针对密钥交换和签名:代理上使用混合TLS X25519MLKEM768;仅在库支持的情况下使用ML-KEM/ML-DSA(FIPS 203/204)。随机值来自 secrets/crypto.getRandomValues。绝不自行实现加密原语。
  • 出站请求(SSRF): 任何UI可配置的URL(Webhook、syslog、LLM、OIDC)都经过验证:仅允许 https(除非明确白名单),解析后的IP如果是回环/链路本地/元数据地址(169.254.0.0/16、fd00:ec2::254)或私有地址(除非白名单)则拒绝,DNS解析后重新检查(DNS重绑定),不进行跨主机重定向,严格的超时。
  • 出站Webhook: 使用HMAC-SHA256签名(X-Signature + 时间戳),以便接收方验证。
  • 电子邮件: 头信息值剥离CR/LF;使用带证书验证的SMTPS。
  • 导出: CSV/XLSX中以 =、+、-、@、制表符或CR开头的单元格前面加上 '(防止公式注入)。
  • 速率限制: 登录、密码重置、MFA验证、API密钥、导出、上传和高成本端点。
  • 响应: 已验证的API响应设置 Cache-Control: no-store。使用包含 request_id 的通用错误消息;堆栈跟踪仅记录在日志中。生产中禁用OpenAPI UI或仅限管理员使用。

5. 授权

  • 默认拒绝: 每个路由声明其所需权限;未声明的路由会在启动或测试时失败。
  • RBAC: 使用映射到权限的角色(而非直接在代码中检查角色)。
  • 对象级检查(IDOR/BOLA): 在仓库层对每个按ID进行的读/写操作执行所有权或租户检查。对现有对象的未授权访问返回 404。
  • 功能级检查: 管理路由位于 /api/v1/admin/* 下,由单个依赖守卫,绝不通过仅隐藏UI来保护。
  • 敏感操作(角色变更、密钥创建、导出、删除用户)需要最近重新认证;角色提升为管理员时可选的“四眼”审批。

6. 文件上传(如果有)

  • 在代理和应用层面设置大小限制;扩展名白名单和魔数检查。
  • 存储在Web根目录之外(或对象存储中),随机文件名,使用 Content-Disposition: attachment 和 X-Content-Type-Options: nosniff 提供服务。
  • 图像重新编码(剥离EXIF和图片内嵌文件);存档文件检查炸弹攻击和路径遍历;可选离线防病毒(ClamAV)。
  • 除非经过清理并从隔离源提供服务,否则拒绝SVG和HTML上传。

7. 日志、审计与管理

  • 结构化日志: JSON格式,级别为DEBUG/INFO/WARN/ERROR/CRITICAL,处处包含 request_id,使用UTC时间戳,从用户值中剥离CR/LF。绝不记录密码、令牌、密钥、会话ID。
  • 远程Syslog: 使用TLS(RFC 5425)的RFC 5424协议,带有有界本地缓冲区;主机、端口、TLS、CA可在管理UI中配置。无rsyslog容器。
  • 错误通知: SMTPS和Webhook可从管理UI配置,经过SSRF验证,包含“发送测试”按钮,可限流。
  • PII屏蔽: 可从管理UI切换的中间件。
  • 防篡改审计追踪: 仅追加表(运行时角色仅拥有 INSERT/SELECT 权限),每行与前一行的哈希链接,转发到syslog。涵盖登录、失败、MFA变更、角色变更、配置变更、导出、API密钥、蜜罐命中;记录用户、IP、用户代理、UTC时间以及变更前后的值。
  • 管理仪表盘: 使用统计、错误、蜜罐告警、被封禁的IP。
  • 计划性清理: 禁用不活跃账户、清除过期令牌/会话/幂等性键、每日加密备份(密钥与备份分离)、保留策略以及经过测试的恢复流程(make restore-test)。
  • 个人数据(GDPR): 每种数据类型的数据保留期限、用户数据导出和删除、清理任务。

8. 身份验证、身份与主动防御

  • 密码: Argon2id(使用argon2-cffi的默认值 / RFC 9106,最小 m=19 MiB,t=2,p=1),参数更改时在登录时重新哈希。密码策略遵循NIST SP 800-63B:≥ 12个字符,最大 ≥ 64个字符,无组合规则,如果存在于捆绑的已泄露/常见密码列表中则拒绝。
  • 登录: 对未知用户返回相同的响应和时间,逐步延迟 + 按账户和按IP限流(避免导致拒绝服务攻击的硬锁定)。
  • 密码重置: 一次性随机令牌,以哈希形式存储,30分钟有效期,无论账户是否存在都返回相同响应,重置后撤销所有会话。
  • 会话: 服务端会话,cookie为 __Host-session(HttpOnly; Secure; SameSite=Lax; Path=/),登录和权限变更时轮换ID,用户可以列出和撤销其活跃会话。浏览器存储中不使用JWT;如果服务间使用JWT:算法固定,拒绝 none,检查 aud/iss/exp,短生命周期。
  • 管理员会话: 空闲1小时,绝对时间8小时,破坏性操作需要重新认证。
  • MFA: TOTP(哈希恢复码,拒绝重放相同代码)和WebAuthn/Passkeys。管理员账户必须启用MFA。
  • 上下文检测: 从未知IP/设备的管理员登录会触发“新登录”通知,并在MFA确认前限制破坏性权限。
  • 引导管理员: 首次启动时生成随机密码,可通过 make admin-password 查看一次,首次登录时强制重置密码并注册MFA。
  • 紧急账户(可选): 当SSO不可用时使用的本地管理员账户,默认禁用,每次使用都会触发严重告警。
  • SSO: OIDC授权码流程 + PKCE,验证 state 和 nonce,检查ID令牌签名/aud/iss;LDAPS或带证书验证的StartTLS,LDAP过滤器值已转义(防止LDAP注入)。目录组映射到角色。
  • SSO配置,两个等效来源: 每个OIDC和LDAP(S)设置(启用标志、颁发者/服务器URL、客户端ID、作用域、绑定DN、基DN、用户/组过滤器、CA捆绑包、组到角色映射、自动配置)既可以从管理UI设置,也可以从环境变量(BACKEND_OIDC_*、BACKEND_LDAP_*)设置。
    • 密钥(client_secret、绑定密码)来自 *_FILE 变量或密钥提供者,生产中绝不使用明文环境变量值;在UI中它们是只写的(显示 ••••last4)。
    • 优先级:由环境定义的设置获胜,并在管理UI中显示为只读,带有“由环境管理”徽章;其他所有内容均可编辑并以加密形式存储在数据库中。
    • 两个来源使用相同的验证规则(由环境加载器和管理API共享的Pydantic模式);无效的环境配置会导致启动失败并显示清晰的错误消息,无效的UI输入在保存前被拒绝。
    • 管理UI包含“测试连接”功能(OIDC发现 + JWKS获取,LDAP绑定 + 示例组搜索),每次更改都会记录审计日志。
    • 每个…

[翻译截断]

相关技能