Skip to content

Security hardening: 4 MEDIUM fixes (content_types determinism, NaN, SVG gaps, font cache) - #20

Merged
900Labs merged 1 commit into
masterfrom
hardening/medium-fixes
Jul 30, 2026
Merged

900Labs merged 1 commit into
masterfrom
hardening/medium-fixes

Conversation

@900Labs

@900Labs 900Labs commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Summary

Follow-up to PR #19 (CRITICAL+HIGH fixes). Addresses 4 MEDIUM issues from the full audit.

Fixes

C1: [Content_Types].xml non-deterministic

crates/slides-pptx/src/package.rs — HashMap iteration order was randomized per process, violating byte-for-byte preservation. Fixed by sorting keys before serialization.

C2: parse_attr_f64 accepts NaN/Infinity

crates/slides-pptx/src/load.rsNaN/inf from OOXML attributes produced malformed XML on save. Fixed by rejecting non-finite values.

C3: SVG sanitizer gaps

crates/slides-media/src/lib.rs — Three bypasses closed:

  • Protocol-relative URLs (//evil.example/x) now rejected
  • <style> elements now rejected (CSS @import/url() vectors)
  • Inline style attributes now rejected
  • Entity parse errors in URL attributes now treated as unsafe (not silently empty)
  • 3 new tests added

C4: Font re-encoding cache

crates/slides-render/src/lib.rs — Each font was base64-encoded per-alias per-export (~10MB redundant base64). Fixed with OnceLock caching — each font encoded once and reused.

Test results

  • 380 workspace tests pass (+3 new SVG sanitizer tests).
  • npm run check: 0 errors, 0 warnings.
  • scripts/verify-local.sh: green. scripts/verify-public-release.sh: green.

…aps, font caching

C1: [Content_Types].xml was non-deterministic (HashMap iteration order is
randomized per process). Fixed by sorting defaults/overrides keys before
serializing, ensuring byte-for-byte stability across runs.

C2: parse_attr_f64 accepted NaN/Infinity from OOXML attributes, producing
malformed XML on save. Fixed by rejecting non-finite values.

C3: SVG sanitizer gaps — protocol-relative URLs (//evil.example), <style>
elements, inline style attributes, and entity-bypass in URL values. All
now rejected. Added 3 new tests.

C4: Font embedding re-encoded each font per-alias per-render (~10MB of
base64 per export where ~2.3MB sufficed). Fixed with OnceLock caching —
each font is base64-encoded once and reused.
@900Labs
900Labs merged commit 3f7f496 into master Jul 30, 2026
8 checks passed
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.

1 participant