diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a3c999..1a65644 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,18 @@ Version numbers follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html --- +## [0.4.1] — 2026-08-18 + +### Removed + +- The unverified-TLS warning banner from the terminal report and file + exports. Unverified probing is the default mode since 0.4.0, so the banner + fired on every HTTPS scan and carried no signal. `tls_verified` remains + available in the `--json` output and on `HeadersReport` for machine + consumers. + +--- + ## [0.4.0] — 2026-08-18 ### Added @@ -343,7 +355,8 @@ Version numbers follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html --- -[Unreleased]: https://github.com/NC3-TestingPlatform/headersvalidator/compare/v0.4.0...HEAD +[Unreleased]: https://github.com/NC3-TestingPlatform/headersvalidator/compare/v0.4.1...HEAD +[0.4.1]: https://github.com/NC3-TestingPlatform/headersvalidator/compare/v0.4.0...v0.4.1 [0.4.0]: https://github.com/NC3-TestingPlatform/headersvalidator/compare/v0.3.2...v0.4.0 [0.3.2]: https://github.com/NC3-TestingPlatform/headersvalidator/compare/v0.3.1...v0.3.2 [0.3.1]: https://github.com/NC3-TestingPlatform/headersvalidator/compare/v0.3.0...v0.3.1 diff --git a/README.md b/README.md index 3d66901..9f3dfa5 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ $ headersvalidator check example.com ``` ![Python](https://img.shields.io/badge/python-%3E%3D3.11-blue) -![Tests](https://img.shields.io/badge/tests-435%20passing-brightgreen) +![Tests](https://img.shields.io/badge/tests-433%20passing-brightgreen) ![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen) ![License](https://img.shields.io/badge/license-GPLv3-lightgrey) @@ -308,7 +308,7 @@ pytest tests/test_checker.py pytest tests/test_checker.py::TestHSTS -v ``` -The test suite has **435 tests** and maintains **100% statement coverage**. +The test suite has **433 tests** and maintains **100% statement coverage**. All HTTP network I/O (`requests.head`, `requests.get`) is mocked at the `fetch_headers` boundary — no test touches a real server or the internet. diff --git a/docs/SECURITY_VERDICT.md b/docs/SECURITY_VERDICT.md index d731850..2456b3c 100644 --- a/docs/SECURITY_VERDICT.md +++ b/docs/SECURITY_VERDICT.md @@ -46,8 +46,8 @@ Total penalty is mapped to a letter grade: > verify certificates by default (no request is spent on a verification > attempt and self-signed or invalid certificates cannot block the > assessment; the pre-existing HTTP fallback on a refused HTTPS connection -> is unchanged); the report is flagged -> instead (`tls_verified: false`, plus a warning banner). Certificate posture +> is unchanged); the report carries `tls_verified: false` in the `--json` +> output and on `HeadersReport` instead. Certificate posture > is assessed and graded by **tlsvalidator**, not here — this module grades > only the headers themselves, exactly as it already does for targets served > over plain HTTP. diff --git a/headersvalidator/__init__.py b/headersvalidator/__init__.py index 4542507..8dddef8 100644 --- a/headersvalidator/__init__.py +++ b/headersvalidator/__init__.py @@ -5,7 +5,7 @@ try: __version__ = version("headersvalidator") except PackageNotFoundError: # pragma: no cover – only when package not installed - __version__ = "0.4.0" + __version__ = "0.4.1" # NullHandler so library users who have not configured logging # do not see "No handler found" warnings (PEP 3118 / logging HOWTO). diff --git a/headersvalidator/reporter.py b/headersvalidator/reporter.py index 4ea1516..8dc2f74 100644 --- a/headersvalidator/reporter.py +++ b/headersvalidator/reporter.py @@ -48,13 +48,6 @@ VerdictSeverity.INFO: "dim", } -# Plain-text body of the unverified-TLS warning banner; also used to size -# file exports so the banner is never wrapped. -_TLS_UNVERIFIED_NOTICE = ( - "⚠ TLS certificate verification disabled — " - "headers were fetched over an unverified HTTPS connection." -) - # Grade letter → Rich colour string _GRADE_STYLE: dict[str, str] = { "A+": "bold bright_green", @@ -87,11 +80,6 @@ def print_full_report(report: HeadersReport, console: Console | None = None) -> f" [dim]→ redirected to[/dim] [cyan]{report.final_url}[/cyan]", highlight=False, ) - if not report.tls_verified: - con.print( - f" [bold yellow]{_TLS_UNVERIFIED_NOTICE}[/bold yellow]", - highlight=False, - ) con.print() _print_results_table(report, con) actions = extract_verdict_actions(report) @@ -299,7 +287,6 @@ def save_report(path: str, report: HeadersReport) -> None: header_floor = max( len(f"HTTP Headers Report — {report.url}"), len(f" → redirected to {report.final_url}"), - len(f" {_TLS_UNVERIFIED_NOTICE}") if not report.tls_verified else 0, ) + 4 width = max(content_width, header_floor) file_console = Console(record=True, highlight=False, width=width, file=StringIO()) diff --git a/pyproject.toml b/pyproject.toml index 89f8c17..450868d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "headersvalidator" -version = "0.4.0" +version = "0.4.1" description = "HTTP response header validator — RFC 9110, RFC 9111, OWASP, IANA" readme = "README.md" requires-python = ">=3.11" diff --git a/tests/test_reporter.py b/tests/test_reporter.py index 45f29f4..8218a12 100644 --- a/tests/test_reporter.py +++ b/tests/test_reporter.py @@ -115,15 +115,12 @@ def test_no_redirect_line_when_final_url_matches(self): output = _capture(print_full_report, report) assert "redirected to" not in output - def test_shows_banner_when_tls_unverified(self): + def test_no_tls_banner_in_output(self): + """tls_verified is exposed via --json / the API only — the terminal + report carries no per-scan banner (unverified is the default mode).""" report = _make_report(("X-Frame-Options", Status.PASS)) report.tls_verified = False output = _capture(print_full_report, report) - assert "unverified HTTPS connection" in output - - def test_no_banner_when_tls_verified(self): - report = _make_report(("X-Frame-Options", Status.PASS)) - output = _capture(print_full_report, report) assert "unverified" not in output @@ -317,18 +314,6 @@ def test_saves_svg(self, tmp_path): assert "X-Frame-Options" in content assert "