Sploitus

Exploit for Automated-Data-and-Code-Quality-Controller

githubexploit Β· 2026-08-22

Exploit Code

README199 lines
## https://sploitus.com/exploit?id=4260277F-0218-5B04-B078-5D2272CBD1A8
# codesentry

Static analysis for Python and JavaScript. Finds injection flaws, XSS sinks,
hardcoded credentials and coding-standard violations, and emits results in a
format CI systems can act on.

Standard library only. No install step, no dependencies.

```bash
python3 -m codesentry samples/
```

---

## Usage

```bash
# scan a tree, human-readable output
python3 -m codesentry src/

# HTML report as a build artifact
python3 -m codesentry src/ --format html --output reports/scan.html

# SARIF for GitHub code scanning / IDE annotations
python3 -m codesentry src/ --format sarif --output results.sarif --fail-on high

# security findings only, above medium
python3 -m codesentry src/ --category security --min-severity medium

# one rule, or everything except a family
python3 -m codesentry src/ --rule PY-SEC-001
python3 -m codesentry src/ --exclude-rule PY-STD

# load team rules from outside the package
python3 -m codesentry src/ --rubric-dir ./team-rubrics --plugin-dir ./team-rules

# what is loaded right now
python3 -m codesentry --list-rules
```

### Exit codes

| Code | Meaning |
|------|---------|
| `0`  | No finding at or above `--fail-on` (default `high`) |
| `1`  | Threshold breached β€” fail the build |
| `2`  | Internal error: a rule crashed or a file could not be prepared |
| `130`| Interrupted |

`2` is deliberately distinct from `1`. "The scan found problems" and "the scan
did not fully run" call for different responses, and collapsing them is how a
silently degraded scanner gets mistaken for a clean bill of health.

### Suppressions

```python
subprocess.run(cmd, shell=True)  # codesentry: ignore[PY-SEC-003]

# codesentry: ignore[PY-SEC-009]
digest = hashlib.md5(blob).hexdigest()

value = eval(expr)  # codesentry: ignore
```

A bare `ignore` suppresses everything on that line; the bracketed form
suppresses only the named rules, so an unrelated flaw on the same line is still
reported. `# codesentry: ignore-file` near the top skips the file. Suppressed
findings are counted in the summary rather than vanishing, and
`--no-suppressions` audits what is being hidden.

---

## Layout

```
codesentry/
  models.py        Severity, Finding, RuleMeta, Diagnostic, ScanResult
  context.py       decoding, comment/string masking, AST parsing, line index
  registry.py      rule registration, discovery, rubric loading   <- extension point
  engine.py        file walk, rule dispatch, error isolation, dedup, suppression
  cli.py           argument parsing and wiring
  rules/           auto-imported rule modules
  reporters/       console, structured (JSON + SARIF), html
rubrics/           declarative JSON rules
samples/           vulnerable fixtures, a clean counterpart, edge cases
tests/             66 tests
```

The engine has no knowledge of any rule. There is no occurrence of `SQL`,
`XSS`, `eval` or `snake_case` anywhere in `engine.py`, and adding a rule never
requires editing it. Rules are found through the registry and described by
their own metadata, which is also what drives filtering, report grouping and
severity thresholds.

---

## Adding a rule

Three routes, in increasing order of power.

### 1. A rubric entry β€” no Python

Add an object to any `.json` file in `rubrics/`:

```json
{
  "id": "TEAM-001",
  "name": "requests.get without a timeout",
  "description": "A request with no timeout can hang a worker indefinitely.",
  "languages": ["python"],
  "severity": "medium",
  "category": "reliability",
  "pattern": "requests\\.get\\((?![^)]*timeout)",
  "message": "requests.get() has no timeout",
  "remediation": "Pass timeout=(connect, read), e.g. requests.get(url, timeout=(3, 10))."
}
```

That is the whole change. Rubrics are validated at load time, so a typo is a
named error before the scan starts rather than a mystery during it.

Keys beyond the required five (`id`, `name`, `languages`, `severity`, `pattern`):

| Key | Effect |
|-----|--------|
| `scope` | `code_only` (default), `masked` (strings visible), `raw` (comments visible) |
| `exclude_pattern` | Drop the hit if this also matches the line |
| `require_pattern` | Only apply the rule to files containing this |
| `skip_minified` | Skip bundled assets (default `true`) |
| `flags` | `ignorecase`, `multiline`, `dotall` |
| `max_hits_per_file` | Cap runaway matches (default 25) |
| `message` | Supports `{match}` and `{1}` substitution |

### 2. A decorated function β€” full AST access

Drop a module into `codesentry/rules/`. It is imported automatically.

```python
import ast
from ..models import make_finding
from ..registry import rule

@rule(
    id="PY-SEC-020",
    name="Flask route without authentication",
    description="A view registered under /admin with no auth decorator.",
    languages=["python"],
    severity="high",
    cwe="CWE-306",
    remediation="Add @login_required, or move the route behind an authenticated blueprint.",
)
def unauthenticated_admin_route(ctx, meta):
    if ctx.tree is None:          # file did not parse; text rules still ran
        return
    for node in ast.walk(ctx.tree):
        if isinstance(node, ast.FunctionDef) and _is_admin_route(node):
            yield make_finding(meta, ctx, node.lineno, f"{node.name}() is unauthenticated")
```

Severity, CWE, remediation text and the code snippet are filled in from
metadata by `make_finding`, so the rule body only describes what it found.

### 3. A plugin directory β€” rules outside the repo

```bash
python3 -m codesentry src/ --plugin-dir ./company-rules
```

Same `@rule` decorator, loaded from loose `.py` files.

### What the context gives a rule

```python
ctx.source        # raw text
ctx.masked        # comments blanked, strings intact
ctx.code_only     # comments and string bodies blanked
ctx.tree          # Python AST, or None if the file did not parse
ctx.line_text(n)  # 1-indexed, never raises
ctx.position(off) # (line, column) for any offset in any view
ctx.in_string(off), ctx.in_comment(off)
ctx.is_minified
```

Blanking replaces characters with spaces rather than deleting them, so an
offset in `code_only` still maps to the correct line and column in the file.

---

## Tests

```bash
python3 -m unittest discover -s tests -v
```

66 tests. Rule tests assert true negatives as hard as true positives: a
parameterised query, `yaml.safe_load`, `usedforsecurity=False`, `x != null`,
`os.environ['KEY']` and a static `innerHTML` literal must all produce nothing.
A scanner that cries wolf on correct code trains people to ignore it.