Share
## https://sploitus.com/exploit?id=060C8156-3FA0-592B-949E-4E38AD48E266
# cve-2026-42945-scan

Static scanner for NGINX configuration files that detects the rewrite/set
pattern associated with CVE-2026-42945.

The scanner parses NGINX configs with
[crossplane](https://github.com/nginxinc/crossplane), walks `location` blocks,
and prints every location that looks affected in this format:

```text
//xxx.conf: -> location XXXXX
```

Example:

```text
/path/to/nginx.conf:39 -> location ~ ^/api/(.*)$
```

Reference: [CVE-2026-42945-POC](https://github.com/p3Nt3st3r-sTAr/CVE-2026-42945-POC).

## What It Detects

The risky configuration pattern is a `location` that contains:

- a `rewrite` directive whose replacement contains an unescaped `?`
- no terminal rewrite flag such as `last`, `break`, `redirect`, or `permanent`
- a later `set` directive that copies a regex capture such as `$1`, `${1}`,
  `$name`, or `${name}`

Example vulnerable pattern:

```nginx
location ~ ^/api/(.*)$ {
    rewrite ^/api/(.*)$ /internal?migrated=true;
    set $original_endpoint $1;
}
```

The scanner reports the `location` line, not the `rewrite` or `set` line,
because the location is the actionable block to inspect and fix.

## Requirements

- Python 3.10 or newer
- [uv](https://docs.astral.sh/uv/)

Dependencies are managed with `uv` in `pyproject.toml` and locked in `uv.lock`.
The only runtime dependency is `crossplane`.

## Setup

From the repository root:

```bash
uv sync
```

You can also skip a separate setup step and let `uv run` create the environment
on first use.

## Usage

Scan one config file:

```bash
uv run ./scan.py /etc/nginx/nginx.conf
```

Scan a directory recursively:

```bash
uv run ./scan.py -r /etc/nginx
```

Scan recursively from the current directory for `*.conf` files:

```bash
uv run ./scan.py -r './*.conf'
```

Quote globs when you want the scanner to expand them recursively. If your shell
expands `./*.conf` first, the scanner receives only the files matched by the
shell.

Scan only the provided files and do not follow `include` directives:

```bash
uv run ./scan.py --single ./site.conf
```

Show parser warnings, including missing include files:

```bash
uv run ./scan.py -v -r /etc/nginx
```

## Test Fixtures

The `tests/fixtures/` directory contains small NGINX configs that can be used
as examples:

| Fixture | Expected result |
| --- | --- |
| `tests/fixtures/vulnerable.conf` | reports a positional capture finding |
| `tests/fixtures/named_capture.conf` | reports a named capture finding |
| `tests/fixtures/missing_include_still_scans.conf` | reports a finding even though an include is missing |
| `tests/fixtures/safe_break_flag.conf` | no finding because the rewrite uses `break` |
| `tests/fixtures/safe_no_capture.conf` | no finding because no capture is available |

Run the scanner against all example fixtures:

```bash
uv run ./scan.py -r tests/fixtures
```

Expected findings:

```text
/absolute/path/to/tests/fixtures/missing_include_still_scans.conf:6 -> location ~ ^/partial/(.*)$
/absolute/path/to/tests/fixtures/named_capture.conf:2 -> location /users
/absolute/path/to/tests/fixtures/vulnerable.conf:2 -> location ~ ^/api/(.*)$
```

## Output

If affected locations are found, each finding is printed on its own line:

```text
/absolute/path/to/file.conf:30 -> location ~ ^/aaaa/dddd/(.*)$
/absolute/path/to/nginx.conf:39 -> location ~ ^/api/(.*)$
```

No output means no affected location was found in the parsed configuration.

## Exit Codes

- `0`: scan completed and no affected locations were found
- `1`: one or more affected locations were found
- `2`: no target files could be parsed

Exit code `1` is intentional so the scanner can be used in CI or shell scripts:

```bash
if uv run ./scan.py -r ./nginx-configs; then
    echo "No affected locations found"
else
    status=$?
    if [ "$status" -eq 1 ]; then
        echo "Affected locations found"
    else
        echo "Scanner failed"
    fi
fi
```

## Include Handling

By default, crossplane follows `include` directives. If an included file is
missing, crossplane marks the config as failed but may still return the parsed
statements from the original file. This scanner still checks those parsed
statements so local vulnerable locations are not missed.

Use `-v` to see missing include warnings. Use `--single` when you want to scan
only the specified files and ignore includes.

## Limitations

This is a static configuration scanner. It does not:

- verify the running NGINX version
- prove exploitability
- execute or test requests against a server
- fully evaluate dynamic variables or generated configs
- detect vulnerable snippets that are hidden in missing include files

Treat findings as locations that need review and remediation. A host is only
actually affected when both the vulnerable NGINX version range and the risky
configuration pattern are present.

## Development

Run the test suite:

```bash
uv run python -m unittest discover -s tests -v
```

Run the syntax check:

```bash
uv run python -m py_compile scan.py
```

Run against the bundled POC config:

```bash
uv run ./scan.py CVE-2026-42945-POC/env/nginx.conf
```

Expected output:

```text
/absolute/path/to/CVE-2026-42945-POC/env/nginx.conf:39 -> location ~ ^/api/(.*)$
```