ignaciovalderrama999-dotcom/ajar

GitHub: ignaciovalderrama999-dotcom/ajar

一款防御性源码扫描工具,专注于检测 fail-open 逻辑、不安全默认配置及常见 Web 漏洞,并能解释每一处风险的修复方案。

Stars: 0 | Forks: 0

ajar — find the door you left open by default

一款防御性扫描工具,专为检测 fail-open 逻辑不安全默认配置Web 漏洞而生 —— 它能理解你的代码,并解释每一处修复。

CI license python rules languages local only stance

ajar scanning a project and explaining each finding

大多数密钥扫描器都在寻找你**主动放入**(`API_KEY = "sk-123"`)的凭证。 **ajar 专找你默认敞开的那扇门** —— 即在缺少配置、环境名称不匹配或错误被 吞没时,会悄无声息地以*不安全*方式运行的代码。无需利用漏洞:默认配置*本身*就是漏洞。 ``` if os.getenv("APP_ENV") != "production": require_auth = False # 🚪 unset/typo'd env → auth is OFF in prod requests.get(url, verify=False) # 🚪 every request open to a man-in-the-middle try: return check_permission(user) except Exception: return True # 🚪 an error becomes a free pass ``` 没人能很好地标记出这些问题。这正是 ajar 填补的空白。 ## 它能扫描什么 将 ajar 指向 Web 应用或 SaaS 后端,它会标记出五大类风险: | 类别 | 示例 | |---|---| | 🚪 **fail-open** *(旗舰功能)* | 因缺少环境变量而禁用身份验证、`verify=False` 默认值、因错误而授予访问权限 | | ⚙️ **不安全默认配置** | `DEBUG=True`、CORS 通配符、`0.0.0.0` 绑定、弱哈希、不安全的 cookie | | 💉 **注入** *(Web)* | SQL injection、命令注入、XSS、SSRF、路径遍历、不安全的反序列化、SSTI、开放重定向 | | 🌊 **拒绝服务** | 缺少超时、灾难性回溯正则表达式 (ReDoS)、解压炸弹、用户控制的正则表达式 | | 🔑 **密钥** | 硬编码的 AWS 密钥、私钥、token、URL 中的凭证 | 支持 **Python、JavaScript、TypeScript 和 TSX (React/Next.js)**。每条规则 都是防御性的 —— 它会解释攻击方式与安全修复方案,且绝不生成攻击代码。 ### 它真正理解你的代码 借助可选的解析器引擎(`pip install ajar[full]`),ajar 使用 [tree-sitter](https://tree-sitter.github.io/) —— 也就是 GitHub 使用的同款解析器 —— 来 理解代码的真实结构。这意味着: - 在**注释或字符串中**提及的关键字**绝不会触发误报** —— 无论是在 Python 还是在你的 TypeScript/Next.js 文件中。 - 密钥依然能在字符串**内部**被捕获(那是它们藏身之处),同时 代码检查只会应用于真实的代码。 没有安装解析器?ajar 会回退到快速模式扫描并继续工作 —— 因此它默认就是“专业的”,且绝不脆弱。 ## 🤖 与你的 AI 助手(或任何 AI 助手)一起使用 ajar 专为**与 AI 编程助手配合**而设计,让你不仅能*发现*漏洞 —— 还能*修复*它们。扫描器告诉你哪里有问题;你的 AI 应用修复;ajar 确认漏洞已闭环。它们共同构成了闭环。 ajar 以 **AI 助手技能**(在 [`skills/ajar/`](skills/ajar/SKILL.md) 中)的形式发布。 安装它,然后只需说: 你的 AI 助手随后将: 1. 使用 ajar **扫描**你的代码(`ajar scan . --format json`)。 2. **解释**每一项发现 —— 它是什么、如何被攻击、如何修复。 3. 与你一起**修复**每个问题,优先处理最严重的,进行最小限度的正确修改。 4. **重新扫描**直到项目干净为止。 每一项发现都已包含机器可读的 `why` 和 `fix`(参见 `--format json`),因此任何助手都能根据结果采取行动 —— 无需特殊模式。 它始终保持防御性:它负责修复和保护,从不攻击。 ## 为什么 ajar 与众不同 - 🎯 **fail-open 优先。** 旗舰类别是 *fail-open 逻辑*,而不仅仅是密钥 —— 这些是真实数据泄露背后的错误配置(开放的 bucket、无身份验证的管理面板、生产环境中的 debug)。 - 🎓 **它能教学。** 每一项发现都解释了**攻击者如何利用它**以及**确切的修复方法**,并附带参考资料。你在扫描的同时也在学习。 - 🧠 **理解代码,而不仅仅是文本。** 可选的 tree-sitter 引擎解析 Python/JS/TS/TSX,因此注释和字符串绝不会导致误报 —— 这是严肃工具与嘈杂工具之间的区别。 - 🔒 **设计上值得信赖。** 100% 本地运行。**零遥测。** 你的代码永远不会离开你的机器。规则是简单、可读的 YAML,你可以在 `ajar/rules/` 中审计。 - ⚡ **轻量且健壮。** 极小的核心(单一依赖);解析器引擎是可选的附加组件,没有它 ajar 也能优雅地降级为模式扫描。支持用于 CI 的终端、JSON 和 SARIF 输出。 ### 横向对比 ajar 并不打算取代大型扫描器 —— 它填补了它们旁边的空白。 | | ajar | 密钥扫描器 | 大型 SAST 平台 | |---|:---:|:---:|:---:| | Fail-open / 不安全默认逻辑 | ✅ 专注 | ⚠️ 部分 | ⚠️ 部分 | | 感知注释/字符串(误报极少) | ✅ tree-sitter | ⚠️ | ✅ | | 每个发现都解释攻击**和**修复 | ✅ | ❌ | ⚠️ | | 100% 本地运行,零遥测 | ✅ | ⚠️ | ❌ (通常是云端) | | 可读取/编辑的透明规则 | ✅ YAML | ⚠️ | ⚠️ | | 设置时间 | 秒级 | 秒级 | 数小时 | ## 安装 ``` pip install "ajar[full]" # recommended: includes the tree-sitter engine pip install ajar # lightweight: pattern scanning only # 或者,从 source: git clone https://github.com/ignaciovalderrama999-dotcom/ajar && cd ajar && pip install ".[full]" ``` ## 用法 ``` ajar scan . # scan the current project ajar scan path/to/file.py # scan one file ajar scan examples/vulnerable_webapp.py # demo: SQLi, XSS, SSRF, RCE, path traversal ajar scan . --min-severity high # only show high+ findings ajar scan . --exclude tests --exclude '*.min.js' # skip paths (repeatable) ajar scan . --format json # machine-readable output ajar scan . --format sarif # GitHub code scanning ajar scan . --write-baseline # record current findings as accepted ajar scan . --baseline # then only show NEW findings ajar rules # list every rule ajar checks ajar rules --format md # the full rule catalog (see RULES.md) ``` 包含每条规则的攻击方式和修复方法的完整规则目录,位于 **[RULES.md](RULES.md)** (由 `ajar rules --format md` 生成)。 ### 示例 ``` $ ajar scan examples/vulnerable_config.py CRITICAL examples/vulnerable_config.py:16:5 Auth disabled outside production [FAILOPEN_AUTH_ENV_BYPASS] Authentication is switched off based on an environment name. code: require_auth = False why: If the env var that flips this is missing or misspelled in production, the app boots wide open with no authentication. The default IS the bug. fix: Fail closed — default auth to ON and require an explicit, logged opt-out. ref: https://owasp.org/Top10/A05_2021-Security_Misconfiguration/ Found 9 open doors: 2 critical · 6 high · 1 medium ``` ## 一次性配置它 在你的项目根目录下放置一个 `.ajar.yml`,就不必再重复填写标志(CLI 标志 依然会覆盖它)。请参阅 [`.ajar.yml.example`](.ajar.yml.example): ``` min_severity: low fail_on: high exclude: - tests - "*.min.js" disable: - DEFAULT_BIND_ALL_INTERFACES ``` ## 使用基线逐步采用它 现有的代码库中存在你今天无法修复的发现?把它们记录一次,然后 让 ajar 从那时起只标记**新增**的内容: ``` ajar scan . --write-baseline # accept today's findings (.ajar-baseline.json) ajar scan . --baseline # from now on, only NEW issues fail the build ``` ## 在 CI 中使用 当 ajar 发现处于或高于 `--fail-on` (默认:`medium`)级别的问题时,它会返回非零退出码,因此可以直接接入任何 pipeline。在你的 GitHub Actions 工作流中添加一个步骤: ``` - run: pip install "ajar[full]" - run: ajar scan . --fail-on high ``` ### pre-commit ajar 提供了一个 [pre-commit](https://pre-commit.com) 钩子 —— 将其添加到 `.pre-commit-config.yaml`: ``` repos: - repo: https://github.com/ignaciovalderrama999-dotcom/ajar rev: v0.1.0 hooks: - id: ajar ``` ### Docker 无需本地安装: ``` docker run --rm -v "$PWD:/src" ghcr.io/ignaciovalderrama999-dotcom/ajar scan /src ``` ## 抑制某项发现 当某些问题被刻意保留为已审查的例外情况时,可以在行内将其静默: ``` DEBUG = True # ajar:ignore # silence every rule on this line DEBUG = True # ajar:ignore DEFAULT_DEBUG_ON # silence one specific rule ``` ## 编写自己的规则 规则是透明的 YAML —— 没有隐藏逻辑。在 `ajar/rules/` 中放入一个文件(或者 用 `--rules` 指向你自己的目录): ``` rules: - id: MY_RULE name: Short human name severity: high # info | low | medium | high | critical category: fail-open message: One-line description of the issue. pattern: '(?i)dangerous_setting\s*=\s*True' # a Python regex why: How an attacker abuses this. fix: How to close the door. references: - https://owasp.org/... extensions: [".py"] # optional: only these file types context: code # optional: code (default) | string | any ``` `context` 控制了一旦 tree-sitter 引擎识别出代码与注释和字符串的区别后,匹配在何处生效:`code` 会忽略注释**和**字符串(大多数规则),`string` 允许在字符串字面量内部进行匹配(例如危险的正则表达式),`any` 永不抑制(针对密钥 —— 泄露的密钥在任何地方都算数)。 ## 道德准则:分析与保护,从不攻击 🛡️ ajar 是一款**防御性**工具,这是其核心宗旨。它**指出风险并解释 修复方案** —— 它从不生成利用代码、payload 或攻击性工具,并且 从不连接或探测任何远程系统。它的全部职责就是帮你 在别人发现门没关之前将其关上。这一原则不容妥协,并且指引着我们添加的每一条规则。 ## 法律与负责任的使用 ⚖️ - **仅在你拥有或被授权审查的代码上使用它。** 请参阅完整的 [可接受使用政策](ACCEPTABLE_USE.md)。 - **它是辅助工具,而非绝对保证。** 干净的扫描结果并不意味着你的应用是 安全的。请参阅[免责声明与责任限制](DISCLAIMER.md)。 - **按“原样”提供,无任何保证或责任** —— 遵循标准的 [Apache 2.0](LICENSE) 条款。你需要对如何使用它负责。 - **在 ajar 本身发现了 Bug?** 请参阅 [SECURITY.md](SECURITY.md)。 - **Fork 和修改后的副本由修改者负责,与 原作者无关。** 仅官方仓库获得认可;不得使用 "ajar" 名称来 推广修改后的版本。详见[免责声明 (DISCLAIMER)](DISCLAIMER.md)。 使用 ajar 即表示你接受[免责声明 (DISCLAIMER)](DISCLAIMER.md) 和 [可接受使用政策](ACCEPTABLE_USE.md)。如果你不同意,请不要使用。 ## 常见问题解答 **这只是又一个密钥扫描器吗?** 不。密钥扫描器寻找的是你*提交*的凭证。ajar 的旗舰类别 是 *fail-open 逻辑* —— 即在缺少配置或配置错误时以不安全方式运行的代码。 这是一类不同且在很大程度上未被覆盖的 Bug。 **它会捕获每一个漏洞吗?** 没有任何工具能做到,ajar 对此很坦诚:它是快速的、启发式的第一道 防线,而不是取代真正的审计。请参阅[免责声明 (DISCLAIMER)](DISCLAIMER.md)。 **我的代码会离开我的机器吗?** 绝不会。ajar 100% 本地运行,仅读取文件,并且不向任何地方发送任何内容。 没有遥测,没有账号,没有网络调用。 **如何抑制误报?** 使用行内的 `# ajar:ignore`、`.ajar.yml` 中的 `disable:` 列表,或者使用 `--baseline`。 **我可以用它攻击网站吗?** 不能。ajar 仅分析本地源代码,从不触碰远程系统,也绝不生成 攻击代码。它在设计上就是防御性的 —— 参见 [ACCEPTABLE_USE.md](ACCEPTABLE_USE.md)。 ## 路线图 - [x] `--baseline`,用于接受现有的发现并仅标记新发现 - [x] pre-commit 钩子与 Docker 镜像 - [x] 拒绝服务规则类别 - [x] 结构化 (tree-sitter) 引擎,确保注释/字符串绝不会导致误报 - [ ] 更深层的结构化规则(跨行追踪某个值,例如通过变量传递的模板字面量 SQLi) - [ ] 更多语言(Go、Java、PHP、Ruby —— tree-sitter 已支持 100 多种) - [ ] 发布到 PyPI ## 贡献 新规则是最好的贡献 —— 尤其是你在实战中 见过的 fail-open 模式。请保持每条规则是**防御性的、可解释的且带有参考资料的**。欢迎提交 PR 和 issue。 ## 许可证 Apache License 2.0 © 2026 Ignacio Valderrama。请参阅 [LICENSE](LICENSE) 和 [NOTICE](NOTICE)。
标签:CMS安全, JavaScript, LNA, Python, 代码安全, 无后门, 漏洞枚举, 请求拦截, 逆向工具, 静态代码扫描