mirror of
https://github.com/yogeshojha/rengine.git
synced 2026-10-20 07:11:28 +02:00
A full static review of the 3.0 tree, run as two fan-out passes with every
finding verified against the running stack rather than taken on inspection.
Correctness and security
- instance settings encrypted the mask over the stored AI key: `!= MASK` never
matched `••••••••abcd`, so saving settings destroyed the key and `test_ai`
posted the mask as a bearer token
- the MFA token was replayable for its full five-minute life; the gate now
checks revocation and consumes the token after a successful exchange
- logout revoked nothing for a bearer client while answering "Logged out"
- `POST /api-keys/{id}/test` returned the plaintext key inside httpx's error
string, which embeds the whole URL
- an interest rule could be edited or deleted through another project's id
- redis ran the celery broker under `allkeys-lru`, free to evict a queued task
or a chord counter; now `noeviction`
- nuclei's stored command carried the OAST token and every auth header
- a finalize step could poison the session and leave a scan RUNNING for ever
- `is:issue` raised TypeError on every search
- offset paging repeated and skipped rows in four dimensions
- a cancelled run kept a stale `scans.*_found` rollup
- every PDF report raised `KeyError: 'software'`
- `version_key` truncated a wide numeric run and inverted release ordering
- psycopg raises a NUL as a bare ValueError, above StatementError, so every
savepoint guard was blind to the case it was written for
Performance
- endpoints.host had no trigram index: 35.9ms seq scan -> 0.389ms
- free text compiled to one OR, not the prescribed UNION ALL: 132ms -> 41ms
- `/http-assets/summary` and `/ips/summary` materialised whole tables
- the cross-link `ip` kind ran an estate query per page and drew nothing
Frontend
- `$effect` loaders that read the state they write, an unbounded request loop
on a failing endpoint
- error states that rendered as empty states
- 2FA backup codes were unusable while the copy said they worked
- a "Scan history" dialog that always reported none
- ~400 duplicated lines across five filter bars, now one component
Build and tooling
- every scanner installed at @latest; all 13 pinned to the measured versions
- CI built `web/`, gone since 2.x, with tags that cannot be valid
- the prettier pre-commit hook discarded its filenames and always passed
- the test suite destroyed itself when run twice
Also: subdomains from public code, via a pinned github-subdomains source and a
GitHub API key that subfinder receives too; sublist3r and oneforall removed
after measuring one unique host in 89 across four targets.
Verified: 853 tests, ruff clean over eleven packages, svelte-check 0 errors,
the count-is-a-promise gate at 131 checks and 0 mismatches, and 143 GET routes
with no 5xx. Four migrations, each with an exercised downgrade.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DVkdx5ynZ6aof5kLFczmhX
76 lines
2.3 KiB
Python
Executable File
76 lines
2.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Regenerate shared/definitions/data/port_registry.json from the IANA port registry."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import csv
|
|
import io
|
|
import json
|
|
import re
|
|
import sys
|
|
import urllib.request
|
|
from pathlib import Path
|
|
|
|
SOURCE = (
|
|
"https://www.iana.org/assignments/service-names-port-numbers/"
|
|
"service-names-port-numbers.csv"
|
|
)
|
|
TARGET = (
|
|
Path(__file__).resolve().parents[1] / "shared/definitions/data/port_registry.json"
|
|
)
|
|
PROTOCOLS = ("tcp",)
|
|
MAX_DESCRIPTION = 120
|
|
UNASSIGNED = {"", "reserved", "unassigned", "de-registered", "deregistered"}
|
|
MIN_PORTS = 4000
|
|
|
|
_ALNUM = re.compile(r"[^a-z0-9]")
|
|
_HOUSEKEEPING = re.compile(
|
|
r"\s*IANA assigned this well-formed service name as a replacement for.*$", re.I
|
|
)
|
|
|
|
|
|
def _same(a: str, b: str) -> bool:
|
|
return _ALNUM.sub("", a.lower()) == _ALNUM.sub("", b.lower())
|
|
|
|
|
|
def build(raw: str) -> dict[str, list[str]]:
|
|
out: dict[str, list[str]] = {}
|
|
for row in csv.DictReader(io.StringIO(raw)):
|
|
if (row["Transport Protocol"] or "").strip().lower() not in PROTOCOLS:
|
|
continue
|
|
number = (row["Port Number"] or "").strip()
|
|
name = (row["Service Name"] or "").strip().lower()
|
|
description = _HOUSEKEEPING.sub(
|
|
"", " ".join((row["Description"] or "").split())
|
|
)
|
|
if not number.isdigit() or not name or number in out:
|
|
continue
|
|
if description.lower() in UNASSIGNED or len(description) > MAX_DESCRIPTION:
|
|
continue
|
|
out[number] = [name] if _same(description, name) else [name, description]
|
|
return out
|
|
|
|
|
|
def main() -> int:
|
|
with urllib.request.urlopen(SOURCE, timeout=60) as response: # noqa: S310
|
|
raw = response.read().decode("utf-8")
|
|
registry = build(raw)
|
|
if len(registry) < MIN_PORTS:
|
|
print(
|
|
f"refusing to write a registry of only {len(registry)} ports",
|
|
file=sys.stderr,
|
|
)
|
|
return 1
|
|
TARGET.parent.mkdir(parents=True, exist_ok=True)
|
|
TARGET.write_text(
|
|
json.dumps(registry, separators=(",", ":"), sort_keys=True) + "\n",
|
|
encoding="utf-8",
|
|
)
|
|
described = sum(1 for entry in registry.values() if len(entry) > 1)
|
|
print(f"{TARGET}: {len(registry)} ports, {described} with a description")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|