Skip to content

filescan: read legacy Office files and files embedded in Office documents - #371

Merged
neamul602 merged 2 commits into
devfrom
feat/327-legacy-office
Nov 2, 2026
Merged

neamul602 merged 2 commits into
devfrom
feat/327-legacy-office

Conversation

@neamul602

@neamul602 neamul602 commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Approval-free task 3 of the File DLP epic (#327). It needs no new dependency: everything is the standard library.

Before this, .doc, .xls and .ppt were reported as unsupported_type, and files embedded in .docx/.xlsx/.pptx weren't opened.

What's read now

Format Text from Password-protected when
Word 97–2003 .doc The piece table (8-bit and UTF-16 pieces). Field codes are dropped and their results kept, as with .docx; paragraph and cell marks become breaks fEncrypted is set
Excel 97–2003 .xls (BIFF8) Shared strings, including strings that continue across CONTINUE records with their own 8/16-bit flag. Also LABEL/STRING cells, and NUMBER/RK/MULRK/cached FORMULA values, with whole numbers as digits so a card number stored as a number is found There's a FILEPASS record
PowerPoint 97–2003 .ppt TextChars and TextBytes atoms There's a CryptSession10 record or an EncryptedSummary stream
OLE packages (Package, Ole10Native) The wrapped file is unwrapped and scanned (the wrapped file's own rules)
  • Embedded files (word/xl/ppt/embeddings) are scanned as entries. Ones with findings, or protected by a password or Rights Management, are recorded and count towards the document's status. Unreadable embedded objects (equations, drawings) don't make the document unscannable; otherwise on_unscannable would trip on everyday documents.
  • Encrypted OOXML is now detected from the parsed directory. The old stream-name search stays as the fallback for compound files that don't parse.
  • Still unsupported_type: Excel 5/95, Outlook .msg and other OLE files, and PDF (which needs a library, so a dependency and license review).

Safety (hostile input)

cfbfile.go is a bounded compound-file reader:

  • every sector number is range-checked;
  • every chain is limited by the file's sector count, so loops end;
  • directory traversal is iterative with a visit bound;
  • streams are capped at max_file_bytes.

Malformed files are reported as corrupt.

Test plan

  • Tests build real compound files, with small streams in the mini stream and large ones in regular sectors, for each format. They cover the encryption flags, both package kinds, embedded files (including a password-protected one and an unreadable equation) and malformed files (truncated, bad sector size, out-of-range directory, a sector chain looping on itself, an oversized stream).
  • Fuzzing with compound-file seeds: 90 s, no crashers. Every saved input scans in under 0.3 ms.
  • golangci-lint: 0 issues on linux, darwin and windows. gosec v2.30.0: 0. Linux tests, make verify-cross and the changelog check pass.
  • Not yet run on real Office 97–2003 files; the fixtures are synthetic. (sentinelgo dlp test can't check this: it reads a file as plain text with the clipboard engine, not with the file scanner.)

Refs #327

🤖 Generated with Claude Code

…ents

.doc, .xls and .ppt were reported unsupported_type, and files embedded in
docx/xlsx/pptx weren't opened.

- cfbfile.go: a bounded OLE compound file reader (header, FAT and DIFAT,
  directory tree, mini stream). Every sector number is range-checked and
  every chain bounded by the file's sector count; streams are capped at
  max_file_bytes.
- .doc: text through Word's piece table (8-bit and UTF-16 pieces); field
  codes dropped and results kept, like instrText in docx; paragraph and
  cell marks as breaks; fEncrypted means password_protected.
- .xls (BIFF8): the shared string table, including strings continued in
  CONTINUE records with their own 8/16-bit flag; LABEL and STRING cells;
  NUMBER, RK, MULRK and cached FORMULA values (whole numbers as digits, so
  a card number stored as a number is found); FILEPASS means
  password_protected. Excel 5/95 (Book) stays unsupported.
- .ppt: TextChars and TextBytes atoms; CryptSession10 or EncryptedSummary
  means password_protected.
- OLE packages (Package, Ole10Native) are unwrapped and scanned.
- Encrypted OOXML is detected from the parsed directory; the stream-name
  search stays as the fallback for files that don't parse.
- Embedded files (word/xl/ppt/embeddings) are scanned as entries. Ones
  with findings or protected by a password/RMS are recorded; unreadable
  objects (equations, drawings) aren't, so everyday documents don't become
  unscannable.

Tests build real compound files (mini stream and regular sectors) for
each format, encryption flags, packages, embeddings and malformed files
(loops, bad sectors, oversized streams). Fuzz seeds now include compound
files; 90 s of fuzzing found no crashers, and the slowest saved input
scans in 0.2 ms.

Refs #327

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI (base), Organization UI (inherited)
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c27d1afa-bdd8-40e7-911e-1ecbc6104ff0

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@sonarqubecloud

sonarqubecloud Bot commented Nov 2, 2026

Copy link
Copy Markdown

@neamul602
neamul602 merged commit abfc3f0 into dev Nov 2, 2026
23 checks passed
@neamul602
neamul602 deleted the feat/327-legacy-office branch November 2, 2026 10:20
@neamul602 neamul602 mentioned this pull request Nov 2, 2026
Merged
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