Skip to content

Fix JUnit XML attribute escaping (use quoteattr)#8

Closed
appsechq-brian wants to merge 14 commits into
levinebw:mainfrom
AppSecHQ:fix/junit-xml-attribute-escaping
Closed

Fix JUnit XML attribute escaping (use quoteattr)#8
appsechq-brian wants to merge 14 commits into
levinebw:mainfrom
AppSecHQ:fix/junit-xml-attribute-escaping

Conversation

@appsechq-brian

Copy link
Copy Markdown
Collaborator

Summary

  • Findings containing double quotes in their message broke the Tests tab ('Secure' is an unexpected token)
  • `xml.sax.saxutils.escape()` only handles `&`, `<`, `>` — not `"`
  • Switch to `quoteattr()`, which escapes `"` and returns the value wrapped in quotes

Test plan

  • Python syntax check passes
  • Validated in a pipeline run with 69 SAST findings: Tests tab now populates with no warnings

levine-cycode and others added 14 commits January 27, 2026 08:43
…ning

- Add vulnerable_packages/ directory for SCA testing
- Add n8n-workflow example with vulnerable n8n v1.100.0
- Add Dockerfile.n8n-vulnerable with CVE-2026-21858
- Update README with new vulnerable_packages section
- gha-excessive-permissions: detects permissions: write-all and broad
  write scope grants at workflow and job level
- gha-dangerous-pr-target-checkout: detects pull_request_target trigger
  combined with checkout of incoming PR code (pwn request pattern)
Scans vulnerable_apps/ for SAST findings on push, PR, and manual trigger.
Blocks build on any finding (default CLI exit code 1).
Scans only the diff between PR base and head commits,
not the full codebase. Falls back to HEAD~1 on manual trigger.
Full scan runs on push to main only. PRs use the delta scan workflow.
…centralized template

Three new patterns complementing the existing CLI gate in azure-pipelines.yml:

- scripts/cycode-gate.sh — queries the Cycode RIG Graph API for Open
  violations in a named repo; fails the build if any match. Filters by
  severity, category, and risk score via env vars. Emits
  ##vso[task.logissue] for Azure Pipelines.

- scripts/cycode-json-to-junit.py + scripts/cycode-summary.py —
  converters that take `cycode -o json scan ...` output and produce
  JUnit XML (for PublishTestResults@2 → Tests tab) and a Markdown
  report (for ##vso[task.uploadsummary] → custom tab on build summary).

- templates/cycode-scan.yml — centralized template consumed via
  `extends`. App pipelines pass parameters (scanPath, scanTypeFlags,
  severityThreshold, repoName, gateMode) and inherit the scan +
  publish + gate logic. Cross-repo usage documented in the header.

Example pipelines:
- azure-pipelines-api-gate.yml           — API gate standalone
- azure-pipelines-publish-results.yml    — Tests tab + summary + artifact
- azure-pipelines-template-consumer.yml  — minimal consumer of the template
- RIG .result[] items wrap detections in a .resource object; updated the
  jq filter to drill through it so severity/risk_score/policy/file_path
  render correctly instead of all dashes.
- Use bare repo name ("vectorvictor") in defaults and docs — the
  owner/repo form returns 0 results in RIG.
- Check .fast_query_has_more and surface "at least N (page cap hit)"
  when results are paginated, so the gate message is truthful when the
  tenant has more than page_size findings.
…terns

Azure Pipelines advanced patterns: API gate, UI publishing, central template
Findings whose message text contained a double quote produced malformed
XML attributes that Azure Pipelines' PublishTestResults@2 rejected with
"'Secure' is an unexpected token. Expecting whitespace" and the Tests
tab failed to populate.

xml.sax.saxutils.escape() only handles &, <, >. quoteattr() additionally
escapes " and returns the value wrapped in quotes — the canonical way to
build XML attribute values.

Verified end-to-end in the AppSecHQ/vectorvictor publish-results pipeline
against a run with 69 findings; Tests tab now populates cleanly.
@appsechq-brian

Copy link
Copy Markdown
Collaborator Author

Opened on wrong fork. See AppSecHQ/vectorvictor instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants