Files
auth-tools/SECURITY.md
T

5.8 KiB
Raw Blame History

Security model

Data flow

All inputs are processed in the browser tab. There are no application fetch, WebSocket, beacon, analytics, service-worker, credential-storage or remote-metadata paths. OTP secrets, OCRA PIN input, imported files, WebAuthn responses and live test credential metadata are React/session memory and disappear on reload or Clear session.

Downloads and clipboard writes require a user action. URI/CSV exports are not encrypted; the dedicated encrypted format uses an authenticated cipher and a user-supplied password. The UI masks OTP secrets and provisioning URIs by default, but masking is not memory protection.

Camera capture is never started automatically. The dedicated origin requests it only after the user selects camera scanning, reads bounded frames locally, and stops all media tracks after a match, cancellation, timeout or component teardown. The shared Portal origin keeps camera permission disabled.

Trust boundaries

  • The static release and its hosting origin are trusted code. A compromised host can alter JavaScript and steal subsequently entered material; verify the release SHA-256 when this matters.
  • Imported URIs, CSV, XML, protobuf, JSON, Base64url and CBOR are untrusted. Size/depth/count limits are applied before or during decoding. Imported text is rendered by React, never as markup. The only generated markup insertion is the project-owned QR SVG serializer, which receives an already serialized provisioning URI and emits path coordinates only.
  • WebAuthn client data is verified as exact strings/bytes. Origins and RP IDs are not suffix-matched. The expected challenge is caller-supplied ceremony state; the tool cannot prove that a server generated or consumed it once.
  • Assertion signatures establish consistency with the supplied COSE public key. Attestation checks establish format-specific cryptographic bindings; certificate-chain trust and authenticator policy remain separate. Imported FIDO metadata has its JWS signer checked and can be evaluated against explicitly supplied roots, but no root is installed or downloaded silently. The signer-chain check validates supported certificate signatures to the pinned root; it is not a full RFC 5280 name-constraints, policy, revocation or path-building engine.
  • WebAuthn trace redaction removes user labels, handles and top-level credential identifiers. Signed client/authenticator/attestation blobs remain intact for replay and can still contain stable identifiers; redacted traces require review before publication.

Origin isolation

toolbox.add-ideas.de/apps/auth/ shares an origin with every other Portal app. Live registration/assertion is therefore disabled there. It is enabled only for localhost development or exact host auth.toolbox.add-ideas.de. Deploy the dedicated host top-level with frame-ancestors 'none'; do not change its RP ID to the parent domain.

Cryptography

HMAC, digest, random generation, PBKDF2 key derivation, AES-GCM authenticated encryption, PSKC AES-CBC encryption/decryption, public-key import and signature verification use the browser Web Cryptography API. Aegis password slots use the maintained @noble/hashes scrypt implementation with explicit memory/work bounds. No project-authored cryptographic primitive is used for key derivation or encryption. OTP dynamic truncation, OCRA data-input assembly and bounded DER/TPM structure interpretation are project code covered by tests.

The encrypted backup format uses a 16-byte random salt, 600,000 PBKDF2-HMAC-SHA-256 iterations, a 256-bit AES-GCM key, a 96-bit random IV, a 128-bit authentication tag and authenticated version/KDF/cipher metadata. Decryption failures do not expose partial plaintext. It is an export format, not persistent storage.

The password-encrypted PSKC profile derives a 128/192/256-bit AES-CBC key with bounded PBKDF2, encrypts a random MAC key with that key, prepends a fresh IV to every encrypted value, and authenticates every encrypted secret with HMAC before decryption. A PSKC extension in the Auth Tools namespace preserves the selected OTP hash. Unsupported or unauthenticated encrypted PSKC profiles are rejected.

SHA-1 remains available only where HOTP/TOTP/OCRA interoperability standards require it; it is used inside HMAC or as an explicitly selected OCRA PIN digest, not as a collision-resistant document signature.

Parser limits

  • Provisioning URI: 16 KiB.
  • Migration/CSV/plain PSKC input: 4 MiB; encrypted PSKC and vendor/encrypted backup input: 16 MiB.
  • Google protobuf: bounded input, varints at most 10 bytes, supported wire types only.
  • CBOR: 4 MiB, depth 32, 10,000 items, definite lengths only, duplicate map keys rejected.
  • OTP secret: 1 KiB; random generation: 161,024 bytes.
  • Verification windows: routine TOTP 100 steps maximum; explicit drift search 10,000 periods; HOTP 10,000 counters maximum.
  • Aegis password derivation: scrypt N at most 65,536, r at most 16, p at most 4 and a 64 MiB memory policy.
  • PSKC password derivation: PBKDF2 at most 2,000,000 iterations; export requires at least 100,000 iterations and a 12-character password.
  • WebAuthn trace and OTP collection snapshot: 8 MiB; collection/profile count 10,000.
  • QR encoder: version 10 maximum. QR decoder: 16 MiB, 4096 px per side and 16 megapixels.
  • FIDO Metadata BLOB: 32 MiB, 100,000 entries and 20 signer certificates maximum.
  • Camera QR scan: 60 seconds, about 10 frames/second and 1,280 px maximum processing edge.

Not persistent storage or an identity provider

Do not use this app as the only copy of a credential. It does not offer browser persistence, recovery codes, account recovery, server-side challenge state, rate limiting, audit logging, a preconfigured device-attestation trust policy, FIDO certification, or phishing protection outside normal browser WebAuthn behavior.

Report vulnerabilities through the repository issue tracker without including real secrets or production assertions.