一键导入
dangerous-config
危险配置静态值审计——对照最小权限基线检查配置文件字面量,覆盖调试模式、默认凭据、过宽 CORS、 弱 TLS、Actuator / Admin 端点未鉴权、反序列化危险默认、XXE、上传限制缺失等类目。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
危险配置静态值审计——对照最小权限基线检查配置文件字面量,覆盖调试模式、默认凭据、过宽 CORS、 弱 TLS、Actuator / Admin 端点未鉴权、反序列化危险默认、XXE、上传限制缺失等类目。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
白盒建模——一次深度建模产出五张共享模型:项目架构(技术栈/分层/框架自有封装/闭源依赖位置)、 入口点(路由/中间件信任边界)、认证与权限(会话/角色/多租户/归属字段)、业务(实体/流程状态机/ 业务不变量/高价值资产)、全局威胁(攻击面×漏洞类别的适用性映射,供下游逐一全测)。本能力不做漏洞判定,为后续 漏洞维度分析建立共享底图。
OS 命令注入综合检测——覆盖直接命令拼接 / shell 元字符 / 参数注入 / 间接 RCE,按回显 / 时间 / 带外通道分诊。 流量中参数值含主机名 / URL / 文件名 / 命令片段、响应里出现 shell 错误关键字(`/bin/sh` / `cmd.exe` / `command not found`)、注入 `sleep N` 耗时增加、上传后异步处理链路时使用。
文件上传多策略综合检测——覆盖扩展名 / MIME / 魔术数 / 解析漏洞 / 上传链组合(LFI / Zip Slip / SVG XSS / SVG XXE)。 流量含 multipart/form-data 上传、响应回显落盘路径、上传后文件可被 GET 解析、上传字段含 filename / path 可控时使用。
IDOR 水平越权检测 — 通过替换资源标识符(ID/UUID/路径)访问他人资源的风险;适用于用户资料、订单、文档、租户隔离场景。
检测路径穿越和本地文件包含(LFI)风险;当目标存在文件读取/下载/预览功能且含路径参数时触发;适用于文件下载、日志查看、模板加载等场景。
黑盒建模 — 迭代式攻击面建模,按站点级 / 页面级 / 功能级三粒度推进;进入新页面即触发一次页面级建模、切换新身份各刷新一次,产出端点账本与页面语义模型,为后续漏洞维度的适用性判断提供依据。
| name | dangerous-config |
| description | 危险配置静态值审计——对照最小权限基线检查配置文件字面量,覆盖调试模式、默认凭据、过宽 CORS、 弱 TLS、Actuator / Admin 端点未鉴权、反序列化危险默认、XXE、上传限制缺失等类目。 |
| when-to-use | 当项目存在框架配置文件(php.ini / web.xml / application.yml / nginx.conf 等)时 |
| allowed-tools | bash,read_file,list_files,rg |
| user-invocable | true |
按 配置介质 + 框架特征 + 依赖三维识别本能力命中场景。白盒视角——按配置文件类型 / 注解 / 依赖签名分类,不讨论流量 / HAR / 响应特征。
配置介质维度(grep / list_files 命中):
application.yml / application-*.yml / application.properties / bootstrap.ymlweb.xml / server.xml(Tomcat)/ context.xmlnginx.conf / apache.conf / Caddyfileconfig/*.json / config/*.yaml / *.toml / *.ini.env / .env.* / Dockerfile 的 ENV 指令docker-compose*.yml / k8s/*.yaml / helm/values.yaml / ConfigMapsettings.py / local_settings.py / config.py(FastAPI)config/*.json / 自定义 config.jsconfig/*.php / .env框架特征 / 注解维度:
@ConfigurationProperties / @Value("${...}") 注解spring-boot-starter-actuator)spring-boot-devtools)enableDefaultTyping / activateDefaultTypingDocumentBuilderFactory / SAXParserFactory)未显式禁用 DOCTYPE依赖维度:
pom.xml 含 Spring Boot Actuator / DevTools / H2 Consolepackage.json 含 cors / helmet / express-sessionrequirements.txt 含 django / fastapi / flaskgo.mod 含 gin-contrib/cors / 配置驱动的 TLS 库反向信号(不命中本能力):
配置项的"默认值"通常倾向便于开发而非生产安全——框架为降低上手门槛,把 debug / verbose / 全开式 CORS / 默认凭据等设为开箱即用,期望开发者上线时手工收敛。一旦上线流程缺少"配置 lint / 最小权限基线对照 / profile 严格隔离"环节,开发态默认值就会原样进入生产环境,每一项都对应一类直接可用的攻击面:
核心成因不在某一项配置错误,而在"基线对照缺失" —— 没有一份"生产环境每项配置应取值"的清单去逐项核对。本能力的工作即是把这份清单与项目实际配置对齐。
本能力 n/a(原因:配置项静态值审计,看配置字面量与最小权限基线对照;无 source-sink 数据流——配置项不是"用户可控输入流向危险函数"的形态,而是"项目配置值与安全基线值的偏差"。与配置消费代码的 source-sink 追踪(如读取了不安全配置后被消费到哪个 sink)由 dataflow-analysis 接力)。
本能力覆盖的配置维度(按已知主流覆盖,不追求穷举):
| 配置维度 | 危险默认值 | 安全配置值 | 主要影响 |
|---|---|---|---|
| 调试模式 | Django DEBUG=True / Flask debug=True / Spring server.error.include-stacktrace=always | False / never / on_trace_param | 堆栈泄露 / SQL 片段泄露 |
| 默认凭据 | admin/admin / root/root / password/password | 强随机生成 + 首次登录强制改 | 直接登录 |
| 过宽 CORS | Access-Control-Allow-Origin: * / null / 反射任意 Origin | 明确域名 allowlist | 跨源数据读取 |
| 弱 TLS | 启用 SSLv3 / TLS 1.0 / TLS 1.1 / RC4 / 3DES 套件 | TLS 1.2+ 且仅 AEAD 套件 | 中间人降级 |
| 上传限制缺失 | 无大小上限 / 无类型校验 / 无路径白名单 | size + MIME + 后缀 + 路径三重约束 | 资源耗尽 / 落 webshell |
| 错误页堆栈泄露 | Spring server.error.include-stacktrace=always / Django DEBUG=True 错误页 | 通用错误页 + 服务端日志 | 内部细节泄露 |
| Actuator / Admin 未鉴权 | Spring management.endpoints.web.exposure.include=* 无 Security | =health,info + Security 强绑定 | env / heapdump / 内存数据外泄 |
| 反序列化危险默认 | Jackson enableDefaultTyping / ObjectInputStream 无白名单 | 禁用 default typing / 显式类型白名单 | RCE |
| XML 外部实体未禁 | DocumentBuilderFactory 默认配置 | setFeature("...disallow-doctype-decl", true) + 禁用外部实体 | XXE → SSRF / 文件读 |
| WebSocket 跨源默认允许 | Spring setAllowedOrigins("*") / Node ws 不校验 origin | origin allowlist | 跨源 WS 劫持 |
| Cookie 加密 Key 默认值 | Laravel APP_KEY 未生成 / Express secret: 'keyboard cat' | 强随机 + Vault 注入 | Session 伪造 |
| 日志含敏感字段 | password / token / 身份证 字段未屏蔽 | 字段脱敏 / 结构化日志过滤 | 日志合规 / 凭据外泄 |
| 限流 / WAF 默认关闭 | nginx limit_req 未配 / WAF 仅 detect 模式 | 入口处 rate limit + WAF block 模式 | 暴力破解 / 资源耗尽 |
注:本表不是穷举清单——配置维度会随框架版本演化;以项目实际配置介质里出现的项为准,按 §8 基线检查项三态标注处置。
按项目结构定位配置文件 + 配置消费代码——两者必须配对看,单看配置文件会漏"运行时被环境变量 override",单看消费代码会漏"配置文件里的默认值已经不安全"。
下列框架 / 项目类型仅作类似项目示例 不限于此;以目标实际栈为准。
src/main/resources/application.yml / application-{profile}.yml / application.properties / bootstrap.ymlspring.profiles.active 由谁决定(环境变量 / 启动参数);再对每个 profile 独立审一遍@Value("${...}") 注入点 / @ConfigurationProperties(prefix = "...") 类management.* 配置 + Spring Security 是否配套拦截 /actuator/**conf/server.xml 的 <Connector> SSL 配置 / web.xml 的 <security-constraint>pom.xml / build.gradle 是否引入 Actuator / DevTools / H2 Consolesettings.py / local_settings.py 关键字段:DEBUG / ALLOWED_HOSTS / SECRET_KEY / CORS_* / SESSION_COOKIE_* / CSRF_COOKIE_* / SECURE_*config.py / app.config.from_object(...)requirements.txt 看 django-cors-headers / django-csp 版本config/*.json / config/*.js(node-config 约定)app.use(cors()) / app.use(helmet()) 实参package.json 看 cors / helmet / express-session 版本config/*.php 全套(app.php / session.php / cors.php / database.php).env 看 APP_DEBUG / APP_ENV / APP_KEYnginx.conf / sites-available/* / sites-enabled/* —— TLS / CORS / 限流 / 错误页apache.conf / httpd.conf / .htaccess —— TLS / Directory 权限 / TraceEnableCaddyfile —— TLS / 反向代理 headerDockerfile 的 ENV 指令(可能 override 镜像内默认配置)docker-compose*.yml 的 environment: 段k8s/*.yaml 的 ConfigMap / Secret / env: 段values.yaml —— profile 切换源头.github/workflows/*.yml / .gitlab-ci.yml / Jenkinsfile —— 部署阶段是否真把 prod profile 注入application-prod.yml > application.yml > 容器 ENV > 启动参数;遇到多源同名配置时按优先级取最终值本节列出主流框架下"安全配置 vs 危险配置"对照——同一语义在不同框架里写法差异巨大,本表是白盒原子 skill 的复利资产。
| 配置维度 | 框架 | 安全形态 | 危险形态 |
|---|---|---|---|
| 错误堆栈 | Spring Boot | server.error.include-stacktrace: never | server.error.include-stacktrace: always |
| 错误堆栈 | Django | DEBUG = False + ADMINS = [...] | DEBUG = True |
| 错误堆栈 | Express | app.use((err,req,res,next) => res.status(500).send('error')) | 默认堆栈输出 / errorhandler() 中间件 |
| Actuator 端点 | Spring Boot | management.endpoints.web.exposure.include: health,info + Spring Security 拦截 /actuator/** | management.endpoints.web.exposure.include: '*' 无 Security |
| 允许 Host | Django | ALLOWED_HOSTS = ['api.example.com'] | ALLOWED_HOSTS = ['*'] |
| CORS | Express | cors({ origin: ['https://app.example.com'], credentials: true }) | app.use(cors()) 默认全开 / origin: '*' + credentials: true |
| CORS | Spring | CorsConfiguration 显式 allowlist + setAllowCredentials(false) 或精确域 | addAllowedOriginPattern("*") + setAllowCredentials(true) |
| CORS | Django | CORS_ALLOWED_ORIGINS = [...] | CORS_ALLOW_ALL_ORIGINS = True |
| TLS 协议 | Tomcat | <Connector SSLEnabled="true" sslEnabledProtocols="TLSv1.2,TLSv1.3" ...> | 默认支持 TLSv1.0 / TLSv1.1 |
| TLS 协议 | nginx | ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers 仅 AEAD | ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; |
| Session Cookie | Django | SESSION_COOKIE_SECURE = True + HTTPONLY = True + SAMESITE = 'Strict' | 全 False / 未设 |
| Session Cookie | Express | session({ cookie: { secure: true, httpOnly: true, sameSite: 'strict' } }) | 默认或 secret: 'keyboard cat' |
| Cookie Key | Laravel | php artisan key:generate 生成强随机 APP_KEY | .env 模板默认空值 |
| Jackson 反序列化 | Spring + Jackson | objectMapper.deactivateDefaultTyping() + 类型白名单 | objectMapper.enableDefaultTyping() / activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ...) |
| XML 解析 | Java | factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) + setXIncludeAware(false) | 默认(DOCTYPE 启用) |
| XML 解析 | Python | defusedxml.ElementTree | xml.etree.ElementTree 默认 |
| WebSocket Origin | Spring | setAllowedOrigins("https://app.example.com") | setAllowedOrigins("*") |
| WebSocket Origin | Node ws | verifyClient: (info) => allowlist.includes(info.origin) | 不校验 |
| 默认凭据 | 各类后台 | 强制首次启动改密 + 强度策略 | admin/admin / root/root / 文档示例值未替换 |
| 限流 | nginx | limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; + limit_req zone=one burst=20; | 未配 |
| 上传大小 | Spring Boot | spring.servlet.multipart.max-file-size: 10MB | unlimited / 未设 |
| 上传大小 | nginx | client_max_body_size 10m; | 默认 1m 但被业务覆盖为大值 |
| H2 Console | Spring Boot | spring.h2.console.enabled: false | true(生产暴露) |
| DevTools | Spring Boot | 生产构建排除 spring-boot-devtools | 生产依赖里仍含 |
加载本 skill 时按这些问题思考(按 sink 语义、不按业务命名):
application-prod.yml)?@PostConstruct 改 bean / 启动时根据 feature flag 切配置)?application.yml 关了 debug 但 bootstrap.yml 又开了)?project-framework-analysis 输出的项目结构 / 依赖图谱application*.yml / *.properties / web.xml / nginx.conf / Dockerfile / k8s/*.yaml / .env* / config/*.json对 §4 表里每个配置维度,在每个配置文件里查 grep 命中:
# 调试模式
rg -i "debug.*[:=]\s*true|server\.error\.include-stacktrace" --type yaml --type properties
rg "^DEBUG\s*=" --glob 'settings*.py'
# CORS
rg -i "allow_all_origins|setAllowedOriginPattern.*\*|cors\(\)\s*$|origin.*\*"
# TLS 协议
rg -i "ssl_protocols|sslEnabledProtocols|TLSv1\.0|TLSv1\.1|SSLv3"
# Actuator
rg "management\.endpoints\.web\.exposure\.include" --type yaml
# H2 / DevTools
rg "h2\.console\.enabled|spring-boot-devtools"
# Jackson default typing
rg "enableDefaultTyping|activateDefaultTyping"
# XML 解析器
rg "DocumentBuilderFactory|SAXParserFactory"
# WebSocket origin
rg "setAllowedOrigins"
# 默认凭据
rg -i "admin.*admin|root.*root|password.*password" --type yaml --type properties --type env
application-{profile}.yml > application.yml > 注解默认值nginx.conf / apache.conf / Caddyfile 的 TLS / CORS / 限流 / header 段server.xml 的 <Connector> SSL 配置Dockerfile 的 ENV 指令——是否在镜像层固化了不安全默认值docker-compose*.yml 的 environment:——是否覆盖了应用配置k8s/*.yaml 的 ConfigMap / Secret —— 运行时真实注入值SPRING_PROFILES_ACTIVE=prod 注入工具加速(可选):若已有 sast-scan 的配置类规则命中(high_confidence 桶含 debug=true / 默认凭据 / Jackson default typing 等)可消费其候选加速;缺位 / 空命中不阻塞——直接 grep / read 上述配置介质(Step 1–4)自盘点。本能力对每条命中做"profile + 优先级 + 消费代码"的复核。
以下是已知的检查角度,作为基线起点而非必检硬清单。结合目标代码动态调整,按三态标注(
[x]/[-]/[+])处置。
[-] 说明static-unknown 而非默认 not_vulnerable闭环判定 / 取证完整性 / 破坏性动作以 common/closure-verification.md 为准,下面只列本能力特有的判定上限与产物契约。
为什么这里是「必须」:本节属交付契约——产物结构关系到下游
result-with-file/ coverage-ledger 机器消费;产物聚合或省略会让整条链路失效,因此是刚性要求。
本能力作为白盒原子能力,判定上限为 static-confirmed(配置项值静态危险 + profile 确认是生产配置 + 无运行时 override 旁路),不等于动态 confirmed。
| 状态 | 判据 | 升级路径 |
|---|---|---|
static-confirmed | 配置值静态危险 + 已确认是 prod profile + 无运行时 override | 黑盒构造请求触发对应攻击面 → confirmed |
static-unknown | 运行时环境变量注入 / Vault 引用 / Feature Flag 切换 | 推黑盒 / 联调环境实测 |
suspected | 配置值危险但 profile / 优先级未完全厘清 | 厘清优先级链或黑盒验证 |
not_vulnerable | 配置值在最小权限基线内 + 多源配置一致 | — |
升级到 confirmed 的样例(白盒不能独立给):
=* 静态危险 → 黑盒 GET /actuator/env 拿到响应(含敏感字段) → confirmed* 静态危险 → 黑盒构造跨源请求拿到带认证态的响应 → confirmedopenssl s_client 协商成功 TLSv1.0 → confirmed禁止白盒独立判 confirmed——无可观测效果证据,仅配置危险值不构成动态利用。
为什么这里是「必须」:产物结构是下游机器消费的接口,聚合 / 省略 / 区间会让 result-with-file 计数闸门失效,并让上游无法回溯到具体配置项位置。
每条配置 finding 立即 append 一行到 shared/coverage-ledger/findings/dangerous-config.jsonl,按 (file, config_key, current_value, baseline_value, profile) 五元组独立成行——任一不同即各自独立成行,禁止合并折叠。
{
"id": "cfg-001",
"title": "Spring Actuator 端点全开",
"severity": "high",
"cwe": "CWE-732",
"file_location": "src/main/resources/application-prod.yml:42",
"config_key": "management.endpoints.web.exposure.include",
"current_value": "*",
"baseline_value": "health,info",
"profile": "prod",
"status": "needs_review",
"confidence": "static-confirmed",
"source_report": "dangerous-config",
"description": "..."
}
字段约束:
id 带 cfg- 前缀全局唯一status ∈ confirmed | needs_review | not_vulnerable | false_positive | superseded(白盒默认 needs_review)confidence ∈ static-confirmed | static-unknown | suspectedprofile 填实际生效的环境名(prod / staging / dev / default / runtime-env)file_location 填 file:line,不留空、不写区间禁止:
why:白盒"已防护"结论是覆盖完整性产物声明,缺失反向验证会让下游误信"该子系统该维度安全"。
写"未发现危险配置"或"已防护"前,产物必须包含:
static-unknown 单元格的具体原因(运行时注入 / Vault / Feature Flag)清单不完整 → 结论降级为 partial-coverage。
反例 1:dev profile 配置看着危险但 prod 有覆盖
application.yml 的危险默认值不代表 prod 真用该值application.yml 写 server.error.include-stacktrace: always,但 application-prod.yml 覆盖为 neverapplication-{profile}.yml 且 CI / 部署确实激活 prod profileSPRING_PROFILES_ACTIVE=prod 或等效环境变量反例 2:Actuator 全开但有 Security 拦截
management.endpoints.web.exposure.include=* 单看是危险,但配套 Spring Security 拦截SecurityConfig 含 .requestMatchers("/actuator/**").hasRole("ADMIN")/actuator/** 显式拦截规则反例 3:CORS * 但仅作用于公开 API
cors({ origin: '*' }) 单看危险,但应用于无鉴权公开端点/public/* 路由 group 应用 CORS *,主业务路由不暴露credentials: false反例 4:调试日志启用但仅 dev 镜像
Dockerfile.dev 含 ENV LOG_LEVEL=debug 不影响 prodDockerfile 与 Dockerfile.dev 两份,prod 用前者docker build -f Dockerfile(不带 .dev)反例 5:bootstrap.yml 覆盖了 application.yml 的安全配置
bootstrap.yml 加载优先级高于 application.yml,但容易被遗漏application.yml 关了 debug,bootstrap.yml 又开了 management.endpoints.web.exposure.include: '*'bootstrap.yml 含同名 keybootstrap.yml 纳入扫描面 + 按 Spring 优先级链取最终值反例 6:环境变量优先级高于配置文件
MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE=*)k8s/*.yaml 的 ConfigMap 含同语义 key 但值不一致反例 7:Docker ENV DEBUG=true 未被运行时覆盖
Dockerfile 含 ENV DEBUG=true 但 docker-compose / k8s 部署描述未 unsetdocker history 或全文搜部署描述反例 8:多模块项目子模块独立配置文件
application.yml,子模块独立配置易被遗漏application-prod.yml 安全,但 payment-service/src/main/resources/application.yml 仍是默认值find . -name application*.yml 命中数 > 1反例 9:YAML 多文档(--- 分隔)后续文档覆盖前面
--- 分隔的多文档块按顺序合并,后续 key 覆盖前面application.yml 第一段写安全配置,第二段 --- 后写危险覆盖--- 分隔符反例 10:环境变量占位但默认值已不安全
debug: ${DEBUG:true} 看似由环境变量决定,但默认 fallback 是 true${VAR:dangerous_default}VAR=safe_value 而非依赖默认白盒底线:不假装看到看不到的代码 / 配置。
下面这些情形配置审计无法继续追踪,必须标 static-unknown,不允许默认为 not_vulnerable:
运行时环境变量注入
${VAR} 但 VAR 的实际注入值由部署平台决定,源码 / 配置文件不可见static-unknown,记录环境变量名 + 需要黑盒 / 联调环境实测Vault / Secret Manager 引用
vault://path/to/key / HashiCorp Vault / AWS Secrets Manager 引用static-unknown,要求运维侧出运行时实际值Feature Flag 切换配置
多 profile / 多环境配置
服务网格 / API Gateway 覆盖底层配置
多容器编排 ConfigMap 与镜像 ENV 优先级
密钥相关配置
HTTP 响应头配置
X-Frame-Options / Content-Security-Policy / X-XSS-Protection 等底线:本能力写"该子系统配置已防护"前,所有 static-unknown 单元格必须显式列出原因。否则结论降级为 partial-coverage。
values.schema.json / 自研启动 lint 拦截不安全配置application-dev.yml / application-staging.yml / application-prod.yml 独立维护;prod 配置文件单独 review + 单独权限管控management.endpoints.web.exposure.include 与 Security 拦截规则必须配对发布(Security 配置缺失即拦截 CI)* + credentials: true 组合;自研 CORS 中间件按业务域分组配置deactivateDefaultTyping() + 类型白名单;XML 解析显式 setFeature("...disallow-doctype-decl", true)/actuator/* / /h2-console/*)ENV DEBUG=false)