Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ All notable changes will be documented here. The project intends to follow seman

### Added

- Deterministic malformed-input corpus for generic bytes, JPEG, WebP, PNG, and shared TIFF corruption families.
- Cross-format invariants for deterministic inspection and cleaning, native-exception containment, fail-closed operations, input immutability, and cheap limit stress.
- Testing and fuzz-readiness guidance with future property and fuzz targets; random fuzzing remains outside normal CI.

- Bounded PNG chunk parsing with chunk-count, IEND, trailing-data, type, range, CRC-field, and compact CRC-32 validation.
- PNG text, exact XMP `iTXt`, `eXIf`, ICC, timestamp, rendering/color, APNG, and unknown ancillary classification.
- Shared TIFF/EXIF field decoding for exact bounded PNG `eXIf` data views.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ GPS rational components remain exact numerator/denominator pairs; decimal coordi

## Security philosophy

Every byte is untrusted. All offsets are interpreted within bounded views, traversal is iterative and limited, and malformed structures fail without unchecked access. PNG image data and compressed metadata are never inflated. Unknown JPEG APP segments, WebP chunks, and PNG ancillary chunks are preserved by default. See the [security model](docs/security-model.md), [architecture](docs/architecture.md), and [cleaning policy](docs/cleaning-policy.md).
Every byte is untrusted. All offsets are interpreted within bounded views, traversal is iterative and limited, and malformed structures fail without unchecked access. PNG image data and compressed metadata are never inflated. Unknown JPEG APP segments, WebP chunks, and PNG ancillary chunks are preserved by default. See the [security model](docs/security-model.md), [architecture](docs/architecture.md), [testing model](docs/testing.md), and [cleaning policy](docs/cleaning-policy.md).

## Non-goals

Expand Down
13 changes: 13 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,16 @@ Traversal validates byte order, magic, complete IFD tables, field sizes, offset
- `metadata-inspected`: reserved for future exhaustive metadata decoders.

A report includes `metadataTruncated: true` when its entry budget is reached; a diagnostic is also emitted when the diagnostic budget permits. Verification fails closed rather than deriving absence from a truncated report.

## Testing layers

```text
bounded binary primitives
→ format fixture tests
→ deterministic malformed corpus
→ cross-format invariants
→ future property tests
→ future fuzzing
```

Production parsers remain internal. Public operations are the preferred cross-format targets; the shared TIFF parser is directly callable only from test code. See [testing and fuzz readiness](testing.md).
6 changes: 6 additions & 0 deletions docs/security-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,9 @@ Malformed inner EXIF/TIFF or textual payloads do not block removal of their boun
Verification reports only supported `present` or `absent` observations. Not-applicable format concepts produce no check. Truncated metadata reporting is recorded independently of diagnostic output, produces no checks, and fails verification. The library does not establish authenticity, provenance, absence of proprietary metadata, visible-person privacy, steganography safety, malware safety, or complete metadata absence.

Core production code has zero runtime dependencies and no network, analytics, telemetry, filesystem, DOM, Node `Buffer`, or required platform-global behavior.

## Malformed-input assurance

Malformed input is part of the expected threat model. A small deterministic corpus covers representative generic, JPEG, WebP, PNG, and TIFF structural corruption families, including truncation, corrupt lengths and offsets, cycles, and configured work limits. Parser loops must advance or terminate, and unsafe outer container boundaries cause typed fail-closed cleaning and verification errors before output is produced.

The corpus is regression coverage, not proof of parser correctness. No decompression is implemented, so decompression bombs are outside the current attack surface and `maxDecompressedBytes` remains reserved. Reproducible property testing and dedicated fuzzing are planned future layers; random fuzzing is not part of normal CI. See [testing and fuzz readiness](testing.md).
51 changes: 51 additions & 0 deletions docs/testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Testing and Fuzz Readiness

The test suite uses deterministic TypeScript fixture builders for JPEG markers,
WebP RIFF chunks, PNG chunks and CRCs, and TIFF IFD structures. Fixtures stay
small, readable, and cheap; binary files are used only when they would be
clearer than the builder expression.

## Test layers

```text
bounded binary primitives
→ format fixtures and parser algorithms
→ deterministic malformed corpus
→ cross-format public API invariants
→ future reproducible property tests
→ future fuzz targets
```

The malformed corpus covers generic byte patterns plus representative JPEG,
WebP, PNG, and shared TIFF truncation, corrupt length, invalid offset, cycle,
and configured-limit families. Corpus assertions focus on stable contracts:
format/status, relevant diagnostic codes, deterministic results, caller-input
immutability, typed fail-closed cleaning and verification, and safe removal of
bounded malformed metadata. They intentionally avoid full-report snapshots and
timing thresholds.

Security-limit tests use tiny inputs with small custom values for input,
segment, chunk, IFD entry/depth, metadata entry, string, and diagnostic limits.
`maxDecompressedBytes` remains unused because the library performs no
decompression.

## Future property and fuzz targets

Likely targets are:

- `inspectMetadata(bytes)` through the public API;
- bounded JPEG, WebP, and PNG parser entry points in test/fuzz builds;
- the bounded TIFF parser as a test-only internal target;
- `cleanMetadata(bytes, policy)` through the public API.

Strong future properties include containment of native bounds exceptions,
deterministic inspection and cleaning, re-inspectable clean output, Privacy
Clean idempotency, input immutability, removal-only output sizing, preservation
of unknown structures, and default ICC preservation. WebP is permitted to patch
the RIFF size and applicable VP8X metadata flags.

No random fuzzing runs in normal CI, and no property/fuzz dependency is
currently installed. A future sprint can add reproducible seeded property tests
or dedicated fuzz harnesses if their coverage benefit justifies the development
dependency and CI cost. The deterministic corpus is regression coverage, not a
proof of parser correctness.
Loading
Loading