Skip to content

v0.1.12 — upload-file-from-url (pinned transport, opt-in)

Choose a tag to compare

@marselsel marselsel released this 13 Aug 19:16
· 4 commits to main since this release

The server-side URL fetcher held back in 0.1.11 — now with its DNS-rebinding TOCTOU closed by connection-level IP pinning. Based on the contribution by @gutencoder (#39, merged as #41).

Added

  • upload-file-from-url — fetch a file from a share link server-side and store it in Lexware, so a receipt already in OneDrive/SharePoint reaches the books without its bytes crossing the model context. Off by default (LEXWARE_ENABLE_URL_UPLOAD); its own capability; requires the drafts tier (does not enable it).
  • LEXWARE_UPLOAD_ALLOWED_HOSTS — hosts the tool may fetch from (dot-boundary match; unset = Microsoft file-sharing defaults; a set value replaces them; empty blocks every host).

Security

  • The connection is pinned to the address that was checked (src/uploads/pinned-fetch.ts, on node:https — no new dependency). The guard's one DNS resolution is both range-checked and fed to the socket, so there is no second lookup to disagree with the first. TLS is untouched: SNI and certificate validation still bind to the hostname; only the dialled address comes from the pin.
  • Three layers at every redirect hop: host allow-list → resolved-address range check (loopback/private/link-local/metadata/CGNAT/… in every IPv4/IPv6 spelling, fail-closed) → pinning.
  • URLs with embedded credentials are refused; filenames are sanitized (the same trust boundary as the ticket flow).

Verification

  • 321 tests, including real-certificate TLS tests proving pinning doesn't weaken cert validation, a raw-ClientHello SNI check, and an RFC-6761 .invalid-host connection proof.
  • Reviewed through multiple adversarial passes, /code-review high, and /security-review high (no findings).

Default-off, so deploying changes no behavior until an operator sets LEXWARE_ENABLE_URL_UPLOAD=true. Full detail in CHANGELOG.md.