Skip to content

Commit 118b9de

Browse files
Merge pull request #102 from stanislav-web/release/v5.15.2
Release v5.15.2
2 parents c68dd2d + 1e83e67 commit 118b9de

22 files changed

Lines changed: 589 additions & 13 deletions

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
CHANGELOG
22
=======
33

4+
v5.15.2 (04.05.2026)
5+
---------------------------
6+
- (enhancement) added compact pre-scan fingerprint summary with detected web stack and security posture
7+
- (enhancement) added offline HSTS and preload-readiness detection to the existing `--fingerprint` pass without adding a new CLI flag
8+
- (enhancement) stores security-header posture as `fingerprint.security_headers.hsts` with grade, max-age, includeSubDomains, preload, redirect and warning metadata
9+
- (enhancement) preserves HSTS metadata in standard, text, CSV, HTML, SQLite, JSON and SARIF reports
10+
- (docs) documented compact pre-scan fingerprint summary and HSTS / preload readiness output
11+
- (tests) added regression coverage for compact fingerprint summary rendering
12+
- (tests) added regression coverage for preload-ready, weak and HTTP-only HSTS handling plus report propagation
13+
- (tests) coverage gate remains configured at `99%`
14+
415
v5.15.1 (03.05.2026)
516
---------------------------
617
- (fix) removed literal `opendoor` markers from active fingerprint 404-baseline, HTTP calibration and DNS wildcard calibration probe paths

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ It helps security researchers, penetration testers, bug bounty hunters, DevSecOp
6161
- custom request headers, cookies, and raw HTTP request templates;
6262
- response filters by status, size, text, regex, and body length;
6363
- smart auto-calibration for soft-404, wildcard, catch-all, semantic response-diff, and DNS wildcard cases;
64-
- technology fingerprint detection for CMS, ecommerce platforms, frameworks, and runtime stacks;
64+
- technology fingerprint detection for CMS, ecommerce platforms, frameworks, runtime stacks, infrastructure, and HSTS posture;
6565
- passive WAF detection and WAF-safe scan mode;
6666
- controlled header and path bypass probes for blocked `401` and `403` resources;
6767
- resumable scan sessions with checkpoint autosave;
@@ -95,7 +95,7 @@ OpenDoor focuses on **context-aware discovery** instead of blind enumeration.
9595

9696
## 🧬 Recognized technologies
9797

98-
OpenDoor includes a heuristic fingerprint engine for detecting probable application stacks, CMS platforms, frameworks, site builders, static-site tooling, infrastructure providers, and WAF / anti-bot systems.
98+
OpenDoor includes a heuristic fingerprint engine for detecting probable application stacks, CMS platforms, frameworks, site builders, static-site tooling, infrastructure providers, HSTS / preload readiness, and WAF / anti-bot systems.
9999

100100
| Category | Examples |
101101
|---|---|
@@ -107,6 +107,7 @@ OpenDoor includes a heuristic fingerprint engine for detecting probable applicat
107107
| Static / docs generators | MkDocs, Docusaurus, Hugo, Jekyll, VitePress |
108108
| Infrastructure / hosting | Cloudflare, AWS, Vercel, Netlify, GitHub Pages, GitLab Pages, Heroku, Azure, Google Cloud, Fastly, Akamai, Hostinger, DDoS-Guard, Tencent Cloud |
109109
| WAF / anti-bot | Cloudflare, AWS WAF, Azure Front Door, Akamai, Imperva, Sucuri, ModSecurity, DataDome, Kasada, F5 BIG-IP ASM |
110+
| Security headers | HSTS presence, max-age, includeSubDomains, preload directive, local preload readiness |
110111

111112
Full list of supported technologies:
112113
[Fingerprinting technologies](https://opendoor.readthedocs.io/detection/fingerprinting)
@@ -117,6 +118,14 @@ Run fingerprint detection:
117118
opendoor --host https://example.com --fingerprint
118119
```
119120

121+
After the fingerprint pass finishes, OpenDoor prints a compact pre-scan summary before dictionary enumeration starts:
122+
123+
```text
124+
Fingerprint result: cms/WordPress (95%)
125+
Web stack: WordPress | PHP | Cloudflare
126+
Security posture: HSTS preload-ready
127+
```
128+
120129
Read more:
121130

122131
- [Fingerprinting guide](https://opendoor.readthedocs.io/detection/fingerprinting/)

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5.15.1
1+
5.15.2

data/directories.dat

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27038,6 +27038,7 @@ cache_icons.php
2703827038
cache_index.php
2703927039
cache_ipbanned.php
2704027040
cache_magics.php
27041+
cache_manager
2704127042
cache_medals.php
2704227043
cache_null.php
2704327044
cache_page
@@ -31453,6 +31454,7 @@ cnf
3145331454
cngemail.html
3145431455
cngenick.html
3145531456
cni-conf.json
31457+
cnjadmin
3145631458
cnn
3145731459
cnn.php
3145831460
cno
@@ -100675,6 +100677,7 @@ test/tmp
100675100677
test/version_tmp
100676100678
test_
100677100679
test_.php
100680+
test_ability
100678100681
test_adodb_lite.php
100679100682
test_area
100680100683
test_banner
@@ -114513,6 +114516,7 @@ zzb
114513114516
zzz
114514114517
zzz.html
114515114518
zzz.php
114519+
zzz_test_ability
114516114520
zzzzz.php
114517114521
zzzzzz
114518114522
~

docs/Usage.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,10 +450,37 @@ Fingerprinting is useful for:
450450
- identifying static hosting or CDN providers;
451451
- adjusting filters and scan strategy.
452452

453+
After fingerprinting finishes, OpenDoor prints a short pre-scan summary and then continues with the requested scan:
454+
455+
```text
456+
Fingerprint result: cms/WordPress (95%)
457+
Web stack: WordPress | PHP | Cloudflare
458+
Security posture: HSTS preload-ready
459+
```
460+
461+
Detailed fingerprint metadata remains available in reports and in the final standard summary.
462+
453463

454464
OpenDoor 5.14.5 expands the passive fingerprint catalog with selected regional CMS, site-builder and strong HTTP-visible infrastructure signatures, including InstantCMS, Duda, Hostinger Website Builder, CMS.S3 / Megagroup, Webasyst / Shop-Script, Discuz!, NetCat, Hostinger, DDoS-Guard and Tencent Cloud.
455465

456466

467+
OpenDoor 5.15.2 also adds offline HSTS / preload-readiness detection to the same `--fingerprint` pass. It checks only the target host response and does not call external preload-status services. Report metadata is stored as `fingerprint.security_headers.hsts`.
468+
469+
Example output in machine-readable reports:
470+
471+
```json
472+
{
473+
"grade": "preload-ready",
474+
"max_age": 31536000,
475+
"include_subdomains": true,
476+
"preload": true,
477+
"preload_ready": true,
478+
"http_to_https_redirect": true,
479+
"warnings": []
480+
}
481+
```
482+
483+
457484
---
458485

459486
## 🛡️ WAF detection and safe mode

docs/detection/fingerprinting.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,22 @@ opendoor \
4545

4646
---
4747

48+
## Compact pre-scan summary
49+
50+
When fingerprinting is enabled, OpenDoor prints a compact summary immediately after the fingerprint pass and before dictionary enumeration starts. This gives operators an early target profile without waiting for report generation.
51+
52+
Example:
53+
54+
```text
55+
Fingerprint result: cms/WordPress (95%)
56+
Web stack: WordPress | PHP | Cloudflare
57+
Security posture: HSTS preload-ready
58+
```
59+
60+
The compact summary intentionally stays short. Full evidence, candidates, HSTS fields and report-specific metadata remain in JSON, HTML, CSV, SQLite, TXT, STD and SARIF outputs.
61+
62+
---
63+
4864
## Fingerprinting with reports
4965

5066
```shell
@@ -277,6 +293,51 @@ The heuristic fingerprint engine currently recognizes the following platform fam
277293

278294
---
279295

296+
## Security headers posture
297+
298+
When `--fingerprint` is enabled, OpenDoor also performs an offline HSTS posture check against the observed target root response. It does not query external preload services. The check uses only headers returned by the target host.
299+
300+
The HSTS result is stored under `fingerprint.security_headers.hsts` in machine-readable reports.
301+
302+
Example JSON fragment:
303+
304+
```json
305+
{
306+
"fingerprint": {
307+
"security_headers": {
308+
"hsts": {
309+
"present": true,
310+
"header": "max-age=31536000; includeSubDomains; preload",
311+
"max_age": 31536000,
312+
"include_subdomains": true,
313+
"preload": true,
314+
"preload_ready": true,
315+
"http_to_https_redirect": true,
316+
"grade": "preload-ready",
317+
"warnings": []
318+
}
319+
}
320+
}
321+
}
322+
```
323+
324+
OpenDoor grades HSTS as:
325+
326+
| Grade | Meaning |
327+
|---|---|
328+
| `missing` | No effective HSTS was observed on the final HTTPS response, or the final response was plain HTTP. |
329+
| `invalid` | HSTS exists, but `max-age` is missing or invalid. |
330+
| `disabled` | HSTS is explicitly disabled with `max-age=0`. |
331+
| `weak` | HSTS exists, but `max-age` is below 180 days. |
332+
| `moderate` | HSTS is usable, but below the common preload minimum of one year. |
333+
| `good` | HSTS has at least one year `max-age`, but lacks `includeSubDomains`. |
334+
| `strong` | HSTS has at least one year `max-age` and `includeSubDomains`. |
335+
| `preload-ready` | Local preload-readiness checks passed: HTTPS final response, `max-age >= 31536000`, `includeSubDomains`, and `preload`. |
336+
337+
Warnings are intentionally explicit, for example `missing_hsts`, `max_age_too_low`, `missing_include_subdomains`, `preload_not_ready`, or `not_https`.
338+
339+
---
340+
280341
## Recommended workflow
281342

282343
```shell

docs/img/logo.png

485 KB
Loading

docs/img/open-door.png

-609 KB
Binary file not shown.

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ OpenDoor supports single-target and batch scanning, custom wordlists, response f
88

99
> Use OpenDoor only on systems you own or have explicit permission to test.
1010
11-
![OpenDoor](img/open-door.png)
11+
![OpenDoor](img/logo.png)
1212

1313
---
1414

src/lib/browser/browser.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,100 @@ def __fingerprint_progress(self, current, total, label):
260260
if int(current or 0) >= int(total or 1):
261261
output.writeln('')
262262

263+
@staticmethod
264+
def __normalize_fingerprint_summary_value(value, default='unknown'):
265+
"""
266+
Normalize optional fingerprint metadata for compact console output.
267+
268+
:param mixed value: raw fingerprint value
269+
:param str default: fallback value
270+
:return: str
271+
"""
272+
273+
normalized = str(value or '').strip()
274+
if not normalized:
275+
return default
276+
return normalized
277+
278+
@classmethod
279+
def __build_fingerprint_stack_summary(cls, fingerprint):
280+
"""
281+
Build a short application/runtime/infrastructure summary.
282+
283+
:param dict fingerprint: fingerprint result
284+
:return: str
285+
"""
286+
287+
if not isinstance(fingerprint, dict):
288+
return 'unknown'
289+
290+
app_name = cls.__normalize_fingerprint_summary_value(fingerprint.get('name'))
291+
runtime = cls.__normalize_fingerprint_summary_value(
292+
fingerprint.get('runtime', {}).get('name') if isinstance(fingerprint.get('runtime'), dict) else None
293+
)
294+
infrastructure = cls.__normalize_fingerprint_summary_value(
295+
fingerprint.get('infrastructure', {}).get('provider')
296+
if isinstance(fingerprint.get('infrastructure'), dict) else None
297+
)
298+
299+
values = []
300+
for value in (app_name, runtime, infrastructure):
301+
if value not in values:
302+
values.append(value)
303+
304+
return ' | '.join(values) if values else 'unknown'
305+
306+
@classmethod
307+
def __build_fingerprint_security_summary(cls, fingerprint):
308+
"""
309+
Build a short security posture summary from fingerprint metadata.
310+
311+
:param dict fingerprint: fingerprint result
312+
:return: str
313+
"""
314+
315+
if not isinstance(fingerprint, dict):
316+
return 'unknown'
317+
318+
security_headers = fingerprint.get('security_headers')
319+
if not isinstance(security_headers, dict):
320+
return 'unknown'
321+
322+
hsts = security_headers.get('hsts')
323+
if not isinstance(hsts, dict):
324+
return 'unknown'
325+
326+
grade = cls.__normalize_fingerprint_summary_value(hsts.get('grade'))
327+
if grade == 'preload-ready':
328+
return 'HSTS preload-ready'
329+
return 'HSTS {0}'.format(grade)
330+
331+
@classmethod
332+
def __render_fingerprint_summary_lines(cls, fingerprint):
333+
"""
334+
Build compact post-fingerprint lines for early scan visibility.
335+
336+
:param dict fingerprint: fingerprint result
337+
:return: list[str]
338+
"""
339+
340+
return [
341+
'Web stack: {0}'.format(cls.__build_fingerprint_stack_summary(fingerprint)),
342+
'Security posture: {0}'.format(cls.__build_fingerprint_security_summary(fingerprint)),
343+
]
344+
345+
@classmethod
346+
def __print_fingerprint_summary(cls, fingerprint):
347+
"""
348+
Print compact fingerprint summary lines before dictionary enumeration starts.
349+
350+
:param dict fingerprint: fingerprint result
351+
:return: None
352+
"""
353+
354+
for line in cls.__render_fingerprint_summary_lines(fingerprint):
355+
tpl.info(msg=line)
356+
263357
def fingerprint(self):
264358
"""
265359
Run heuristic technology fingerprinting before the main scan.
@@ -296,6 +390,8 @@ def fingerprint(self):
296390
)
297391
)
298392

393+
self.__print_fingerprint_summary(result)
394+
299395
if result.get('signals'):
300396
evidence = ', '.join([signal.get('value', '') for signal in result.get('signals', [])[:4]])
301397
tpl.info(msg='Fingerprint evidence: {0}'.format(evidence))

0 commit comments

Comments
 (0)