Skip to content

Audio metadata findings are reported but no redactor handles audio, so --enable-redaction exits 0 with the value still in the file #306

Description

@sectoramen

Summary

Audio files are scanned and their metadata findings are reported, but no redactor handles audio, so those findings can never be removed. --enable-redaction produces an output file that still contains the value, at exit 0, with nothing saying otherwise.

A reported-but-unredactable value is the same leak as an undetected one, dressed as a success.

Evidence

The read side is fully built out — there is a dedicated preprocessor:

internal/preprocessors/audio_metadata_preprocessor.go:239   case ".mp3":
internal/preprocessors/audio_metadata_preprocessor.go:241   case ".flac":
internal/preprocessors/audio_metadata_preprocessor.go:245   case ".m4a":
internal/preprocessors/shared_utilities.go:132              ".mp3": true,

Audio is also admitted as an embedded part, so it is reached inside containers too (embeddedMediaType returns "audio" for .mp3, .wav, .m4a, .flac).

The write side has nothing. Every registered redactor's supported types, checked:

redactor claims
office .docx .xlsx .pptx
legacyole .doc .xls .ppt
image .bmp .gif .jpeg .jpg .png .tif .tiff .webp
pdf .pdf
plaintext .txt .log .csv .json .xml .yaml .yml .md .conf .ini
$ grep -o '"\.\(mp3\|wav\|m4a\|flac\)"' internal/redactors/*/*.go
# no matches

So RedactionManager.GetRedactorForFile cannot resolve a redactor for any audio extension.

Why it matters

ID3 and MP4/M4A metadata carry author, artist, comment, copyright and free-text description fields — exactly the shape the engine reports as AUTHOR_INFO and friends, and exactly where a name, email or phone number ends up in a voice memo or recorded call.

The failure is silent: the finding is named in the report, redaction is requested, the run exits 0. RedactionCount counts findings, not replacements (internal/core/redact.go:148), so it is not usable as evidence either way.

Scope

Independent of container nesting. It applies to a standalone .mp3 on the command line, and #305's nested-redaction loop will hit the same wall from the other direction — when that loop asks the manager for an audio redactor it will get none, and that outcome has to be disclosed rather than silently skipped.

Two ways to close it

  1. Disclose it (small, and needed regardless). When no redactor can handle a file that produced findings, surface it through the existing stats.UnredactedFiles path so the run cannot report success. internal/core/redact.go:118-130 already carries the guard and the reasoning for exactly this case; it just is not reached here.
  2. Write an audio redactor (complete). Strip or overwrite the offending ID3 / MP4 atom fields, mirroring what the image redactor does for EXIF. That redactor is the closest existing model — same shape of problem, metadata-only, simple strategy.

(1) should probably land first and on its own, since it stops the false success for any unhandled type, not just audio.

Note

Found while auditing embedded-part parity for #305. The parity table there records this row; this issue exists because the gap is not about nesting.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions