Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .bumpversion.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: Apache-2.0

[tool.bumpversion]
current_version = "0.19.5"
current_version = "0.19.6"
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)((?P<pre_l>a|b|rc)(?P<pre_n>\\d+))?"
serialize = [
"{major}.{minor}.{patch}{pre_l}{pre_n}",
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/security_vulnerability.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
8 changes: 4 additions & 4 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

| Field | Value |
| :------- | :--------- |
| Version | v0.19.5 |
| Version | v0.19.6 |
| Codename | Magnetite |
| Date | 2026-07-04 |
| Status | Stable |
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion src/zenzic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
2 changes: 1 addition & 1 deletion src/zenzic/cli/_standalone.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand Down
22 changes: 7 additions & 15 deletions tests/test_security.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading