diff --git a/.bumpversion.toml b/.bumpversion.toml index 6ddf71f..7ac95bf 100644 --- a/.bumpversion.toml +++ b/.bumpversion.toml @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 [tool.bumpversion] -current_version = "0.19.5" +current_version = "0.19.6" parse = "(?P\\d+)\\.(?P\\d+)\\.(?P\\d+)((?Pa|b|rc)(?P\\d+))?" serialize = [ "{major}.{minor}.{patch}{pre_l}{pre_n}", diff --git a/.github/ISSUE_TEMPLATE/security_vulnerability.yml b/.github/ISSUE_TEMPLATE/security_vulnerability.yml index bdeea74..c7b425f 100644 --- a/.github/ISSUE_TEMPLATE/security_vulnerability.yml +++ b/.github/ISSUE_TEMPLATE/security_vulnerability.yml @@ -29,7 +29,7 @@ body: attributes: label: Zenzic version description: Output of `zenzic --version` - placeholder: "0.19.5" + placeholder: "0.19.6" validations: required: true diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index dab4b50..1d55761 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -7,7 +7,7 @@ # # repos: # - repo: https://github.com/PythonWoods/zenzic -# rev: v0.19.5 +# rev: v0.19.6 # hooks: # - id: zenzic-verify # quality gate β€” corrisponde a `just verify` lato zenzic # - id: zenzic-guard # fast staged-file credential scan diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d30633..be45dc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,18 @@ Versions follow [Semantic Versioning](https://semver.org/). ## [Unreleased] +## [0.19.6] - 2026-07-04 + +### πŸ”’ Security Advisory + +This patch release resolves three vulnerabilities identified during Red Team adversarial audits. All users are advised to update to ensure DQS integrity and CI stability. + +### Fixed + +- **Security (DQS Evasion):** Resolved the "Ghost Policy" bypass where developers could evade the Suppression Cap and DQS penalties by injecting leading spaces (e.g., `" Z101"`) into `.zenzic.toml` policies. The scoring engine now strictly sanitizes inputs. +- **Security (DoS via TOML Bomb):** Hardened the configuration parser against mixed-type arrays. Malformed arrays no longer cause unhandled Python tracebacks (crashing the CI runner) but are safely caught and reported as `Z001` (Fatal Config Error). +- **Security (Z603 Evasion):** Fixed a logical flaw where duplicate inline suppressions on the same line were all marked as "consumed" by a single finding. Duplicates now correctly trigger `Z603` (Dead Suppression) to prevent hidden debt. + ## [0.19.5] - 2026-07-04 ### Fixed diff --git a/CITATION.cff b/CITATION.cff index 6da0ddb..b605435 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -15,7 +15,7 @@ abstract: >- performs deterministic static analysis using a two-pass reference pipeline and a RE2-backed credential scanner, with zero subprocess calls and full SARIF 2.1.0 support for CI/CD integration. -version: 0.19.5 +version: 0.19.6 date-released: 2026-07-04 url: "https://zenzic.dev" repository-code: "https://github.com/PythonWoods/zenzic" diff --git a/RELEASE.md b/RELEASE.md index 76d1d45..d56a8fb 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -8,7 +8,7 @@ | Field | Value | | :------- | :--------- | -| Version | v0.19.5 | +| Version | v0.19.6 | | Codename | Magnetite | | Date | 2026-07-04 | | Status | Stable | @@ -21,7 +21,7 @@ Before tagging, every item must be green: - [ ] `zenzic lab all` β€” all 20 scenarios exit with expected code - [ ] `zenzic score --stamp` committed β€” badge in README.md reflects current score - [ ] `zenzic check all .` β€” zero findings in the repo root -- [ ] `pyproject.toml` version matches the tag (`0.19.5`) +- [ ] `pyproject.toml` version matches the tag (`0.19.6`) - [ ] `CITATION.cff` version and date updated - [ ] ParitΓ  bilingue Z602 verificata (docs vs i18n/it/) - [ ] `CHANGELOG.md` β€” `[Unreleased]` section moved to the new version heading @@ -55,11 +55,11 @@ git checkout main git pull origin main # 3. Tag the main branch and push -git tag v0.19.5 +git tag v0.19.6 git push origin main --tags ``` -- [ ] Create GitHub Release from the tag, using the `## [0.19.5]` CHANGELOG section as the release body. +- [ ] Create GitHub Release from the tag, using the `## [0.19.6]` CHANGELOG section as the release body. ## Changelog Reference diff --git a/mkdocs.yml b/mkdocs.yml index 75bb493..e8e578e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -199,7 +199,7 @@ extra: # ADR-037: No hardcoded SemVer in any .html or .md source. # CI pipeline passes the current version at build time, e.g.: # uv run mkdocs build --extra zenzic_version=0.14.1 - zenzic_version: "0.19.5" # release sync + zenzic_version: "0.19.6" # release sync social: - icon: fontawesome/brands/github link: https://github.com/PythonWoods/zenzic diff --git a/pyproject.toml b/pyproject.toml index 5d6e7a7..ccf8973 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ build-backend = "hatchling.build" [project] name = "zenzic" -version = "0.19.5" +version = "0.19.6" description = "Engineering-grade, engine-agnostic static analyzer and credential scanner for Markdown documentation" readme = "README.md" requires-python = ">=3.10" diff --git a/src/zenzic/__init__.py b/src/zenzic/__init__.py index f3a6ce4..c9823c5 100644 --- a/src/zenzic/__init__.py +++ b/src/zenzic/__init__.py @@ -2,5 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 """Zenzic β€” engine-agnostic static analyzer and credential scanner for Markdown documentation.""" -__version__ = "0.19.5" +__version__ = "0.19.6" __version_name__ = "Basalt" # Release codename stored separately from the package version. diff --git a/src/zenzic/cli/_standalone.py b/src/zenzic/cli/_standalone.py index 0065479..133c74d 100644 --- a/src/zenzic/cli/_standalone.py +++ b/src/zenzic/cli/_standalone.py @@ -1585,7 +1585,7 @@ def _scaffold_plugin(repo_root: Path, plugin_name: str, force: bool) -> None: description = "Custom Zenzic plugin rule package" readme = "README.md" requires-python = ">=3.11" -dependencies = ["zenzic>=0.19.5"] +dependencies = ["zenzic>=0.19.6"] [project.entry-points."zenzic.rules"] {project_slug} = "{module_name}.rules:{class_name}" diff --git a/tests/test_security.py b/tests/test_security.py index 4cb7532..25bcb8d 100644 --- a/tests/test_security.py +++ b/tests/test_security.py @@ -5,37 +5,29 @@ from __future__ import annotations from pathlib import Path + import pytest -from zenzic.models.config import ZenzicConfig from zenzic.cli._governance import count_per_file_ignores from zenzic.core.suppressions import SuppressionTracker +from zenzic.models.config import ZenzicConfig def test_ghost_policy_leading_space_remediation() -> None: """Vulnerability 1: Ensure leading/trailing spaces in per_file_ignores are counted in DQS.""" - config_data = { - "governance": { - "per_file_ignores": { - "docs/index.md": [" Z101"] - } - } - } + config_data = {"governance": {"per_file_ignores": {"docs/index.md": [" Z101"]}}} config = ZenzicConfig(**config_data) # Verify the space-prefixed code is properly counted as a suppression per_file_count = count_per_file_ignores(config) - assert per_file_count == 1, "The leading-space ignore must be counted as a suppression to avoid DQS bypass" + assert per_file_count == 1, ( + "The leading-space ignore must be counted as a suppression to avoid DQS bypass" + ) def test_toml_bomb_mixed_type_array_remediation() -> None: """Vulnerability 2: Ensure mixed-type arrays in configuration tables do not crash the swallowed root validator.""" - data = { - "custom_rules": [ - {"id": "ZZ-TEST", "pattern": "test", "message": "test"}, - 42 - ] - } + data = {"custom_rules": [{"id": "ZZ-TEST", "pattern": "test", "message": "test"}, 42]} # This should not raise an AttributeError crash try: diff --git a/uv.lock b/uv.lock index 19fd3b7..68562ce 100644 --- a/uv.lock +++ b/uv.lock @@ -2465,7 +2465,7 @@ wheels = [ [[package]] name = "zenzic" -version = "0.19.5" +version = "0.19.6" source = { editable = "." } dependencies = [ { name = "google-re2" },