Files
onenote-tools/docs/SECURITY.md

5.5 KiB

Security model

Trust boundary and local processing

Selected .one and .onepkg files are untrusted. The main thread checks the source size, reads one file into an ArrayBuffer, transfers it to a dedicated module worker, and receives serializable data-transfer objects. CAB entries are extracted only into memory; archive paths are never written to the filesystem.

The worker is a fault-containment and responsiveness boundary, not a security sandbox. A successful open keeps its worker session alive for page requests. Clearing the file, choosing another file, or unmounting the app terminates that worker; a failed open also terminates it. JavaScript garbage collection does not promise immediate release or secure erasure.

The application does not:

  • upload or transmit notebook bytes;
  • use a backend, proxy, telemetry, analytics, remote fonts, or external content fetching;
  • persist source or derived content in LocalStorage, IndexedDB, Cache Storage, cookies, or a service worker;
  • execute notebook content or inject notebook HTML/SVG;
  • use WebAssembly, a Rust runtime, or a native helper.

Active default limits

The main thread rejects a source larger than 512 MiB before reading it. The desktop section parser then applies these independent defaults:

Resource Default limit
Section bytes 512 MiB
File-node list fragments / nesting 16,384 / 64
File nodes 1,000,000
Objects 500,000
Properties per set / property nesting 16,384 / 64
Stream IDs 1,000,000
One property vector 64 MiB
Object references 1,000,000
Content-graph depth 256
Pages per section 100,000
Diagnostics per section 10,000
Extracted text per section 2,000,000 characters

The CAB/package path applies these defaults:

Resource Default limit
Cabinet input 512 MiB
Folders / files 1,024 / 10,000
CFDATA blocks 131,072
CAB name bytes 255
Path characters / path segments 4,096 / 64
One extracted file 256 MiB
One folder output 512 MiB
Total folder output 512 MiB
Total extracted entry bytes 512 MiB
Folder compression ratio 200:1
LZX window 8 MiB
LZX decode operations 1,000,000,000

A CFDATA block may declare at most 32 KiB of output. Counts and offsets use checked arithmetic and bounded readers. The CAB parser verifies supplied block checksums, rejects overlapping/out-of-range data, rejects absolute/traversal, empty, control-character, and case-insensitive duplicate paths, and refuses multi-cabinet/spanning entries.

LZX checks its window, Huffman trees, block sizes, match ranges, output size, and operation budget. CAB extraction checks cancellation and yields between data blocks so the worker can process termination. Desktop OneStore traversal checks fragment/reference cycles, nesting, object/property/reference counts, and byte ranges.

DTO strings are rendered as React text nodes. Notebook HTML, active SVG, scripts, attachment payloads, and automatic external navigation are not rendered. Link activation is not implemented. If links are added, they require explicit user action, scheme validation, and safe navigation attributes.

Known gaps and roadmap

  • There is no wall-clock deadline. Synchronous desktop .one parsing cannot observe cooperative cancellation until control returns; terminating the worker is the current hard stop.
  • The package flow holds the source, decompressed folder buffers, extracted entry slices, and parsed DTOs in memory at overlapping times. The byte/count limits bound these individually but do not guarantee a low peak heap.
  • Section text/page/diagnostic limits apply per contained section rather than once to the complete package.
  • CAB checksums detect accidental corruption but do not authenticate a package.
  • Format coverage is narrow and has only the documented golden files. New producer/version claims require licensed regression fixtures and malformed variants.
  • The worker boundary reduces UI impact but is not a substitute for browser and operating-system isolation. Open especially sensitive files in a dedicated browser profile if that risk matters.

Planned hardening includes an elapsed-time budget, cancellation checkpoints in desktop OneStore graph traversal, aggregate package DTO/text budgets, lower peak-memory extraction, expanded malformed-input/fuzz corpora, and additional licensed OneNote export fixtures.

Fixtures and vulnerability reporting

Never commit private notebooks. Fixture provenance and redistribution terms must be recorded in tests/fixtures/README.md.

Report suspected parser vulnerabilities privately to the repository owner through the Gitea instance before publishing malicious fixtures. Include the application version, browser, smallest reproducible input, diagnostic, and observed resource use. Do not attach sensitive notebooks.