mirror of
https://github.com/yogeshojha/rengine.git
synced 2026-10-21 07:41:28 +02:00
A finding is corroborated when another check fired at the same matched_at, names the same CVE or CWE, and neither is informational or suppressed. The peer carries its basis, the shared identifiers and its scanner, so a second scanner confirming the same weakness is distinguishable from a second nuclei template. Co-location alone no longer counts: four unrelated TLS defects on one endpoint used to vouch for each other. Surface it the way the grammar surfaces everything else: an is:corroborated flag, a Confirmed quick filter, two counted example leads, a Location group dimension, and a tiebreaker in the risk sort after severity and KEV. The row carries a confirmed badge beside new and KEV instead of trailing text on the origin line; the detail sheet states each peer's basis and links to the other findings at that location. Add a btree over (scan_id, matched_at) - the equality lookup was probing the trigram GIN index at 8.2ms a key - and disable JIT on the vulnerability query paths, where the set-returning expansion's 100-rows-a-row estimate bought 267ms of compilation per request. On 60k findings: search 510ms to 240ms, issues 1380ms to 440ms (830ms before the feature existed). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UZKQQx39KeiDo8QE9XXzf3
34 lines
1.1 KiB
Python
34 lines
1.1 KiB
Python
from __future__ import annotations
|
|
|
|
from sqlalchemy.exc import DBAPIError
|
|
|
|
from shared.models.asset_query import QueryError
|
|
|
|
STATEMENT_TIMEOUT = "SET LOCAL statement_timeout = '20s'"
|
|
# a set-returning expansion is estimated at 100 rows a row, and the bogus cost buys 270ms of JIT
|
|
NO_JIT = "SET LOCAL jit = off"
|
|
|
|
QUERY_SQLSTATES = {
|
|
"2201B": (
|
|
"That regular expression is not valid here.",
|
|
"PostgreSQL regular expressions differ slightly from PCRE.",
|
|
),
|
|
"2201G": ("That regular expression is not valid here.", None),
|
|
"57014": (
|
|
"That search took too long to run.",
|
|
"Add a field filter to narrow it down.",
|
|
),
|
|
"22003": ("A number in that query is out of range.", None),
|
|
"22P02": ("A value in that query has the wrong shape.", None),
|
|
"54000": ("That search term is too large to index.", None),
|
|
}
|
|
|
|
|
|
def query_error_for(exc: DBAPIError) -> QueryError | None:
|
|
sqlstate = getattr(exc.orig, "sqlstate", None) or getattr(exc.orig, "pgcode", None)
|
|
known = QUERY_SQLSTATES.get(str(sqlstate))
|
|
if known is None:
|
|
return None
|
|
message, hint = known
|
|
return QueryError(message=message, hint=hint)
|