Skip to content

gebalamariusz/cloud-audit

v2.3.0 Security

This release includes 14 security fixes for security teams reviewing exposed deployments.

✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →
This release patches 14 known CVEs

Topics

audit aws aws-audit aws-security cis-benchmarks cli
+13 more
cloud-security compliance devops security iam iac infrastructure-security open-source-security python python-cli security-scanner terraform vulnerability-scanning

Affected surfaces

auth rbac

ReleasePort's take

Moderate signal
editorial:auto 9d

HTML entity escapes user‑controlled Mermaid node labels to prevent SVG context breakout.

Why it matters: Security fix (severity 90) mitigates SVG context breakout in Mermaid output generation; critical for developers and SREs handling untrusted diagram data.

Summary

AI summary

Updates Tests, admin, and default across a mixed release.

Changes in this release

Security Critical

HTML entity escapes user-controlled Mermaid node labels to prevent SVG context breakout.

HTML entity escapes user-controlled Mermaid node labels to prevent SVG context breakout.

Source: llm_adapter@2026-05-25

Confidence: high

Security High

Strips non‑http(s) URL schemes from HTML report links to block JavaScript injection.

Strips non‑http(s) URL schemes from HTML report links to block JavaScript injection.

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Security High

Escapes markdown control characters in Markdown output to prevent link injection.

Escapes markdown control characters in Markdown output to prevent link injection.

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Security Medium

Prevents `_make_id` collisions by appending SHA‑256 suffix for long identifiers (CWE-345/CWE-1023).

Prevents `_make_id` collisions by appending SHA‑256 suffix for long identifiers (CWE-345/CWE-1023).

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Security Medium

Eliminates AssumeRole cycle re‑emission of seed role as lateral target via ARN deduplication.

Eliminates AssumeRole cycle re‑emission of seed role as lateral target via ARN deduplication.

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Security Medium

Restricts `_find_execution_role_for_lambda` to return roles only for the queried Lambda (CWE-697).

Restricts `_find_execution_role_for_lambda` to return roles only for the queried Lambda (CWE-697).

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Security Medium

Clamps `--max-depth` and `--max-nodes` CLI options to safe bounds (1‑25, 1‑10 000) to avoid DoS.

Clamps `--max-depth` and `--max-nodes` CLI options to safe bounds (1‑25, 1‑10 000) to avoid DoS.

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Security Medium

Errors when writing ANSI escape sequences to non‑TTY files (`--format tree --output FILE`).

Errors when writing ANSI escape sequences to non‑TTY files (`--format tree --output FILE`).

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Security Medium

Escapes Rich markup in console rendering to prevent terminal recoloring attacks.

Escapes Rich markup in console rendering to prevent terminal recoloring attacks.

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Security Medium

Refuses to follow pre‑existing symlinks in `--output` writers (TOCTOU protection).

Refuses to follow pre‑existing symlinks in `--output` writers (TOCTOU protection).

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Security Low

Wraps `OSError` in friendly messages instead of leaking full tracebacks.

Wraps `OSError` in friendly messages instead of leaking full tracebacks.

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Security Low

Persists `escalation_paths` in saved scans for blast‑radius consumption.

Persists `escalation_paths` in saved scans for blast‑radius consumption.

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Feature Low

Adds `cloud-audit blast-radius` CLI command for attack‑surface analysis.

Adds `cloud-audit blast-radius` CLI command for attack‑surface analysis.

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Feature Low

Supports EC2, IAM Role/User, Lambda, S3 bucket, and Secrets Manager secret as seed resources.

Supports EC2, IAM Role/User, Lambda, S3 bucket, and Secrets Manager secret as seed resources.

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Feature Low

Provides output formats: tree (default), JSON, Mermaid diagram, and Markdown summary.

Provides output formats: tree (default), JSON, Mermaid diagram, and Markdown summary.

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Feature Low

Introduces `cloud-audit exposure` command for account‑wide blast‑impact aggregation.

Introduces `cloud-audit exposure` command for account‑wide blast‑impact aggregation.

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Performance Low

Adds regression tests covering resource‑type detection, depth limits, rendering formats, and security fixes (26 new tests).

Adds regression tests covering resource‑type detection, depth limits, rendering formats, and security fixes (26 new tests).

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Bugfix Medium

Falls back to `report.all_findings` when role missing from `escalation_paths` (EC2 admin‑role case).

Falls back to `report.all_findings` when role missing from `escalation_paths` (EC2 admin‑role case).

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Bugfix Medium

Refines detection matching to require `/` or `:` boundaries, eliminating false positives from short labels.

Refines detection matching to require `/` or `:` boundaries, eliminating false positives from short labels.

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Bugfix Low

Corrects off‑by‑one depth handling so max‑depth = 1 reports Account Takeover for EC2 with attached admin role.

Corrects off‑by‑one depth handling so max‑depth = 1 reports Account Takeover for EC2 with attached admin role.

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Refactor Medium

Adds optional `security_graph` field to `ScanReport` with default None for backward compatibility.

Adds optional `security_graph` field to `ScanReport` with default None for backward compatibility.

Source: granite4.1:30b@2026-05-25-audit

Confidence: low

Full changelog

Added

  • Blast Radius CLI - new cloud-audit blast-radius --resource <id> command
    that walks outward from a single AWS resource and shows what an attacker
    could reach if THAT resource were compromised. Pure in-memory analysis
    against a saved scan - zero AWS API calls at blast-radius time.

    Seed resource types supported:

    • EC2 instance (short id i-XXX)
    • IAM Role / IAM User (full ARN)
    • Lambda function (full ARN)
    • S3 bucket (full ARN)
    • Secrets Manager secret (full ARN)

    Expansion rules:

    • Compute -> attached IAM role (via attack chain viz_steps from AC-01,
      AC-02, AC-05 etc.) -> reachable identities and data
    • Identity -> admin impact node when escalation_paths indicate admin
    • Identity -> AssumeRole chain targets from iam_trust_graph
    • Identity (admin) -> S3 buckets / Secrets Manager secrets present in
      findings as candidate exfiltration targets

    Output formats (--format):

    • tree (default) - Rich tree in CLI with color-coded node types
    • json - BlastRadiusGraph v1.0 schema, the wire-format contract with
      cloud-audit-demo's 3D visualization (camelCase fields preserved on purpose)
    • mermaid - Mermaid graph TD diagram with per-type styling
    • markdown - compact summary for PRs or reports

    Bounds:

    • --max-depth N (default 5) caps BFS hops
    • --max-nodes N (default 50) caps total nodes in the graph

    Pure CLI, no Neo4j, no Docker, no SaaS account. Built on top of the
    existing iam_trust_graph (524 lines, AssumeRole BFS), iam_analyzer
    (706 lines, 60 escalation methods catalog), correlate (1574 lines,
    31 attack-chain rules with VizSteps), and cost_model so the
    same fixes you see in scan show up under the same finding ids in the
    blast-radius output. Documented in docs/features/blast-radius.md.

  • exposure command - new cloud-audit exposure rolls up findings by
    blast-impact heuristic (which identities/data would compound on the next
    hop). Complements blast-radius (single-seed) with an account-wide view.

Changed

  • ScanReport.security_graph - new optional field (dict[str, object] | None).
    Populated by the scanner for blast-radius / exposure consumers. Backwards-
    compatible: existing parsers that don't know the field will keep working
    thanks to default=None.

Fixed

Nine issues addressed by the pre-release security audit (SECURITY-AUDIT-2026-05-15.md):

  • SEC-001 - Mermaid output now HTML-entity escapes user-controlled node
    labels (<, >, &, ", \, plus brackets, braces, pipes). Without this,
    a crafted scan label </text> would break out of the Mermaid SVG context
    when the diagram is rendered in a GitHub README.
  • SEC-002 - _make_id collision protection: when a sanitised candidate id
    exceeds 120 chars, a SHA-256(prefix + value) suffix is appended so two
    long-but-different inputs cannot collide post-truncation (CWE-345 / CWE-1023).
  • SEC-003 - AssumeRole cycle (A->B->A) no longer re-emits the seed role
    as a lateral target node. ARN-level dedup (visited_arns) catches the
    cross-prefix duplicate that graph-id dedup alone misses.
  • SEC-004 - _find_execution_role_for_lambda now refuses to return a
    role belonging to a different function (CWE-697 narrow-match): scan with
    chain for fnA and query for fnB returns None, not fnA's role.
  • SEC-005 - --max-depth and --max-nodes are clamped to safe bounds
    (1..25 and 1..10_000) instead of accepting unbounded user input (DoS).
  • SEC-006 - --format tree + --output FILE returns an error instead of
    silently writing ANSI escape sequences to disk (CWE-684).
  • SEC-007 - Exception handler in the CLI wraps OSError with a friendly
    message instead of leaking a full Python traceback to stderr.
  • SEC-008 - Rich console rendering of node lines escapes Rich markup
    ([red]...[/]) found inside scan labels so a crafted scan can't recolor
    the terminal output.
  • SEC-009 - Scanner persists escalation_paths to the saved scan so
    blast-radius can read them without re-running the IAM analyzer.

Plus pre-release follow-ups from the second security pass:

  • F-S2-01 - HTML report templates (report.html.j2, compliance_html.py)
    now strip non-http(s) URL schemes from finding.cost_estimate.source_url
    and finding.remediation.doc_url. Without this, a javascript: URL in a
    crafted scan JSON would execute when the user clicks the link in the
    rendered HTML report.
  • F-S2-02 - All --output writers refuse to follow pre-existing symlinks
    (TOCTOU symlink attack protection on shared CI runners). The CLI raises a
    clear error instead of silently clobbering the symlink target.
  • F-S2-03 - Markdown output (--format markdown) now escapes markdown
    control characters in user-controlled labels so a crafted resource name
    cannot inject [link](javascript:...) into the rendered report.
  • F-S2-04 - _resolve_role_arn falls back to report.all_findings when
    the role isn't present in escalation_paths (an EC2 with an attached
    admin role but no separate escalation path previously returned a
    seed-only blast graph - now resolves and reports Account Takeover).
  • F-S2-05 - BFS --max-depth=1 now surfaces Account Takeover for an
    EC2 seed with an attached admin role (was off-by-one: compute->role
    linkage previously consumed the depth budget).
  • F-S2-06 - Fix/detection matching no longer uses bare endswith(label)
    for short labels - now requires a / or : boundary, eliminating false
    positives where label "admin" matched super-admin.

Tests

  • 786 -> 812 (+26 net). New regression tests in tests/test_blast_radius.py
    and tests/test_graph.py cover: resource-type detection (8 regex patterns),
    empty-scan seed-only behaviour, IAM role -> impact node, EC2 with attached
    role linkage, Lambda with execution role, max-depth and max-nodes
    enforcement, Rich tree render, Mermaid graph TD shape, JSON schema
    spot-checks (top-level fields, camelCase preservation, node + edge type
    enums), fixes and detections pulled from findings, and a full
    TestSecurityRegression class for SEC-001 through SEC-009.

Schema contract

The JSON output is the schema documented in
cloud-audit-demo/src/types/blast-radius.ts (BlastRadiusGraph v1.0).
Field names are camelCase by intent because the demo's TypeScript types
are the consumer. A per-file ruff exemption in pyproject.toml documents
this trade-off.

Security Fixes

  • SEC-001 – Mermaid output HTML‑entity escapes user‑controlled labels to prevent SVG context breakout
  • SEC-002 – SHA‑256 suffix added when sanitized IDs exceed 120 chars (CWE‑345/CWE‑1023)
  • SEC-003 – Deduplication prevents AssumeRole cycle re‑emission of seed role
  • SEC-004 – `_find_execution_role_for_lambda` now rejects cross‑function role returns (CWE‑697)
  • SEC-005 – `--max-depth` and `--max-nodes` clamped to safe bounds (1‑25, 1‑10 000) to avoid DoS
  • SEC-006 – Error raised when writing ANSI escapes to a file via `--format tree --output FILE` (CWE‑684)
  • SEC-007 – Friendly error message instead of full traceback on CLI OSError
  • SEC-008 – Rich console rendering escapes markup in scan labels to prevent terminal recoloring
  • F-S2-01 – HTML report strips non‑http(s) URL schemes from `source_url` and `doc_url` (prevents javascript: injection)
  • F-S2-02 – CLI refuses to follow pre‑existing symlinks on `--output` paths (TOCTOU protection)
  • F-S2-03 – Markdown output escapes markdown control characters in labels (prevents link injection)
  • F-S2-04 – `_resolve_role_arn` falls back to all findings for missing escalation paths, enabling Account Takeover detection
  • F-S2-05 – BFS `--max-depth=1` now surfaces Account Takeover for EC2 seeds with attached admin roles
  • F-S2-06 – Detection matching requires `/` or `:` boundary to avoid false positives on short labels

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track gebalamariusz/cloud-audit

Get notified when new releases ship.

Sign up free

About gebalamariusz/cloud-audit

Open-source AWS security scanner with attack chain detection, breach cost estimation, and copy-paste remediation (CLI + Terraform). 47 checks, 16 attack chain rules. First free standalone AWS security MCP server.

All releases →

Related context

Earlier breaking changes

  • v2.2.0 Category enum gains THREAT value, separating active-abuse from SECURITY misconfigurations.

Beta — feedback welcome: [email protected]