Skip to content

Commit 8da0211

Browse files
Release v5.16.0 (#112)
* Fix stacktrace sniffer bucket naming * Fix HTML report status tab navigation * Remove unused six and tabulate dependencies * - (fix) fixed runtime debug classification compatibility with metadata so no longer breaks auto-calibration or scan progress rendering. * Restore calibrated response progress output * Fix calibrated progress line rotation * Improve browser calibration coverage * Add secret response sniffer * Add shadow copy sniffer * Fix filtered progress line clearing before WAF warnings * Fix filtered progress rotation after WAF warning * Fix stacktrace false positive on notice-like 404 paths * Fix stacktrace false positives on notice and warning-like 404 paths * Document Mobirise fingerprint detection * Fix graceful proxy failure handling * Add 403 path bypass normalization variants * Add verified open redirect sniffer * extend gitignore * Refactor sniffer architecture for multi-finding support * Add staged lint and dead-code quality gates * Apply safe Ruff cleanup rules * added to passively classify suspicious malware, webshell, injected script * Clean noisy stdout summary fields * Add QRATOR infrastructure fingerprint * (feat) Add differential report comparison * fix(scanner): clean WAF diagnostic logging * fix(proxy): support authenticated HTTP CONNECT * fix(proxy): harden rotating proxy handling * fix(wordlist): harden extension filters * Harden response filter handling * Harden response filter handling * fix(runtime): keep request provider stable for filtered directory scans * fix(scanner): stabilize filtered scans and report e2e contract * fix(scanner): harden proxy and transport-loss handling * docs(update): document safe cross-platform update flow * noisy debug output in mode by logging proxy selection only when a new proxy pool is created * Prepare managed scan temp workspace * Prepare managed scan temp workspace * Add socks5h proxy scheme support without changing proxy debug output * test: cover output and calibration edge branches * Hardened WordPress fingerprinting by adding static asset probes and preventing weak login/xmlrpc-only evidence from becoming a primary CMS match * add legacy tls compatibility * fix stacktrace false positives on localized 404 pages * Update readme * Update readme * Update readme * Update readme * Fix security scanner findings * Disable noisy CodeQL cleartext logging rule
1 parent 04e1b38 commit 8da0211

222 files changed

Lines changed: 20131 additions & 5540 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dockerignore

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ reports
4444
syslog
4545
site
4646
*.log
47+
debug.log
4748

4849
# Local binaries / keys
4950
opendoor
@@ -66,11 +67,11 @@ benchmarks
6667
docs
6768
tests
6869
e2e-server.log
69-
data/test.dat
7070

7171
# Local helper scripts are not needed in runtime image
7272
scripts
7373
release.sh
74+
debug.sh
7475

7576
# Debian/Kali packaging build artifacts
7677
.pybuild
@@ -91,4 +92,5 @@ debian/*.substvars
9192
*.tar.xz
9293

9394
# Misc
94-
TODO
95+
TODO
96+
ROADMAP.md

.github/codeql/codeql-config.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ paths-ignore:
55

66
query-filters:
77
- exclude:
8-
id: py/incomplete-url-substring-sanitization
8+
id: py/incomplete-url-substring-sanitization
9+
- exclude:
10+
id: py/clear-text-logging-sensitive-data

.github/e2e/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,4 @@ def log_message(self, fmt: str, *args: object) -> None:
5252
if __name__ == "__main__":
5353
server = HTTPServer(("127.0.0.1", 8088), Handler)
5454
print("E2E server listening on http://127.0.0.1:8088", flush=True)
55-
server.serve_forever()
55+
server.serve_forever()

.github/e2e/validate.py

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Validate OpenDoor GitHub Actions E2E reports against v5.15.2 report shape.
2+
Validate OpenDoor GitHub Actions E2E reports against current filtered report shape.
33
"""
44

55
import json
@@ -18,7 +18,7 @@
1818
"/login",
1919
}
2020

21-
EXPECTED_IGNORED_404_PATHS = {
21+
EXPECTED_FILTERED_404_PATHS = {
2222
"/nonexistent",
2323
"/ghost",
2424
"/random-miss",
@@ -62,22 +62,6 @@ def item_urls(report: dict, bucket: str) -> list[str]:
6262
]
6363

6464

65-
def item_details(report: dict, bucket: str) -> list[dict]:
66-
details = report.get("report_items", {}).get(bucket)
67-
68-
if isinstance(details, list):
69-
return [
70-
item
71-
for item in details
72-
if isinstance(item, dict)
73-
]
74-
75-
return [
76-
{"url": str(item), "code": "-"}
77-
for item in report.get("items", {}).get(bucket, [])
78-
]
79-
80-
8165
def has_path(urls: list[str], path: str) -> bool:
8266
return any(url.endswith(path) or path in url for url in urls)
8367

@@ -90,7 +74,10 @@ def validate_json_report() -> None:
9074
assert_true(total.get("forbidden") == 1, "JSON: forbidden bucket has exactly 1 hit")
9175
assert_true(total.get("auth") == 1, "JSON: auth bucket has exactly 1 hit")
9276
assert_true(total.get("redirect") == 1, "JSON: redirect bucket has exactly 1 hit")
93-
assert_true(total.get("ignored") == 4, "JSON: ignored bucket has exactly 4 filtered misses")
77+
assert_true(
78+
total.get("ignored") in (None, 0),
79+
"JSON: ignored bucket is absent or empty for filtered misses",
80+
)
9481

9582
success_urls = item_urls(report, "success")
9683

@@ -107,16 +94,12 @@ def validate_json_report() -> None:
10794
"JSON: /auth-required is in auth bucket",
10895
)
10996

110-
ignored_items = item_details(report, "ignored")
97+
ignored_urls = item_urls(report, "ignored")
11198

112-
for path in sorted(EXPECTED_IGNORED_404_PATHS):
99+
for path in sorted(EXPECTED_FILTERED_404_PATHS):
113100
assert_true(
114-
any(
115-
has_path([str(item.get("url", ""))], path)
116-
and str(item.get("code")) == "404"
117-
for item in ignored_items
118-
),
119-
f"JSON: {path} is preserved as ignored 404",
101+
not has_path(ignored_urls, path),
102+
f"JSON: {path} is not preserved as an ignored report item",
120103
)
121104

122105
active_buckets = ("success", "forbidden", "auth", "redirect")
@@ -126,7 +109,7 @@ def validate_json_report() -> None:
126109
for url in item_urls(report, bucket)
127110
]
128111

129-
for path in sorted(EXPECTED_IGNORED_404_PATHS):
112+
for path in sorted(EXPECTED_FILTERED_404_PATHS):
130113
assert_true(
131114
not has_path(active_urls, path),
132115
f"JSON: {path} is not in active finding buckets",
@@ -190,10 +173,15 @@ def result_matches(rule_id: str, path: str | None = None, code: int | None = Non
190173
"SARIF: redirect bucket has status 301",
191174
)
192175

193-
for path in sorted(EXPECTED_IGNORED_404_PATHS):
176+
assert_true(
177+
not result_matches("opendoor.finding.ignored"),
178+
"SARIF: ignored filtered misses are not reported as findings",
179+
)
180+
181+
for path in sorted(EXPECTED_FILTERED_404_PATHS):
194182
assert_true(
195-
result_matches("opendoor.finding.ignored", path, 404),
196-
f"SARIF: {path} is ignored/404",
183+
not result_matches("opendoor.finding.ignored", path, 404),
184+
f"SARIF: {path} is not reported as ignored/404",
197185
)
198186

199187

@@ -210,4 +198,4 @@ def main() -> int:
210198

211199

212200
if __name__ == "__main__":
213-
raise SystemExit(main())
201+
raise SystemExit(main())

.github/workflows/lint.yml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
name: Lint
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
workflow_dispatch:
9+
10+
permissions:
11+
contents: read
12+
13+
concurrency:
14+
group: lint-${{ github.ref }}
15+
cancel-in-progress: true
16+
17+
jobs:
18+
ruff:
19+
name: Ruff
20+
runs-on: ubuntu-latest
21+
timeout-minutes: 5
22+
23+
env:
24+
PYTHONUTF8: "1"
25+
PYTHONIOENCODING: utf-8
26+
27+
steps:
28+
- name: Checkout repository
29+
uses: actions/checkout@v6
30+
31+
- name: Set up Python
32+
uses: actions/setup-python@v6
33+
with:
34+
python-version: "3.12"
35+
cache: pip
36+
cache-dependency-path: |
37+
requirements.txt
38+
requirements-dev.txt
39+
pyproject.toml
40+
41+
- name: Install dev dependencies
42+
run: |
43+
python -m pip install --upgrade pip
44+
python -m pip install -r requirements-dev.txt
45+
46+
- name: Run Ruff
47+
run: python -m ruff check .
48+
vulture:
49+
name: Vulture advisory
50+
runs-on: ubuntu-latest
51+
timeout-minutes: 5
52+
continue-on-error: true
53+
54+
env:
55+
PYTHONUTF8: "1"
56+
PYTHONIOENCODING: utf-8
57+
58+
steps:
59+
- name: Checkout repository
60+
uses: actions/checkout@v6
61+
62+
- name: Set up Python
63+
uses: actions/setup-python@v6
64+
with:
65+
python-version: "3.12"
66+
cache: pip
67+
cache-dependency-path: |
68+
requirements.txt
69+
requirements-dev.txt
70+
pyproject.toml
71+
72+
- name: Install dev dependencies
73+
run: |
74+
python -m pip install --upgrade pip
75+
python -m pip install -r requirements-dev.txt
76+
77+
- name: Run Vulture advisory scan
78+
run: |
79+
vulture src tests --min-confidence 65

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ reports/
3939
scripts/
4040
syslog/
4141
site/
42-
data/test.dat
4342
release.sh
43+
debug.sh
44+
debug.log
4445

4546
# Local binaries / keys
4647
opendoor
@@ -57,6 +58,8 @@ results.sarif
5758

5859
# Misc
5960
TODO
61+
ROADMAP.md
62+
6063
# Local transport profiles may contain secrets.
6164
data/wireguard-profiles/*.conf
6265
!data/wireguard-profiles/example.conf
@@ -86,3 +89,4 @@ debian/*.substvars
8689
*.changes
8790
*.dsc
8891
*.tar.xz
92+
/debug.sh

0 commit comments

Comments
 (0)