Document importing from a Nuclei template, and what the importer refuses
A CVE record describes a vulnerability, not a request, which is why this channel is written by hand. A Nuclei template contains the request — path, query, headers, body — because that is what it sends, so for thousands of CVEs the shape a virtual patch needs is already written down. What cannot come across is the template's matchers: they read the RESPONSE to decide whether the target was actually vulnerable, and a WAF decides before a response exists. So an imported rule is strictly weaker than the template it came from — it recognises the attempt, not the exploitation. That is why they land as action "log", which the engine now honours: observed, recorded as an event, scoring nothing. Also records what the importer skips rather than guesses: a CVE already patched in compiled code, a request that is entirely template variables, a literal under twelve characters, the site root. And what it corrects: one leading path segment, because a template is written against a laboratory where the application is mounted somewhere — /laravel52/vendor/phpunit/... would have been published unable to match a real attack at /vendor/phpunit/... Documentation only. cve.json is untouched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N5fpE6Gu4W6JoFMXyb7t7r
This commit is contained in:
1 parent
1e0ad6cd7b
commit
d8426a1d6c
1 file changed
+54
@@ -57,6 +57,60 @@ only one it may clear, which is also what makes a rule **withdrawable**: remove
|
||||
it, bump the stamp, and it stops being enforced everywhere within the hour.
|
||||
Publishing an empty `"rulesets": []` withdraws the lot.
|
||||
|
||||
|
||||
## Importing from a Nuclei template
|
||||
|
||||
A CVE record describes a vulnerability, not a request, which is why this
|
||||
channel is written by hand. A **Nuclei template** does contain the request —
|
||||
path, query, headers, body — because that is what it sends. So for thousands of
|
||||
CVEs the shape a virtual patch needs is already written down.
|
||||
|
||||
go run ./tools/nuclei-importer -cves CVE-2025-31161,CVE-2024-4577 \
|
||||
-merge edgeguard-rules/cve.json > /tmp/next.json
|
||||
cp /tmp/next.json edgeguard-rules/cve.json
|
||||
bash tools/publish-cve-feed.sh --check
|
||||
|
||||
**Imported rules land as `action: "log"`, and that is not timidity.** A template
|
||||
decides whether a target was actually vulnerable by reading the RESPONSE —
|
||||
words in the body, the content type, the status. A WAF decides before a
|
||||
response exists, so the imported rule is strictly weaker than the template it
|
||||
came from: the template confirms exploitation, the rule only recognises the
|
||||
attempt. Watch what it would have caught in your own traffic, then change
|
||||
`log` to `block` deliberately, per rule.
|
||||
|
||||
Each imported rule carries an `origin` field saying a human did not write its
|
||||
pattern and what it came from. Do not remove it — it is the difference between
|
||||
a rule somebody reasoned about and one a converter guessed.
|
||||
|
||||
### What it refuses to do
|
||||
|
||||
It skips rather than guesses, and prints why:
|
||||
|
||||
- **A CVE the engine already patches in code.** Both rules would fire and the
|
||||
scores would add. Five are patched today: the two PHP2Shell ones, Log4Shell
|
||||
(two) and Spring4Shell.
|
||||
- **A request with nothing literal in it.** Templates are full of
|
||||
`{{BaseURL}}` and `{{string_1}}`; a pattern that is mostly `.*` matches
|
||||
ordinary traffic.
|
||||
- **A request whose longest literal is under twelve characters**, or is the
|
||||
site root. A rule on `/` matches everything.
|
||||
|
||||
### What it corrects, and why you should check anyway
|
||||
|
||||
It strips one leading path segment when three remain, because a template is
|
||||
written against a laboratory where the application is mounted somewhere: the
|
||||
phpunit template requests `/laravel52/vendor/phpunit/...` and `laravel52` is
|
||||
that lab's directory. Without stripping it the rule is published, enabled, and
|
||||
unable to match a real attack at `/vendor/phpunit/...`.
|
||||
|
||||
It prefers a header value carrying an injection marker (`${jndi:`, `<%`, `$(`,
|
||||
`../`) over a path, and ignores standard headers entirely whatever their value.
|
||||
An earlier version preferred headers over everything and produced the pattern
|
||||
`Content-Type: text/html` for a PHP RCE — a rule that says nothing about the
|
||||
attack and something about every request.
|
||||
|
||||
None of that makes the output right. Read every pattern before publishing.
|
||||
|
||||
## Targets
|
||||
|
||||
The usual ones (`uri`, `query`, `args`, `body`, `headers`, `user_agent`,
|
||||
|
||||
Reference in new issue
Block a user