Share
## https://sploitus.com/exploit?id=F7C265D2-62B7-5097-8819-CD89F5120F45
ajar ๐Ÿšช


  Find the door you left open by default.
  A defensive scanner for fail-open logic, insecure defaults, and web vulnerabilities โ€” that understands your code and explains every fix.



  
  
  
  
  
  
  



  


---

Most secret scanners look for the credential you **put in** (`API_KEY = "sk-123"`).

**ajar looks for the door you left open by default** โ€” code that silently runs
*insecure* when a config is missing, an environment name differs, or an error
gets swallowed. No exploit required: the default *is* the vulnerability.

```python
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
```

Nobody flags these well. That's the gap ajar fills.

## What it scans

Point ajar at a web app or SaaS backend and it flags five families of risk:

| Category | Examples |
|---|---|
| ๐Ÿšช **fail-open** *(flagship)* | auth disabled by a missing env var, `verify=False` defaults, errors that grant access |
| โš™๏ธ **insecure-defaults** | `DEBUG=True`, wildcard CORS, `0.0.0.0` binds, weak hashes, insecure cookies |
| ๐Ÿ’‰ **injection** *(web)* | SQL injection, command injection, XSS, SSRF, path traversal, unsafe deserialization, SSTI, open redirect |
| ๐ŸŒŠ **denial-of-service** | missing timeouts, catastrophic-backtracking regex (ReDoS), decompression bombs, user-controlled regex |
| ๐Ÿ”‘ **secrets** | hardcoded AWS keys, private keys, tokens, credentials in URLs |

Works on **Python, JavaScript, TypeScript, and TSX (React/Next.js)**. Every rule
is defensive โ€” it explains the attack and the safe fix, and never produces an exploit.

### It actually understands your code

With the optional parser engine (`pip install ajar[full]`), ajar uses
[tree-sitter](https://tree-sitter.github.io/) โ€” the same parser GitHub uses โ€” to
understand the real structure of your code. That means:

- A keyword mentioned in a **comment or a string never triggers a false alarm** โ€”
  in Python *and* in your TypeScript/Next.js files.
- Secrets are still caught **inside** strings (that's where they hide), while
  code checks are only applied to real code.

No parsers installed? ajar falls back to fast pattern scanning and still works โ€”
so it's "pro by default" without ever being fragile.

## ๐Ÿค– Use it with Claude (or any AI assistant)

ajar is built to **pair with an AI coding assistant** so you don't just *find*
vulnerabilities โ€” you *fix* them. A scanner tells you what's wrong; your AI
applies the fix; ajar confirms it's closed. Together they close the loop.

ajar ships as a **Claude Code skill** (in [`skills/ajar/`](skills/ajar/SKILL.md)).
Install it and just say:

> **"Use the ajar skill on my project."**

Claude will then:

1. **Scan** your code with ajar (`ajar scan . --format json`).
2. **Explain** every finding โ€” what it is, how it's attacked, how to fix it.
3. **Fix** each issue with you, worst-first, making minimal correct changes.
4. **Re-scan** until the project is clean.

Every finding already carries a machine-readable `why` and `fix` (see
`--format json`), so any assistant can act on the results โ€” no special mode
needed. It stays defensive throughout: it fixes and protects, never attacks.

> A clean scan is a strong result, not a guarantee โ€” ajar catches common,
> detectable issues, not business-logic or design flaws. Keep a human in the loop
> for anything security-critical.

## Why ajar is different

- ๐ŸŽฏ **Fail-open first.** The flagship category is *fail-open logic*, not just secrets โ€” the misconfigurations behind real breaches (open buckets, auth-less admin panels, debug in prod).
- ๐ŸŽ“ **It teaches.** Every finding explains **how an attacker exploits it** and **exactly how to fix it**, with references. You learn while you scan.
- ๐Ÿง  **Understands code, not just text.** An optional tree-sitter engine parses Python/JS/TS/TSX so comments and strings never cause false positives โ€” the difference between a serious tool and a noisy one.
- ๐Ÿ”’ **Trust by design.** 100% local. **Zero telemetry.** Your code never leaves your machine. Rules are plain, readable YAML you can audit in `ajar/rules/`.
- โšก **Light and robust.** Tiny core (one dependency); the parser engine is an optional extra, and ajar degrades gracefully to pattern scanning without it. Terminal, JSON, and SARIF output for CI.

### How it compares

ajar isn't trying to replace the big scanners โ€” it fills a gap next to them.

| | ajar | secret scanners | big SAST platforms |
|---|:---:|:---:|:---:|
| Fail-open / insecure-default logic | โœ… focus | โš ๏ธ partial | โš ๏ธ partial |
| Comment/string-aware (few false positives) | โœ… tree-sitter | โš ๏ธ | โœ… |
| Explains attack **and** fix per finding | โœ… | โŒ | โš ๏ธ |
| Runs 100% locally, zero telemetry | โœ… | โš ๏ธ | โŒ (often cloud) |
| Transparent rules you can read/edit | โœ… YAML | โš ๏ธ | โš ๏ธ |
| Setup time | seconds | seconds | hours |

## Install

```bash
pip install "ajar[full]"   # recommended: includes the tree-sitter engine
pip install ajar           # lightweight: pattern scanning only
# or, from source:
git clone https://github.com/ignaciovalderrama999-dotcom/ajar && cd ajar && pip install ".[full]"
```

## Usage

```bash
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)
```

The full catalog of all rules, with the attack and the fix for each, lives in
**[RULES.md](RULES.md)** (generated by `ajar rules --format md`).

### Example

```console
$ 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
```

## Configure it once

Drop a `.ajar.yml` in your project root and stop repeating flags (CLI flags
still override it). See [`.ajar.yml.example`](.ajar.yml.example):

```yaml
min_severity: low
fail_on: high
exclude:
  - tests
  - "*.min.js"
disable:
  - DEFAULT_BIND_ALL_INTERFACES
```

## Adopt it gradually with a baseline

Got an existing codebase with findings you can't fix today? Record them once and
let ajar flag only what's **new** from then on:

```bash
ajar scan . --write-baseline   # accept today's findings (.ajar-baseline.json)
ajar scan . --baseline         # from now on, only NEW issues fail the build
```

## Use it in CI

ajar returns a non-zero exit code when it finds an issue at or above
`--fail-on` (default: `medium`), so it drops straight into any pipeline. Add a
step to your GitHub Actions workflow:

```yaml
- run: pip install "ajar[full]"
- run: ajar scan . --fail-on high
```

### pre-commit

ajar ships a [pre-commit](https://pre-commit.com) hook โ€” add it to
`.pre-commit-config.yaml`:

```yaml
repos:
  - repo: https://github.com/ignaciovalderrama999-dotcom/ajar
    rev: v0.1.0
    hooks:
      - id: ajar
```

### Docker

No local install needed:

```bash
docker run --rm -v "$PWD:/src" ghcr.io/ignaciovalderrama999-dotcom/ajar scan /src
```

## Suppressing a finding

When something is a deliberate, reviewed exception, silence it inline:

```python
DEBUG = True  # ajar:ignore                    # silence every rule on this line
DEBUG = True  # ajar:ignore DEFAULT_DEBUG_ON    # silence one specific rule
```

## Writing your own rules

Rules are transparent YAML โ€” no hidden logic. Drop a file in `ajar/rules/` (or
point `--rules` at your own directory):

```yaml
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` controls where a match counts once the tree-sitter engine knows code
from comments and strings: `code` ignores comments **and** strings (most rules),
`string` allows matches inside string literals (e.g. a dangerous regex),
`any` never suppresses (secrets โ€” a leaked key counts anywhere).

## Ethics: analyze and protect, never attack ๐Ÿ›ก๏ธ

ajar is a **defensive** tool, on purpose. It **points at risk and explains the
fix** โ€” it never generates exploits, payloads, or offensive tooling, and it
never connects to or probes any remote system. Its whole job is to help you
close doors before someone else finds them open. That principle is not up for
negotiation, and it guides every rule we add.

## Legal & responsible use โš–๏ธ

- **Use it only on code you own or are authorized to review.** See the full
  [Acceptable Use Policy](ACCEPTABLE_USE.md).
- **It is an aid, not a guarantee.** A clean scan does not mean your app is
  secure. See the [Disclaimer & Limitation of Liability](DISCLAIMER.md).
- **Provided "AS IS", no warranty, no liability** โ€” standard [Apache 2.0](LICENSE)
  terms. You are responsible for how you use it.
- **Found a bug in ajar itself?** See [SECURITY.md](SECURITY.md).
- **Forks & modified copies are the modifier's responsibility, not the
  author's.** Only the official repository is endorsed; the name "ajar" may not
  be used to promote modified versions. Details in the [DISCLAIMER](DISCLAIMER.md).

By using ajar you accept the [DISCLAIMER](DISCLAIMER.md) and
[Acceptable Use Policy](ACCEPTABLE_USE.md). If you do not agree, do not use it.

## FAQ

**Isn't this just another secret scanner?**
No. Secret scanners find the credential you *committed*. ajar's flagship category
is *fail-open logic* โ€” code that runs insecure when a config is missing or wrong.
That's a different, largely uncovered class of bug.

**Will it catch every vulnerability?**
No tool does, and ajar is honest about it: it's a fast, heuristic first line of
defense, not a replacement for a real audit. See the [DISCLAIMER](DISCLAIMER.md).

**Does my code leave my machine?**
Never. ajar runs 100% locally, reads files only, and sends nothing anywhere.
No telemetry, no account, no network calls.

**How do I silence a false positive?**
Inline `# ajar:ignore`, a `disable:` list in `.ajar.yml`, or a `--baseline`.

**Can I use it to attack a site?**
No. ajar analyzes local source and never touches remote systems or generates
exploits. It is defensive by design โ€” see [ACCEPTABLE_USE.md](ACCEPTABLE_USE.md).

## Roadmap

- [x] `--baseline` to accept existing findings and only flag new ones
- [x] pre-commit hook and Docker image
- [x] Denial-of-service rule category
- [x] Structural (tree-sitter) engine so comments/strings never false-positive
- [ ] Deeper structural rules (track a value across lines, e.g. template-literal SQLi through a variable)
- [ ] More languages (Go, Java, PHP, Ruby โ€” tree-sitter already supports 100+)
- [ ] Publish to PyPI

## Contributing

New rules are the best contribution โ€” especially fail-open patterns you've seen
in the wild. Keep every rule **defensive, explainable, and referenced**. PRs and
issues welcome.

## License

Apache License 2.0 ยฉ 2026 Ignacio Valderrama. See [LICENSE](LICENSE) and [NOTICE](NOTICE).