CyberKareem/kameRules

GitHub: CyberKareem/kameRules

一套自定义的 Semgrep 静态安全扫描规则集,用于检测代码中缺失的函数级授权、跨租户 IDOR 和不安全反序列化等高危漏洞。

Stars: 0 | Forks: 0

# kameRules **我在真实审计中发现的漏洞类别的自定义 [Semgrep](https://semgrep.dev) 规则 —— 包括缺少函数级授权、跨租户 IDOR 以及不安全的反序列化。** 此规则集将我自己的方法论产品化。这里的每条规则都对应我在实际中发现并披露的漏洞类别;如果某条规则对应我披露的 CVE,则该 CVE 会在规则的 `references` 和下表中引用。 由 **Abdullah Kareem** ([@CyberKareem](https://github.com/CyberKareem)) 维护。 ## 为什么选择这三个类别 失效的访问控制和不安全的反序列化在实际影响中位居前列: - **缺少函数级授权** 和 **跨租户 IDOR** 是同一缺陷的两个方面 —— 路由对调用者进行了身份验证,但从不检查他们是否有权对*此特定资源*进行操作,并且数据层直接从请求提供的 id 解析对象,没有任何租户范围。这就是 [OWASP A01:2021 – 失效的访问控制](https://owasp.org/Top10/A01_2021-Broken_Access_Control/),排名第一的类别。 - **不安全的反序列化** ([A08:2021](https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures/)) 将数据解析调用转变为跨 Java、Python、PHP 和 Node 的远程代码执行。 ## 规则 → CWE → CVE 映射 | 规则 | 语言 | CWE | OWASP | 本可拦截的已披露 CVE | 严重性 | |------|-------------|-----|-------|-------------------------------------|----------| | [`express-auth-without-authz`](rules/authz/express-auth-without-authz.yaml) | JavaScript, TypeScript | CWE-862 (缺少授权), CWE-306 | A01:2021 | **CVE-2026-59979** | WARNING | | [`db-findbyid-no-tenant-scope`](rules/idor/db-findbyid-no-tenant-scope.yaml) | JavaScript, TypeScript | CWE-639 (通过用户控制键绕过授权), CWE-284 | A01:2021 | **CVE-2026-59979** | WARNING | | [`java-jackson-default-typing`](rules/deserialization/java-jackson-default-typing.yaml) | Java | CWE-502 (不可信数据反序列化) | A08:2021 | **CVE-2026-59889** | ERROR | | [`java-jackson-polymorphic-annotation`](rules/deserialization/java-jackson-polymorphic-annotation.yaml) | Java | CWE-502 | A08:2021 | **CVE-2026-59889** | WARNING | | [`python-pickle-loads`](rules/deserialization/python-pickle-loads.yaml) | Python | CWE-502 | A08:2021 | — | ERROR | | [`php-unserialize-request`](rules/deserialization/php-unserialize-request.yaml) | PHP | CWE-502 | A08:2021 | — | ERROR | | [`node-serialize-unserialize`](rules/deserialization/node-serialize-unserialize.yaml) | JavaScript, TypeScript | CWE-502 | A08:2021 | — | ERROR | ## 规则详情 ### `authz/express-auth-without-authz` — 缺少函数级授权 标记使用单个且**仅用于身份验证**的中间件注册的 Express 路由,且其后续没有授权/权限中间件: ``` app.delete('/tasks/:id', requireAuth, deleteTask); // flagged: auth, no authz app.put('/tasks/:id', requireAuth, requireOrgPermission, up); // clean: authz middleware present ``` 身份验证证明你*是*谁;它并不能证明你*被允许对该资源进行操作*。该规则将第一个中间件限制为已知的身份验证检查名称(`requireAuth`、`authenticateJWT`、`verifyToken`、`isAuthenticated`、Cognito/Passport 助手等),因此它针对的是特定的“已验证但未授权”模式,而不是所有的双参数路由。它有意设计为**审查级启发式规则** (WARNING):一个真正的只读、仅靠身份验证即可访问的路由是值得分诊的合法命中。 ### `idor/db-findbyid-no-tenant-scope` — 跨租户 IDOR 标记从**请求提供的 id** 解析记录但在查询中没有租户/组织范围的数据库读/写操作: ``` User.findById(req.params.id); // flagged Doc.findOne({ _id: req.params.id }); // flagged Account.findByPk(req.query.accountId); // flagged prisma.invoice.findUnique({ where: { id: req.params.id } }); // flagged Doc.findOne({ _id: req.params.id, organizationId: req.user.orgId }); // clean: tenant-scoped User.findById(req.user.id); // clean: id is the caller's own ``` 涵盖 Mongoose(`findById`、`findByPk`、`findByIdAndUpdate/Delete`、`findOne({_id})`)和 Prisma(`findUnique`/`findFirst`)。`findOne`/Prisma 变体使用 `pattern-not` 来抑制已经带有 `organizationId` / `orgId` / `tenantId` / `teamId` / `accountId` / `workspaceId` 范围的查询,并且 metavariable 正则表达式要求 id 来自 `req|request|ctx . params|query|body`。 ### `deserialization/*` — 不安全的反序列化 (RCE) | Sink | 标记内容 | |------|----------------| | `java-jackson-default-typing` | `ObjectMapper.enableDefaultTyping(...)` / `activateDefaultTyping()` —— 多态默认类型允许传输格式选择反序列化的类 → gadget-chain RCE。 | | `java-jackson-polymorphic-annotation` | `@JsonTypeInfo(use = Id.CLASS)` / `Id.MINIMAL_CLASS` —— 在 payload 中嵌入类名;`Id.NAME` + `@JsonSubTypes` 允许列表是安全的。 | | `python-pickle-loads` | `pickle.loads/load`, `cPickle.*`, `_pickle.*` —— 在重建对象图时会执行任意代码。 | | `php-unserialize-request` | 在超全局变量(`$_GET/$_POST/$_REQUEST/$_COOKIE`)或 `php://input` 上的 `unserialize()` → PHP 对象注入。 | | `node-serialize-unserialize` | `node-serialize` 的 `unserialize()` —— 复活并调用嵌入在 payload 中的函数。 | ## 用法 安装 Semgrep: ``` python -m pip install semgrep # or: brew install semgrep ``` 使用整个包扫描目标代码库: ``` semgrep --config /path/to/kameRules/rules /path/to/your/project ``` 仅运行一个类别: ``` semgrep --config /path/to/kameRules/rules/idor /path/to/your/project ``` 直接从 GitHub 使用(无需 clone): ``` semgrep --config https://raw.githubusercontent.com/CyberKareem/kameRules/main/rules/authz/express-auth-without-authz.yaml . ``` 输出 SARIF 以进行代码扫描: ``` semgrep --config /path/to/kameRules/rules --sarif --output kame.sarif . ``` ## 测试 每条规则都在 [`tests/`](tests/) 下附带了一个编号对应的 fixture,包含一个**易受攻击**的部分(标注为 `// ruleid: `)和一个**安全**的部分(标注为 `// ok: `),视情况涵盖 JavaScript/TypeScript、Java、Python 和 PHP。按照 CI 的方式运行套件: ``` semgrep --validate --config rules/ # rule syntax + metadata semgrep --test --config rules/ tests/ # every ruleid/ok annotation must hold ``` `semgrep --test` 仅在每一行易受攻击的代码都被标记且每一行安全的代码都未被标记时才算通过,因此这些 fixture 也可作为可执行文档,说明每条规则会捕获什么以及不会捕获什么。CI ([`.github/workflows/ci.yml`](.github/workflows/ci.yml)) 会在每次推送和拉取请求时运行这两者。 ## 贡献 / 扩展 将规则添加为 `rules//.yaml`,将 fixture 添加为具有匹配词干的 `tests//.`,然后保持 `semgrep --test` 为通过状态。与宽泛的 AST 匹配相比,优先使用 `pattern-not` 守卫和 `metavariable-regex`/`metavariable-pattern` 约束,以保持高信号。 ## 许可证 [MIT](LICENSE) © 2026 Abdullah Kareem ([@CyberKareem](https://github.com/CyberKareem)).
标签:JS文件枚举, SAST, Semgrep规则, Streamlit, 云安全监控, 反序列化, 数据可视化, 盲注攻击, 自定义脚本, 访问控制, 逆向工具, 静态分析