@blamejs/blamejs-shop 0.5.12 → 0.5.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/lib/asset-manifest.json +1 -1
- package/lib/sales-tax-filings.js +143 -0
- package/lib/vendor/MANIFEST.json +632 -416
- package/lib/vendor/blamejs/.clusterfuzzlite/Dockerfile +21 -10
- package/lib/vendor/blamejs/.clusterfuzzlite/build.sh +30 -9
- package/lib/vendor/blamejs/.github/dependabot.yml +8 -0
- package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +7 -2
- package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +7 -2
- package/lib/vendor/blamejs/.github/workflows/ci.yml +21 -21
- package/lib/vendor/blamejs/.github/workflows/codeql.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +4 -4
- package/lib/vendor/blamejs/.github/workflows/release-container.yml +7 -7
- package/lib/vendor/blamejs/.github/workflows/scorecard.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
- package/lib/vendor/blamejs/.gitignore +2 -0
- package/lib/vendor/blamejs/CHANGELOG.md +122 -0
- package/lib/vendor/blamejs/NOTICE +26 -1
- package/lib/vendor/blamejs/SECURITY.md +1 -1
- package/lib/vendor/blamejs/api-snapshot.json +207 -5
- package/lib/vendor/blamejs/docker/keycloak/realm-blamejs-test.json +29 -0
- package/lib/vendor/blamejs/examples/wiki/DEPLOY.md +1 -0
- package/lib/vendor/blamejs/examples/wiki/lib/build-app.js +31 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +109 -0
- package/lib/vendor/blamejs/examples/wiki/nginx.conf +106 -0
- package/lib/vendor/blamejs/examples/wiki/package-lock.json +1 -1
- package/lib/vendor/blamejs/examples/wiki/test/e2e.js +92 -0
- package/lib/vendor/blamejs/fuzz/asn1-der.fuzz.js +28 -0
- package/lib/vendor/blamejs/fuzz/cms-codec.fuzz.js +17 -0
- package/lib/vendor/blamejs/fuzz/link-header.fuzz.js +18 -0
- package/lib/vendor/blamejs/index.js +6 -0
- package/lib/vendor/blamejs/lib/a2a.js +4 -4
- package/lib/vendor/blamejs/lib/agent-idempotency.js +18 -2
- package/lib/vendor/blamejs/lib/agent-saga.js +36 -8
- package/lib/vendor/blamejs/lib/agent-snapshot.js +63 -6
- package/lib/vendor/blamejs/lib/app-shutdown.js +23 -20
- package/lib/vendor/blamejs/lib/archive-read.js +8 -0
- package/lib/vendor/blamejs/lib/archive-tar.js +12 -2
- package/lib/vendor/blamejs/lib/arg-parser.js +49 -5
- package/lib/vendor/blamejs/lib/asn1-der.js +12 -0
- package/lib/vendor/blamejs/lib/audit-sign.js +47 -1
- package/lib/vendor/blamejs/lib/audit.js +71 -8
- package/lib/vendor/blamejs/lib/auth/ciba.js +14 -2
- package/lib/vendor/blamejs/lib/auth/fido-mds3.js +58 -47
- package/lib/vendor/blamejs/lib/auth/jwt.js +34 -0
- package/lib/vendor/blamejs/lib/auth/oauth.js +90 -13
- package/lib/vendor/blamejs/lib/auth/oid4vci.js +20 -17
- package/lib/vendor/blamejs/lib/auth/openid-federation.js +214 -23
- package/lib/vendor/blamejs/lib/auth/saml.js +38 -20
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +10 -4
- package/lib/vendor/blamejs/lib/backup/bundle.js +13 -3
- package/lib/vendor/blamejs/lib/backup/index.js +16 -5
- package/lib/vendor/blamejs/lib/backup/manifest.js +18 -5
- package/lib/vendor/blamejs/lib/base32.js +21 -0
- package/lib/vendor/blamejs/lib/break-glass.js +19 -10
- package/lib/vendor/blamejs/lib/bundler.js +5 -1
- package/lib/vendor/blamejs/lib/cache-status.js +3 -7
- package/lib/vendor/blamejs/lib/calendar.js +21 -1
- package/lib/vendor/blamejs/lib/cbor.js +12 -1
- package/lib/vendor/blamejs/lib/cert.js +29 -11
- package/lib/vendor/blamejs/lib/cli.js +94 -24
- package/lib/vendor/blamejs/lib/cloud-events.js +2 -2
- package/lib/vendor/blamejs/lib/cluster-provider-db.js +13 -3
- package/lib/vendor/blamejs/lib/codepoint-class.js +85 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act-prohibited.js +8 -4
- package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +19 -4
- package/lib/vendor/blamejs/lib/compliance-ai-act.js +6 -8
- package/lib/vendor/blamejs/lib/content-credentials.js +1 -1
- package/lib/vendor/blamejs/lib/content-digest.js +2 -1
- package/lib/vendor/blamejs/lib/cookies.js +13 -3
- package/lib/vendor/blamejs/lib/cose.js +31 -16
- package/lib/vendor/blamejs/lib/crypto-field.js +32 -0
- package/lib/vendor/blamejs/lib/crypto-oprf.js +11 -2
- package/lib/vendor/blamejs/lib/crypto-xwing.js +22 -4
- package/lib/vendor/blamejs/lib/crypto.js +314 -19
- package/lib/vendor/blamejs/lib/csp.js +11 -3
- package/lib/vendor/blamejs/lib/daemon.js +270 -24
- package/lib/vendor/blamejs/lib/dark-patterns.js +5 -2
- package/lib/vendor/blamejs/lib/db-declare-view.js +2 -2
- package/lib/vendor/blamejs/lib/db-query.js +34 -7
- package/lib/vendor/blamejs/lib/db.js +18 -6
- package/lib/vendor/blamejs/lib/dbsc.js +17 -0
- package/lib/vendor/blamejs/lib/dev.js +21 -2
- package/lib/vendor/blamejs/lib/dsr.js +157 -102
- package/lib/vendor/blamejs/lib/external-db.js +41 -2
- package/lib/vendor/blamejs/lib/file-upload.js +25 -7
- package/lib/vendor/blamejs/lib/flag-providers.js +27 -15
- package/lib/vendor/blamejs/lib/forms.js +113 -27
- package/lib/vendor/blamejs/lib/gate-contract.js +23 -10
- package/lib/vendor/blamejs/lib/gdpr-ropa.js +8 -1
- package/lib/vendor/blamejs/lib/guard-agent-registry.js +1 -1
- package/lib/vendor/blamejs/lib/guard-archive.js +2 -2
- package/lib/vendor/blamejs/lib/guard-cidr.js +27 -1
- package/lib/vendor/blamejs/lib/guard-graphql.js +30 -11
- package/lib/vendor/blamejs/lib/guard-html.js +26 -53
- package/lib/vendor/blamejs/lib/guard-image.js +24 -5
- package/lib/vendor/blamejs/lib/guard-imap-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-jmap.js +19 -3
- package/lib/vendor/blamejs/lib/guard-jwt.js +18 -2
- package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -2
- package/lib/vendor/blamejs/lib/guard-managesieve-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-markdown.js +11 -24
- package/lib/vendor/blamejs/lib/guard-pdf.js +18 -2
- package/lib/vendor/blamejs/lib/guard-pop3-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-regex.js +8 -5
- package/lib/vendor/blamejs/lib/guard-svg.js +31 -32
- package/lib/vendor/blamejs/lib/guard-time.js +1 -1
- package/lib/vendor/blamejs/lib/guard-uuid.js +2 -2
- package/lib/vendor/blamejs/lib/html-balance.js +3 -3
- package/lib/vendor/blamejs/lib/http-client-cache.js +82 -4
- package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +16 -1
- package/lib/vendor/blamejs/lib/http-client.js +39 -7
- package/lib/vendor/blamejs/lib/http-message-signature.js +35 -1
- package/lib/vendor/blamejs/lib/i18n-messageformat.js +31 -6
- package/lib/vendor/blamejs/lib/i18n.js +35 -21
- package/lib/vendor/blamejs/lib/incident-report.js +8 -1
- package/lib/vendor/blamejs/lib/ip-utils.js +11 -1
- package/lib/vendor/blamejs/lib/json-path.js +23 -1
- package/lib/vendor/blamejs/lib/jwk.js +20 -3
- package/lib/vendor/blamejs/lib/link-header.js +2 -1
- package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +5 -1
- package/lib/vendor/blamejs/lib/log-stream-otlp.js +5 -1
- package/lib/vendor/blamejs/lib/log-stream.js +8 -3
- package/lib/vendor/blamejs/lib/mail-auth.js +123 -22
- package/lib/vendor/blamejs/lib/mail-bimi.js +1 -1
- package/lib/vendor/blamejs/lib/mail-bounce.js +8 -0
- package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +46 -10
- package/lib/vendor/blamejs/lib/mail-dav.js +22 -3
- package/lib/vendor/blamejs/lib/mail-dkim.js +96 -30
- package/lib/vendor/blamejs/lib/mail-helo.js +6 -1
- package/lib/vendor/blamejs/lib/mail-scan.js +23 -16
- package/lib/vendor/blamejs/lib/mail-send-deliver.js +34 -8
- package/lib/vendor/blamejs/lib/mail-server-imap.js +3 -4
- package/lib/vendor/blamejs/lib/mail-server-managesieve.js +7 -11
- package/lib/vendor/blamejs/lib/mail-server-mx.js +93 -7
- package/lib/vendor/blamejs/lib/mail-server-registry.js +8 -2
- package/lib/vendor/blamejs/lib/mail.js +15 -5
- package/lib/vendor/blamejs/lib/metrics.js +268 -63
- package/lib/vendor/blamejs/lib/middleware/age-gate.js +7 -1
- package/lib/vendor/blamejs/lib/middleware/asyncapi-serve.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/body-parser.js +19 -4
- package/lib/vendor/blamejs/lib/middleware/bot-guard.js +5 -9
- package/lib/vendor/blamejs/lib/middleware/csp-report.js +40 -8
- package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +24 -10
- package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -5
- package/lib/vendor/blamejs/lib/middleware/index.js +6 -1
- package/lib/vendor/blamejs/lib/middleware/nel.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/openapi-serve.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/rate-limit.js +12 -1
- package/lib/vendor/blamejs/lib/middleware/require-bound-key.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/scim-server.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/tus-upload.js +6 -2
- package/lib/vendor/blamejs/lib/mtls-ca.js +18 -2
- package/lib/vendor/blamejs/lib/network-dns-resolver.js +11 -1
- package/lib/vendor/blamejs/lib/network-dns.js +21 -2
- package/lib/vendor/blamejs/lib/network-tls.js +69 -7
- package/lib/vendor/blamejs/lib/nonce-store.js +9 -1
- package/lib/vendor/blamejs/lib/object-store/gcs.js +7 -0
- package/lib/vendor/blamejs/lib/object-store/sigv4.js +31 -0
- package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +1 -1
- package/lib/vendor/blamejs/lib/outbox.js +1 -1
- package/lib/vendor/blamejs/lib/parsers/safe-ini.js +9 -1
- package/lib/vendor/blamejs/lib/parsers/safe-toml.js +10 -1
- package/lib/vendor/blamejs/lib/permissions.js +6 -3
- package/lib/vendor/blamejs/lib/pid-probe.js +55 -0
- package/lib/vendor/blamejs/lib/pqc-agent.js +8 -1
- package/lib/vendor/blamejs/lib/pqc-software.js +3 -3
- package/lib/vendor/blamejs/lib/pubsub.js +20 -9
- package/lib/vendor/blamejs/lib/queue-local.js +8 -1
- package/lib/vendor/blamejs/lib/queue-redis.js +5 -0
- package/lib/vendor/blamejs/lib/redact.js +54 -0
- package/lib/vendor/blamejs/lib/restore-bundle.js +10 -2
- package/lib/vendor/blamejs/lib/restore.js +19 -0
- package/lib/vendor/blamejs/lib/retention.js +12 -4
- package/lib/vendor/blamejs/lib/router.js +60 -6
- package/lib/vendor/blamejs/lib/safe-buffer.js +69 -0
- package/lib/vendor/blamejs/lib/safe-decompress.js +8 -2
- package/lib/vendor/blamejs/lib/safe-dns.js +25 -20
- package/lib/vendor/blamejs/lib/safe-ical.js +7 -3
- package/lib/vendor/blamejs/lib/safe-mime.js +12 -1
- package/lib/vendor/blamejs/lib/safe-object.js +80 -0
- package/lib/vendor/blamejs/lib/safe-path.js +52 -4
- package/lib/vendor/blamejs/lib/safe-redirect.js +10 -2
- package/lib/vendor/blamejs/lib/safe-schema.js +4 -1
- package/lib/vendor/blamejs/lib/safe-sieve.js +33 -1
- package/lib/vendor/blamejs/lib/safe-sql.js +88 -0
- package/lib/vendor/blamejs/lib/safe-vcard.js +7 -3
- package/lib/vendor/blamejs/lib/scheduler.js +8 -1
- package/lib/vendor/blamejs/lib/security-assert.js +6 -6
- package/lib/vendor/blamejs/lib/self-update-standalone-verifier.js +74 -27
- package/lib/vendor/blamejs/lib/self-update.js +517 -87
- package/lib/vendor/blamejs/lib/server-timing.js +2 -4
- package/lib/vendor/blamejs/lib/session.js +34 -12
- package/lib/vendor/blamejs/lib/sql.js +15 -1
- package/lib/vendor/blamejs/lib/ssrf-guard.js +52 -0
- package/lib/vendor/blamejs/lib/static.js +55 -13
- package/lib/vendor/blamejs/lib/storage.js +8 -2
- package/lib/vendor/blamejs/lib/subject.js +6 -1
- package/lib/vendor/blamejs/lib/tenant-quota.js +52 -13
- package/lib/vendor/blamejs/lib/tls-exporter.js +3 -3
- package/lib/vendor/blamejs/lib/tsa.js +34 -13
- package/lib/vendor/blamejs/lib/uri-template.js +8 -1
- package/lib/vendor/blamejs/lib/vault/index.js +13 -0
- package/lib/vendor/blamejs/lib/vc.js +44 -5
- package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +26 -26
- package/lib/vendor/blamejs/lib/vendor/noble-ciphers.cjs +792 -1
- package/lib/vendor/blamejs/lib/vendor/noble-curves.cjs +3443 -1
- package/lib/vendor/blamejs/lib/vendor/noble-post-quantum.cjs +2737 -1
- package/lib/vendor/blamejs/lib/vendor/pki.cjs +39550 -13
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.dat +55 -53
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.data.js +5551 -5554
- package/lib/vendor/blamejs/lib/vendor/simplewebauthn-server.cjs +22459 -32
- package/lib/vendor/blamejs/lib/watcher.js +89 -17
- package/lib/vendor/blamejs/lib/webhook-dispatcher.js +25 -3
- package/lib/vendor/blamejs/lib/webhook.js +12 -2
- package/lib/vendor/blamejs/lib/ws-client.js +32 -1
- package/lib/vendor/blamejs/lib/xml-c14n.js +29 -1
- package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/Dockerfile +1 -1
- package/lib/vendor/blamejs/package-lock.json +2 -2
- package/lib/vendor/blamejs/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.16.x.json +1462 -0
- package/lib/vendor/blamejs/release-notes/v0.17.0.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.1.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.10.json +30 -0
- package/lib/vendor/blamejs/release-notes/v0.17.11.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.17.12.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.13.json +77 -0
- package/lib/vendor/blamejs/release-notes/v0.17.14.json +40 -0
- package/lib/vendor/blamejs/release-notes/v0.17.15.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.16.json +27 -0
- package/lib/vendor/blamejs/release-notes/v0.17.17.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.18.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.19.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.2.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.20.json +43 -0
- package/lib/vendor/blamejs/release-notes/v0.17.21.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.22.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.3.json +43 -0
- package/lib/vendor/blamejs/release-notes/v0.17.4.json +35 -0
- package/lib/vendor/blamejs/release-notes/v0.17.5.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.6.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.7.json +35 -0
- package/lib/vendor/blamejs/release-notes/v0.17.8.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.17.9.json +26 -0
- package/lib/vendor/blamejs/scripts/validate-source-comment-blocks.js +4 -0
- package/lib/vendor/blamejs/scripts/vendor-update.sh +293 -9
- package/lib/vendor/blamejs/socket.yml +94 -0
- package/lib/vendor/blamejs/test/00-primitives.js +605 -0
- package/lib/vendor/blamejs/test/helpers/drivers.js +12 -9
- package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +90 -1
- package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +122 -1
- package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +30 -0
- package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +29 -0
- package/lib/vendor/blamejs/test/integration/dsr-cluster-mysql.test.js +479 -0
- package/lib/vendor/blamejs/test/integration/dsr-cluster-pg.test.js +487 -0
- package/lib/vendor/blamejs/test/integration/federation-auth.test.js +313 -5
- package/lib/vendor/blamejs/test/integration/mail-dkim.test.js +80 -0
- package/lib/vendor/blamejs/test/integration/openid-federation-chain.test.js +275 -0
- package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +96 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/a2a-tasks.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/acme.test.js +1649 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/age-gate.test.js +33 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-idempotency.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-saga.test.js +60 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-snapshot.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/api-encrypt.test.js +891 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/app-shutdown.test.js +128 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-adapters.test.js +271 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-read.test.js +628 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-tar-read.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-wrap.test.js +227 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/arg-parser.test.js +15 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/asn1-der.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file.test.js +114 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +141 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-tools.test.js +624 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit.test.js +769 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-jwt-defenses.test.js +436 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth.test.js +1697 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oid4vp.test.js +495 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-password.test.js +500 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml.test.js +1809 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-status-list.test.js +243 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-index.test.js +2226 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-manifest-signature.test.js +183 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/base32.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +693 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cache.test.js +603 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/calendar.test.js +557 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/case-insensitive-security-token-guard.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cbor.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cert.test.js +843 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba-authreqid-binding.test.js +77 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba.test.js +866 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/clear-site-data.test.js +18 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-erase.test.js +19 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli.test.js +2790 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cluster-lease-renewal-ttl.test.js +114 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cluster.test.js +1032 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cms-codec.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +739 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +8 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-ai-act.test.js +194 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-lifecycle-proto-key.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +254 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials.test.js +613 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/cookies.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cose.test.js +407 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-adversarial.test.js +352 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-files-parallel.test.js +10 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +24 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-oprf.test.js +17 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-spki-pin.test.js +183 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-xwing.test.js +48 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto.test.js +345 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csp-report.test.js +58 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csv.test.js +48 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +459 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/dark-patterns.test.js +19 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query.test.js +1019 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db.test.js +1621 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ddl-change-control.test.js +462 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/dnssec.test.js +323 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-verify.test.js +562 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +901 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/dual-control.test.js +249 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +561 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db.test.js +1214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fal.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fedcm-dbsc.test.js +46 -20
- package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +147 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/fido-mds3.test.js +907 -38
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload.test.js +1135 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/forms.test.js +747 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract.test.js +1855 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gdpr-ropa.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-archive.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-auth.test.js +117 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-cidr.test.js +151 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-domain.test.js +422 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +424 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{guard-gate-disposition-coverage.test.js → guard-gate-disposition.test.js} +1 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-graphql.test.js +340 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-idempotency-key.test.js +28 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +519 -45
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jmap.test.js +51 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jsonpath.test.js +66 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jwt.test.js +436 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +16 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mime.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-oauth.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-regex.test.js +99 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-shell.test.js +76 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{guard-sql-coverage.test.js → guard-sql.test.js} +3 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-template.test.js +71 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-time.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-uuid.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/html-balance.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache-authorization.test.js +347 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache.test.js +908 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client.test.js +2874 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-message-signature.test.js +643 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n-messageformat.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +1153 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +494 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jsdoc-example-execution.test.js +177 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-path.test.js +103 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-schema.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwk.test.js +41 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwt-external.test.js +276 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log-stream.test.js +241 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log.test.js +106 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-agent.test.js +441 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +2136 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bimi.test.js +759 -12
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bounce.test.js +811 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp-experimental.test.js +401 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp.test.js +751 -8
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-smime.test.js +864 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dav.test.js +830 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy.test.js +635 -86
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +818 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-helo.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-scan.test.js +199 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-send-deliver.test.js +686 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-imap.test.js +778 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +1438 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-managesieve.test.js +449 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +773 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-pop3.test.js +623 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-rate-limit.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-registry.test.js +13 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-submission.test.js +877 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-sieve.test.js +326 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store-fts.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +242 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail.test.js +1596 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp.test.js +440 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-snapshot.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics.test.js +1230 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-assetlinks.test.js +113 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-body-parser.test.js +1169 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-bot-disclose.test.js +123 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-cookies.test.js +108 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-gpc.test.js +121 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-headers.test.js +163 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-host-allowlist.test.js +154 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-require-content-type.test.js +127 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{middleware-tus-upload-coverage.test.js → middleware-tus-upload.test.js} +45 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-web-app-manifest.test.js +132 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-crl-fingerprint-only.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns-resolver.test.js +65 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns.test.js +1727 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/network-nts.test.js +699 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy.test.js +1181 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-tls.test.js +1876 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/network.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-enforce-replay-nonboolean.test.js +81 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ntp-check.test.js +122 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability-tracing.test.js +378 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/oid4vci.test.js +1016 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/openid-federation.test.js +946 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/outbox.test.js +818 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/own-property-membership-guards.test.js +109 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-safe-toml.test.js +543 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{parsers-safe-yaml-coverage.test.js → parsers-safe-yaml.test.js} +2 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/passkey.test.js +649 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/permissions.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +22 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pubsub.test.js +295 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-flow-repeat.test.js +36 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-xff-spoofing.test.js +34 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redact.test.js +1031 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/require-bound-key.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/restore-empty-manifest-wipe.test.js +154 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/retention.test.js +600 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-host-path-injection.test.js +231 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-tls0rtt.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router.test.js +1277 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-async.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +14 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-decompress.test.js +28 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-dns.test.js +245 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ical.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ini.test.js +376 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-json.test.js +175 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-mime.test.js +518 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-object.test.js +62 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-path.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-schema.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-sql.test.js +142 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-url.test.js +112 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-vcard.test.js +26 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scheduler.test.js +157 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scim-server.test.js +396 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +930 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-assert.test.js +755 -82
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +1053 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +200 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-strict-binding-missing-failclosed.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +636 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql-offset-without-limit.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +1190 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +850 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage-presigned-url.test.js +146 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage.test.js +621 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/subject.test.js +47 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/template.test.js +582 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tenant-quota.test.js +587 -25
- package/lib/vendor/blamejs/test/layer-0-primitives/time.test.js +11 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tsa.test.js +524 -63
- package/lib/vendor/blamejs/test/layer-0-primitives/uri-template.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault-rotate.test.js +866 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault.test.js +74 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vc.test.js +215 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/watcher.test.js +550 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +388 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +262 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/websocket.test.js +1294 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +629 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/xml-c14n-attr-normalization.test.js +164 -0
- package/lib/vendor/blamejs/test/smoke.js +2 -0
- package/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.16.0.json +0 -44
- package/lib/vendor/blamejs/release-notes/v0.16.1.json +0 -36
- package/lib/vendor/blamejs/release-notes/v0.16.2.json +0 -71
- package/lib/vendor/blamejs/release-notes/v0.16.3.json +0 -71
- package/lib/vendor/blamejs/test/layer-0-primitives/acme-coverage.test.js +0 -441
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth-coverage.test.js +0 -482
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml-coverage.test.js +0 -671
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-index-coverage.test.js +0 -690
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-coverage.test.js +0 -238
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials-coverage.test.js +0 -319
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain-coverage.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth-coverage.test.js +0 -437
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp-coverage.test.js +0 -443
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-coverage.test.js +0 -395
- package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy-coverage.test.js +0 -565
- package/lib/vendor/blamejs/test/layer-0-primitives/router-coverage.test.js +0 -592
- package/lib/vendor/blamejs/test/layer-0-primitives/sql-coverage.test.js +0 -422
- package/lib/vendor/blamejs/test/layer-0-primitives/test-coverage.test.js +0 -573
|
@@ -156,11 +156,62 @@ function testCompliancePosture() {
|
|
|
156
156
|
check("posture: unknown → null", b.guardJmap.compliancePosture("nope") === null);
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
+
function testCapabilityPrototypeKeyBypass() {
|
|
160
|
+
// A `using` capability whose name is a JS prototype-key (constructor /
|
|
161
|
+
// __proto__ / toString / ...) is NOT advertised by the server and MUST
|
|
162
|
+
// be refused as unknownCapability. Pre-fix the allowlist test read
|
|
163
|
+
// `serverCaps[cap]` by bracket access, so an inherited Object.prototype
|
|
164
|
+
// member resolved truthy and the attacker-supplied bogus capability
|
|
165
|
+
// passed the gate — a fail-open in the RFC 8620 §3.6.1 capability
|
|
166
|
+
// allowlist driven entirely by the request body.
|
|
167
|
+
var protoKeys = ["constructor", "__proto__", "toString", "valueOf",
|
|
168
|
+
"hasOwnProperty", "isPrototypeOf", "toLocaleString", "propertyIsEnumerable"];
|
|
169
|
+
for (var i = 0; i < protoKeys.length; i += 1) {
|
|
170
|
+
var threw = null;
|
|
171
|
+
try {
|
|
172
|
+
b.guardJmap.validate({
|
|
173
|
+
using: [protoKeys[i]],
|
|
174
|
+
methodCalls: [["Core/echo", {}, "c0"]],
|
|
175
|
+
}, { serverCapabilities: { "urn:ietf:params:jmap:mail": true } });
|
|
176
|
+
} catch (e) { threw = e; }
|
|
177
|
+
check("prototype-key capability '" + protoKeys[i] + "' refused as unknownCapability",
|
|
178
|
+
threw && threw.code === "urn:ietf:params:jmap:error:unknownCapability");
|
|
179
|
+
}
|
|
180
|
+
// An operator that explicitly disables a capability (own key, falsy
|
|
181
|
+
// value) still refuses it — presence alone is not advertisement.
|
|
182
|
+
var threwDisabled = null;
|
|
183
|
+
try {
|
|
184
|
+
b.guardJmap.validate({
|
|
185
|
+
using: ["urn:ietf:params:jmap:mail"],
|
|
186
|
+
methodCalls: [["Mailbox/get", {}, "c0"]],
|
|
187
|
+
}, { serverCapabilities: { "urn:ietf:params:jmap:mail": false } });
|
|
188
|
+
} catch (e) { threwDisabled = e; }
|
|
189
|
+
check("explicitly-disabled capability (own key, falsy) refused",
|
|
190
|
+
threwDisabled && threwDisabled.code === "urn:ietf:params:jmap:error:unknownCapability");
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function testProfilePrototypeKeyRefused() {
|
|
194
|
+
// A profile / posture name that collides with a JS prototype-key must
|
|
195
|
+
// resolve to bad-profile, never silently disable the request caps
|
|
196
|
+
// (PROFILES["constructor"] would otherwise be the inherited Object
|
|
197
|
+
// function — truthy — so `if (!caps)` never fired and every size /
|
|
198
|
+
// count cap was bypassed).
|
|
199
|
+
["constructor", "__proto__", "toString", "valueOf", "hasOwnProperty"].forEach(function (k) {
|
|
200
|
+
var threw = null;
|
|
201
|
+
try { b.guardJmap.validate({ using: [], methodCalls: [["x", {}, "c0"]] }, { profile: k }); }
|
|
202
|
+
catch (e) { threw = e; }
|
|
203
|
+
check("profile '" + k + "' refused as bad-profile",
|
|
204
|
+
threw && threw.code === "guard-jmap/bad-profile");
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
159
208
|
function run() {
|
|
160
209
|
testSurface();
|
|
161
210
|
testHappyPath();
|
|
162
211
|
testBadShapeRefused();
|
|
163
212
|
testUnknownCapabilityRefused();
|
|
213
|
+
testCapabilityPrototypeKeyBypass();
|
|
214
|
+
testProfilePrototypeKeyRefused();
|
|
164
215
|
testCapsTripped();
|
|
165
216
|
testBackRefDepth();
|
|
166
217
|
testServerCapsNotMutated();
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) blamejs contributors
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
var helpers = require("../helpers");
|
|
6
|
+
var b = helpers.b;
|
|
7
|
+
var check = helpers.check;
|
|
8
|
+
|
|
9
|
+
function expectThrows(label, fn, codeMatch) {
|
|
10
|
+
var threw = null;
|
|
11
|
+
try { fn(); } catch (e) { threw = e; }
|
|
12
|
+
check(label, !!threw && (threw.code || "") === codeMatch);
|
|
13
|
+
return threw;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function testSanitize() {
|
|
17
|
+
// Benign: a plain RFC 9535 member/wildcard path carries no code-
|
|
18
|
+
// execution shape — sanitize returns it byte-for-byte (JSONPath
|
|
19
|
+
// strings can't be repaired, so the transform is pass-through).
|
|
20
|
+
var safe = b.guardJsonpath.sanitize("$.users[*].name", { profile: "strict" });
|
|
21
|
+
check("guardJsonpath.sanitize benign passthrough", safe === "$.users[*].name");
|
|
22
|
+
check("guardJsonpath.sanitize benign type", typeof safe === "string");
|
|
23
|
+
|
|
24
|
+
// Hostile: `?(...)` filter expression — the dynamic-code-execution
|
|
25
|
+
// class in legacy JSONPath evaluators. Refused at every profile;
|
|
26
|
+
// never returned as a "cleaned" string.
|
|
27
|
+
var filterErr = expectThrows("guardJsonpath.sanitize filter-expression throws",
|
|
28
|
+
function () { b.guardJsonpath.sanitize("$..[?(@.x)]", { profile: "strict" }); },
|
|
29
|
+
"jsonpath.filter-expression");
|
|
30
|
+
check("guardJsonpath.sanitize filter GuardJsonpathError",
|
|
31
|
+
filterErr instanceof b.guardJsonpath.GuardJsonpathError);
|
|
32
|
+
|
|
33
|
+
// Hostile: JS-source hint (dynamic-code-exec keyword) embedded in the
|
|
34
|
+
// path — refused as a code-injection attempt.
|
|
35
|
+
expectThrows("guardJsonpath.sanitize dynamic-hint throws",
|
|
36
|
+
function () { b.guardJsonpath.sanitize("$[eval]", { profile: "strict" }); },
|
|
37
|
+
"jsonpath.dynamic-hint");
|
|
38
|
+
|
|
39
|
+
// Hostile: bare script-expression shape `(@.x)` — aliased to filter
|
|
40
|
+
// in several implementations; refused under strict.
|
|
41
|
+
expectThrows("guardJsonpath.sanitize script-expression throws",
|
|
42
|
+
function () { b.guardJsonpath.sanitize("$[(@.length-1)]", { profile: "strict" }); },
|
|
43
|
+
"jsonpath.script-expression");
|
|
44
|
+
|
|
45
|
+
// Hostile: 3+ consecutive `[` — parser-DoS shape, high under strict.
|
|
46
|
+
expectThrows("guardJsonpath.sanitize bracket-nesting throws",
|
|
47
|
+
function () { b.guardJsonpath.sanitize("$[[[0]]]", { profile: "strict" }); },
|
|
48
|
+
"jsonpath.bracket-nesting");
|
|
49
|
+
|
|
50
|
+
// The RCE class is refused regardless of profile — a permissive
|
|
51
|
+
// caller can loosen recursive-descent depth but never the filter/
|
|
52
|
+
// script/dynamic-hint refusal.
|
|
53
|
+
expectThrows("guardJsonpath.sanitize filter refused at permissive too",
|
|
54
|
+
function () { b.guardJsonpath.sanitize("$..[?(@.x)]", { profile: "permissive" }); },
|
|
55
|
+
"jsonpath.filter-expression");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function run() {
|
|
59
|
+
testSanitize();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = { run: run };
|
|
63
|
+
if (require.main === module) {
|
|
64
|
+
run().then(function () { console.log("OK"); })
|
|
65
|
+
.catch(function (e) { console.error(e); process.exit(1); });
|
|
66
|
+
}
|
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) blamejs contributors
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
var helpers = require("../helpers");
|
|
6
|
+
var b = helpers.b;
|
|
7
|
+
var check = helpers.check;
|
|
8
|
+
|
|
9
|
+
// base64url encode (no padding) — the JWT compact-serialization segment
|
|
10
|
+
// encoding. Kept local so every fixture token is built in-process from a
|
|
11
|
+
// plain object; no network, no vendored codec dependency.
|
|
12
|
+
function b64url(str) {
|
|
13
|
+
return Buffer.from(str, "utf8").toString("base64")
|
|
14
|
+
.replace(/=+$/, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Assemble a compact-serialization token from a header object, a payload
|
|
18
|
+
// (object OR a pre-encoded segment string — passing a string lets a test
|
|
19
|
+
// smuggle a non-object / undecodable payload past JSON.stringify), and an
|
|
20
|
+
// optional signature segment.
|
|
21
|
+
function mkTok(header, payload, sig) {
|
|
22
|
+
var h = b64url(JSON.stringify(header));
|
|
23
|
+
var p = typeof payload === "string" ? payload : b64url(JSON.stringify(payload));
|
|
24
|
+
return h + "." + p + "." + (sig === undefined ? "sig" : sig);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var OK_HEADER = { alg: "ES256", typ: "JWT" };
|
|
28
|
+
var OK_PAYLOAD = { iss: "example", exp: 9999999999, iat: 1700000000 };
|
|
29
|
+
|
|
30
|
+
// Minimal ES256 token — valid JSON header/payload, required claims
|
|
31
|
+
// present, far-future exp. The "sig" segment is a placeholder; the
|
|
32
|
+
// guard is the shape/header/claims contract, not a signature verifier.
|
|
33
|
+
var BENIGN_JWT =
|
|
34
|
+
"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9." +
|
|
35
|
+
"eyJpc3MiOiJleGFtcGxlIiwiZXhwIjo5OTk5OTk5OTk5LCJpYXQiOjE3MDAwMDAwMDB9." +
|
|
36
|
+
"sig";
|
|
37
|
+
|
|
38
|
+
// alg=none — RFC 7518 §3.6 explicit-no-signature; the canonical
|
|
39
|
+
// CVE-2015-9235 / CVE-2018-0114 algorithm-confusion refuse class.
|
|
40
|
+
var ALG_NONE_JWT =
|
|
41
|
+
"eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0." +
|
|
42
|
+
"eyJzdWIiOiJhdHRhY2tlciJ9.";
|
|
43
|
+
|
|
44
|
+
function expectThrows(label, fn, codeMatch) {
|
|
45
|
+
var threw = null;
|
|
46
|
+
try { fn(); } catch (e) { threw = e; }
|
|
47
|
+
check(label, !!threw && (threw.code || "") === codeMatch);
|
|
48
|
+
return threw;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function hasIssue(rv, ruleId) {
|
|
52
|
+
return rv.issues.some(function (i) { return i.ruleId === ruleId; });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function testKidSafe() {
|
|
56
|
+
// Benign: a plain keystore identifier survives unchanged.
|
|
57
|
+
var ok = b.guardJwt.kidSafe("tenant-1-2026-05");
|
|
58
|
+
check("guardJwt.kidSafe benign passthrough", ok === "tenant-1-2026-05");
|
|
59
|
+
|
|
60
|
+
// Hostile: dot-dot path traversal — the operator keyResolver could
|
|
61
|
+
// otherwise read outside the keystore directory.
|
|
62
|
+
var trav = expectThrows("guardJwt.kidSafe rejects ../ traversal",
|
|
63
|
+
function () { b.guardJwt.kidSafe("../../etc/passwd"); },
|
|
64
|
+
"jwt.kid-traversal");
|
|
65
|
+
check("guardJwt.kidSafe traversal GuardJwtError",
|
|
66
|
+
trav instanceof b.guardJwt.GuardJwtError);
|
|
67
|
+
|
|
68
|
+
// Hostile: forward slash / backslash separators and percent-encoded
|
|
69
|
+
// variants are each refused as traversal indicators.
|
|
70
|
+
expectThrows("guardJwt.kidSafe rejects embedded ../",
|
|
71
|
+
function () { b.guardJwt.kidSafe("keys/../secret"); },
|
|
72
|
+
"jwt.kid-traversal");
|
|
73
|
+
expectThrows("guardJwt.kidSafe rejects backslash separator",
|
|
74
|
+
function () { b.guardJwt.kidSafe("keys\\secret"); },
|
|
75
|
+
"jwt.kid-traversal");
|
|
76
|
+
expectThrows("guardJwt.kidSafe rejects percent-encoded dot-dot",
|
|
77
|
+
function () { b.guardJwt.kidSafe("%2e%2e/keys"); },
|
|
78
|
+
"jwt.kid-traversal");
|
|
79
|
+
expectThrows("guardJwt.kidSafe rejects percent-encoded slash",
|
|
80
|
+
function () { b.guardJwt.kidSafe("id%2fx"); },
|
|
81
|
+
"jwt.kid-traversal");
|
|
82
|
+
|
|
83
|
+
// Empty / non-string kid is a config-time refusal.
|
|
84
|
+
expectThrows("guardJwt.kidSafe rejects empty string",
|
|
85
|
+
function () { b.guardJwt.kidSafe(""); },
|
|
86
|
+
"jwt.kid-empty");
|
|
87
|
+
expectThrows("guardJwt.kidSafe rejects non-string",
|
|
88
|
+
function () { b.guardJwt.kidSafe(1234); },
|
|
89
|
+
"jwt.kid-empty");
|
|
90
|
+
|
|
91
|
+
// Control byte in the kid — non-printable smuggling refuse.
|
|
92
|
+
expectThrows("guardJwt.kidSafe rejects control byte",
|
|
93
|
+
function () { b.guardJwt.kidSafe("bad\x00ctl"); },
|
|
94
|
+
"jwt.kid-control");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function testSanitize() {
|
|
98
|
+
// Benign: a well-formed ES256 token with required claims passes
|
|
99
|
+
// through unchanged (compact serialization can't be repaired).
|
|
100
|
+
var safe = b.guardJwt.sanitize(BENIGN_JWT, { profile: "strict" });
|
|
101
|
+
check("guardJwt.sanitize benign passthrough", safe === BENIGN_JWT);
|
|
102
|
+
|
|
103
|
+
// Hostile: alg=none — critical, refused at every profile. sanitize
|
|
104
|
+
// throws rather than returning a "cleaned" token.
|
|
105
|
+
var noneErr = expectThrows("guardJwt.sanitize rejects alg=none",
|
|
106
|
+
function () { b.guardJwt.sanitize(ALG_NONE_JWT, { profile: "strict" }); },
|
|
107
|
+
"jwt.alg-none");
|
|
108
|
+
check("guardJwt.sanitize alg-none GuardJwtError",
|
|
109
|
+
noneErr instanceof b.guardJwt.GuardJwtError);
|
|
110
|
+
|
|
111
|
+
// alg=none is universal — even permissive, which loosens the alg
|
|
112
|
+
// allowlist entirely, still refuses the explicit-no-signature class.
|
|
113
|
+
expectThrows("guardJwt.sanitize rejects alg=none at permissive too",
|
|
114
|
+
function () { b.guardJwt.sanitize(ALG_NONE_JWT, { profile: "permissive" }); },
|
|
115
|
+
"jwt.alg-none");
|
|
116
|
+
|
|
117
|
+
// Hostile: not JWT compact-serialization shape — refused as jwt-shape.
|
|
118
|
+
expectThrows("guardJwt.sanitize rejects non-JWT shape",
|
|
119
|
+
function () { b.guardJwt.sanitize("not-a-jwt", { profile: "strict" }); },
|
|
120
|
+
"jwt.jwt-shape");
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function testValidateAlgNone() {
|
|
124
|
+
// validate is the non-throwing sibling — confirm the alg=none refuse
|
|
125
|
+
// surfaces in the issue list with ok=false, matching sanitize's throw.
|
|
126
|
+
var rv = b.guardJwt.validate(ALG_NONE_JWT, { profile: "strict" });
|
|
127
|
+
check("guardJwt.validate alg=none ok=false", rv.ok === false);
|
|
128
|
+
check("guardJwt.validate alg-none kind present",
|
|
129
|
+
rv.issues.some(function (i) { return i.kind === "alg-none"; }));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ---- payload-decode fail-open (root: an undecodable / non-object payload
|
|
133
|
+
// silently skipped the required-claims + exp/nbf/iat sanity checks,
|
|
134
|
+
// so a token missing every required claim passed at strict — the
|
|
135
|
+
// asymmetric sibling of the header-decode path, which DOES refuse) ----
|
|
136
|
+
|
|
137
|
+
function testValidatePayloadDecode() {
|
|
138
|
+
// Sibling that IS handled: an undecodable HEADER surfaces header-decode
|
|
139
|
+
// and fails the token. The payload path below must behave the same.
|
|
140
|
+
var badHdr = b.guardJwt.validate("qqqq." + b64url(JSON.stringify(OK_PAYLOAD)) +
|
|
141
|
+
".sig", { profile: "strict" });
|
|
142
|
+
check("validate: undecodable header -> header-decode (control)",
|
|
143
|
+
badHdr.ok === false && hasIssue(badHdr, "jwt.header-decode"));
|
|
144
|
+
|
|
145
|
+
// A JSON-STRING payload is not a claims object — required-claims and
|
|
146
|
+
// exp/nbf/iat sanity have nothing to check. It must refuse, not pass.
|
|
147
|
+
var strPay = mkTok(OK_HEADER, b64url(JSON.stringify("attacker")));
|
|
148
|
+
var rStr = b.guardJwt.validate(strPay, { profile: "strict" });
|
|
149
|
+
check("validate: json-string payload -> ok=false", rStr.ok === false);
|
|
150
|
+
check("validate: json-string payload -> payload-decode",
|
|
151
|
+
hasIssue(rStr, "jwt.payload-decode"));
|
|
152
|
+
|
|
153
|
+
// A JSON-NUMBER payload — same non-object class.
|
|
154
|
+
var numPay = mkTok(OK_HEADER, b64url("12345"));
|
|
155
|
+
var rNum = b.guardJwt.validate(numPay, { profile: "strict" });
|
|
156
|
+
check("validate: json-number payload -> ok=false + payload-decode",
|
|
157
|
+
rNum.ok === false && hasIssue(rNum, "jwt.payload-decode"));
|
|
158
|
+
|
|
159
|
+
// An UNDECODABLE payload (valid base64url, non-JSON bytes) — the required
|
|
160
|
+
// claims definitionally can't be present, so it must fail fast.
|
|
161
|
+
var undec = mkTok(OK_HEADER, "qqqq");
|
|
162
|
+
var rUn = b.guardJwt.validate(undec, { profile: "strict" });
|
|
163
|
+
check("validate: undecodable payload -> ok=false + payload-decode",
|
|
164
|
+
rUn.ok === false && hasIssue(rUn, "jwt.payload-decode"));
|
|
165
|
+
|
|
166
|
+
// A JSON-ARRAY payload is not a valid claims set (RFC 7519 §7.2 requires
|
|
167
|
+
// a JSON object). Refused at EVERY profile, including permissive where
|
|
168
|
+
// requiredClaims is empty — otherwise an array payload passes untouched.
|
|
169
|
+
var arrPay = mkTok(OK_HEADER, b64url("[1,2,3]"));
|
|
170
|
+
var rArrStrict = b.guardJwt.validate(arrPay, { profile: "strict" });
|
|
171
|
+
check("validate: array payload strict -> ok=false + payload-decode",
|
|
172
|
+
rArrStrict.ok === false && hasIssue(rArrStrict, "jwt.payload-decode"));
|
|
173
|
+
var rArrPerm = b.guardJwt.validate(arrPay, { profile: "permissive" });
|
|
174
|
+
check("validate: array payload permissive -> ok=false + payload-decode",
|
|
175
|
+
rArrPerm.ok === false && hasIssue(rArrPerm, "jwt.payload-decode"));
|
|
176
|
+
|
|
177
|
+
// Regression floor: a real object payload with required claims still
|
|
178
|
+
// passes — the fix must not over-reject a well-formed claims set.
|
|
179
|
+
var okObj = b.guardJwt.validate(mkTok(OK_HEADER, OK_PAYLOAD), { profile: "strict" });
|
|
180
|
+
check("validate: object payload with claims still passes",
|
|
181
|
+
okObj.ok === true && okObj.issues.length === 0);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function testSanitizePayloadDecode() {
|
|
185
|
+
// sanitize is the throwing sibling — a non-object payload throws
|
|
186
|
+
// jwt.payload-decode rather than returning the token as "clean".
|
|
187
|
+
var strPay = mkTok(OK_HEADER, b64url(JSON.stringify("attacker")));
|
|
188
|
+
var err = expectThrows("sanitize: json-string payload throws payload-decode",
|
|
189
|
+
function () { b.guardJwt.sanitize(strPay, { profile: "strict" }); },
|
|
190
|
+
"jwt.payload-decode");
|
|
191
|
+
check("sanitize payload-decode GuardJwtError",
|
|
192
|
+
err instanceof b.guardJwt.GuardJwtError);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async function testGatePayloadDecode() {
|
|
196
|
+
// The shipped consumer path: b.guardJwt.gate().check(ctx). A token whose
|
|
197
|
+
// payload is a JSON string (missing every required claim at strict) must
|
|
198
|
+
// NOT be served.
|
|
199
|
+
var g = b.guardJwt.gate({ profile: "strict" });
|
|
200
|
+
try {
|
|
201
|
+
var strPay = mkTok(OK_HEADER, b64url(JSON.stringify("attacker")));
|
|
202
|
+
var d = await g.check({ jwt: strPay });
|
|
203
|
+
check("gate: non-object payload -> action !== serve", d.action !== "serve");
|
|
204
|
+
check("gate: non-object payload -> ok=false", d.ok === false);
|
|
205
|
+
} finally {
|
|
206
|
+
await g.close();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// ---- broad branch coverage for the detector ----
|
|
211
|
+
|
|
212
|
+
function testValidateAlgAllowlist() {
|
|
213
|
+
var hs = mkTok({ alg: "HS256", typ: "JWT" }, OK_PAYLOAD);
|
|
214
|
+
|
|
215
|
+
// strict: alg-not-allowed is high -> ok=false. This is the HS256-against-
|
|
216
|
+
// RSA-public-key forgery class blocked before the verifier.
|
|
217
|
+
var rStrict = b.guardJwt.validate(hs, { profile: "strict" });
|
|
218
|
+
check("alg-not-allowed strict -> ok=false high",
|
|
219
|
+
rStrict.ok === false &&
|
|
220
|
+
rStrict.issues.some(function (i) {
|
|
221
|
+
return i.ruleId === "jwt.alg-not-allowed" && i.severity === "high";
|
|
222
|
+
}));
|
|
223
|
+
|
|
224
|
+
// balanced: audit -> warn severity, ok stays true (surfaced, not refused).
|
|
225
|
+
var rBal = b.guardJwt.validate(hs, { profile: "balanced" });
|
|
226
|
+
check("alg-not-allowed balanced -> ok=true warn",
|
|
227
|
+
rBal.ok === true &&
|
|
228
|
+
rBal.issues.some(function (i) {
|
|
229
|
+
return i.ruleId === "jwt.alg-not-allowed" && i.severity === "warn";
|
|
230
|
+
}));
|
|
231
|
+
|
|
232
|
+
// permissive: allowlist off -> no alg-not-allowed issue at all.
|
|
233
|
+
var rPerm = b.guardJwt.validate(hs, { profile: "permissive" });
|
|
234
|
+
check("alg-not-allowed permissive -> not flagged",
|
|
235
|
+
rPerm.ok === true && !hasIssue(rPerm, "jwt.alg-not-allowed"));
|
|
236
|
+
|
|
237
|
+
// Operator allowlist override — add HS256 and it passes strict.
|
|
238
|
+
var rOverride = b.guardJwt.validate(hs, {
|
|
239
|
+
profile: "strict", allowedAlgs: ["HS256"],
|
|
240
|
+
});
|
|
241
|
+
check("alg allowlist override admits HS256",
|
|
242
|
+
!hasIssue(rOverride, "jwt.alg-not-allowed"));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function testValidateTypConfusion() {
|
|
246
|
+
var tok = mkTok({ alg: "ES256", typ: "evil" }, OK_PAYLOAD);
|
|
247
|
+
var rStrict = b.guardJwt.validate(tok, { profile: "strict" });
|
|
248
|
+
check("typ-confusion strict -> ok=false high",
|
|
249
|
+
rStrict.ok === false && hasIssue(rStrict, "jwt.typ-confusion"));
|
|
250
|
+
var rBal = b.guardJwt.validate(tok, { profile: "balanced" });
|
|
251
|
+
check("typ-confusion balanced -> audit warn, ok=true",
|
|
252
|
+
rBal.ok === true &&
|
|
253
|
+
rBal.issues.some(function (i) {
|
|
254
|
+
return i.ruleId === "jwt.typ-confusion" && i.severity === "warn";
|
|
255
|
+
}));
|
|
256
|
+
// Known JWT media-type is not flagged.
|
|
257
|
+
var okTyp = b.guardJwt.validate(mkTok({ alg: "ES256", typ: "at+jwt" }, OK_PAYLOAD),
|
|
258
|
+
{ profile: "strict" });
|
|
259
|
+
check("typ at+jwt not flagged", !hasIssue(okTyp, "jwt.typ-confusion"));
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function testValidateCritUnknown() {
|
|
263
|
+
var tok = mkTok({ alg: "ES256", typ: "JWT", crit: ["b64"] }, OK_PAYLOAD);
|
|
264
|
+
// Unknown crit is refused at every profile (RFC 7515 §4.1.11).
|
|
265
|
+
var rStrict = b.guardJwt.validate(tok, { profile: "strict" });
|
|
266
|
+
check("crit-unknown strict -> ok=false",
|
|
267
|
+
rStrict.ok === false && hasIssue(rStrict, "jwt.crit-unknown"));
|
|
268
|
+
var rPerm = b.guardJwt.validate(tok, { profile: "permissive" });
|
|
269
|
+
check("crit-unknown permissive -> ok=false (refused every profile)",
|
|
270
|
+
rPerm.ok === false && hasIssue(rPerm, "jwt.crit-unknown"));
|
|
271
|
+
// Opt a crit name into knownCrit and it is accepted.
|
|
272
|
+
var rKnown = b.guardJwt.validate(tok, { profile: "strict", knownCrit: ["b64"] });
|
|
273
|
+
check("crit in knownCrit allowlist -> not flagged",
|
|
274
|
+
!hasIssue(rKnown, "jwt.crit-unknown"));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function testValidateClaimSanity() {
|
|
278
|
+
var now = Math.floor(Date.now() / 1000);
|
|
279
|
+
|
|
280
|
+
// exp in the past — replay / expired-token detection.
|
|
281
|
+
var expPast = b.guardJwt.validate(
|
|
282
|
+
mkTok(OK_HEADER, { iss: "ex", exp: 1, iat: 1 }), { profile: "strict" });
|
|
283
|
+
check("exp-past -> ok=false", expPast.ok === false && hasIssue(expPast, "jwt.exp-past"));
|
|
284
|
+
|
|
285
|
+
// nbf far in the future (> strict 5-min slack) — clock-skew / not-yet-valid.
|
|
286
|
+
var nbfFar = b.guardJwt.validate(
|
|
287
|
+
mkTok(OK_HEADER, { iss: "ex", exp: 9999999999, iat: now, nbf: now + 86400 }),
|
|
288
|
+
{ profile: "strict" });
|
|
289
|
+
check("nbf-far-future -> ok=false",
|
|
290
|
+
nbfFar.ok === false && hasIssue(nbfFar, "jwt.nbf-far-future"));
|
|
291
|
+
|
|
292
|
+
// iat far in the future — issued-in-the-future is suspect.
|
|
293
|
+
var iatFar = b.guardJwt.validate(
|
|
294
|
+
mkTok(OK_HEADER, { iss: "ex", exp: 9999999999, iat: now + 86400 }),
|
|
295
|
+
{ profile: "strict" });
|
|
296
|
+
check("iat-far-future -> ok=false",
|
|
297
|
+
iatFar.ok === false && hasIssue(iatFar, "jwt.iat-far-future"));
|
|
298
|
+
|
|
299
|
+
// nbf within slack is NOT flagged.
|
|
300
|
+
var nbfOk = b.guardJwt.validate(
|
|
301
|
+
mkTok(OK_HEADER, { iss: "ex", exp: 9999999999, iat: now, nbf: now + 60 }),
|
|
302
|
+
{ profile: "strict" });
|
|
303
|
+
check("nbf within slack not flagged", !hasIssue(nbfOk, "jwt.nbf-far-future"));
|
|
304
|
+
|
|
305
|
+
// Missing required claim — strict requires iss/exp/iat; an empty object
|
|
306
|
+
// payload flags every one.
|
|
307
|
+
var missing = b.guardJwt.validate(mkTok(OK_HEADER, {}), { profile: "strict" });
|
|
308
|
+
check("claim-missing -> ok=false", missing.ok === false && hasIssue(missing, "jwt.claim-missing"));
|
|
309
|
+
var missingCount = missing.issues.filter(function (i) {
|
|
310
|
+
return i.ruleId === "jwt.claim-missing";
|
|
311
|
+
}).length;
|
|
312
|
+
check("claim-missing flags all three strict required claims", missingCount === 3);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function testValidateKidTraversalHeader() {
|
|
316
|
+
var tok = mkTok({ alg: "ES256", typ: "JWT", kid: "../../etc/passwd" }, OK_PAYLOAD);
|
|
317
|
+
var rv = b.guardJwt.validate(tok, { profile: "strict" });
|
|
318
|
+
check("header kid traversal -> critical, ok=false",
|
|
319
|
+
rv.ok === false &&
|
|
320
|
+
rv.issues.some(function (i) {
|
|
321
|
+
return i.ruleId === "jwt.kid-traversal" && i.severity === "critical";
|
|
322
|
+
}));
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function testValidateSegmentCaps() {
|
|
326
|
+
// header segment over maxHeaderBytes (strict 2 KiB).
|
|
327
|
+
var bigHdr = mkTok({ alg: "ES256", typ: "JWT", kid: "A".repeat(3000) }, OK_PAYLOAD);
|
|
328
|
+
var rHc = b.guardJwt.validate(bigHdr, { profile: "strict" });
|
|
329
|
+
check("header-cap -> ok=false", rHc.ok === false && hasIssue(rHc, "jwt.header-cap"));
|
|
330
|
+
|
|
331
|
+
// signature segment over maxSignatureBytes (strict 4 KiB).
|
|
332
|
+
var rSc = b.guardJwt.validate(
|
|
333
|
+
mkTok(OK_HEADER, OK_PAYLOAD, "s".repeat(5000)), { profile: "strict" });
|
|
334
|
+
check("signature-cap -> ok=false", rSc.ok === false && hasIssue(rSc, "jwt.signature-cap"));
|
|
335
|
+
|
|
336
|
+
// total token over maxBytes (strict 16 KiB) — refused before segment parse.
|
|
337
|
+
var rTc = b.guardJwt.validate(
|
|
338
|
+
mkTok(OK_HEADER, OK_PAYLOAD, "s".repeat(17000)), { profile: "strict" });
|
|
339
|
+
check("jwt-cap (total) -> ok=false", rTc.ok === false && hasIssue(rTc, "jwt.jwt-cap"));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function testValidateInputContract() {
|
|
343
|
+
// Non-string input is bad-input, not a thrown TypeError.
|
|
344
|
+
var rNon = b.guardJwt.validate(12345, { profile: "strict" });
|
|
345
|
+
check("non-string input -> bad-input high",
|
|
346
|
+
rNon.ok === false && hasIssue(rNon, "jwt.bad-input"));
|
|
347
|
+
// Empty string is refused.
|
|
348
|
+
var rEmpty = b.guardJwt.validate("", { profile: "strict" });
|
|
349
|
+
check("empty input -> empty issue",
|
|
350
|
+
rEmpty.ok === false && hasIssue(rEmpty, "jwt.empty"));
|
|
351
|
+
// Not JWT compact shape.
|
|
352
|
+
var rShape = b.guardJwt.validate("not-a-jwt", { profile: "strict" });
|
|
353
|
+
check("non-JWT shape -> jwt-shape",
|
|
354
|
+
rShape.ok === false && hasIssue(rShape, "jwt.jwt-shape"));
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function testValidateCharThreats() {
|
|
358
|
+
// A raw NUL byte in the compact string is a universal-refuse codepoint
|
|
359
|
+
// class BEFORE any base64url decode — trojan-source can't ride inside.
|
|
360
|
+
var tok = mkTok(OK_HEADER, OK_PAYLOAD);
|
|
361
|
+
var withNul = tok.slice(0, 5) + "\x00" + tok.slice(5);
|
|
362
|
+
var rv = b.guardJwt.validate(withNul, { profile: "strict" });
|
|
363
|
+
check("raw NUL byte -> ok=false null-byte",
|
|
364
|
+
rv.ok === false && hasIssue(rv, "jwt.null-byte"));
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function testValidateBadOpts() {
|
|
368
|
+
// A negative maxBytes is a config-time throw (entry-point tier).
|
|
369
|
+
expectThrows("negative maxBytes throws jwt.bad-opt",
|
|
370
|
+
function () { b.guardJwt.validate(BENIGN_JWT, { profile: "strict", maxBytes: -5 }); },
|
|
371
|
+
"jwt.bad-opt");
|
|
372
|
+
// Non-integer slack window is a config-time throw.
|
|
373
|
+
expectThrows("non-int nbfFutureSlackMs throws jwt.bad-opt",
|
|
374
|
+
function () { b.guardJwt.validate(BENIGN_JWT, { profile: "strict", nbfFutureSlackMs: 1.5 }); },
|
|
375
|
+
"jwt.bad-opt");
|
|
376
|
+
// Unknown profile / posture are config-time throws.
|
|
377
|
+
expectThrows("unknown profile throws jwt.bad-profile",
|
|
378
|
+
function () { b.guardJwt.validate(BENIGN_JWT, { profile: "nope" }); },
|
|
379
|
+
"jwt.bad-profile");
|
|
380
|
+
expectThrows("unknown compliancePosture throws jwt.bad-posture",
|
|
381
|
+
function () { b.guardJwt.validate(BENIGN_JWT, { compliancePosture: "nope" }); },
|
|
382
|
+
"jwt.bad-posture");
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function testCompliancePosture() {
|
|
386
|
+
// A benign token passes under a mapped posture (hipaa) — the posture
|
|
387
|
+
// overlay tightens caps/policies but does not reject a well-formed token.
|
|
388
|
+
var rv = b.guardJwt.validate(BENIGN_JWT, { profile: "strict", compliancePosture: "hipaa" });
|
|
389
|
+
check("hipaa posture admits benign token", rv.ok === true);
|
|
390
|
+
// The guard advertises the four postures via compliancePosture().
|
|
391
|
+
var hipaa = b.guardJwt.compliancePosture("hipaa");
|
|
392
|
+
check("compliancePosture(hipaa) resolves", !!hipaa && typeof hipaa === "object");
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
async function testGate() {
|
|
396
|
+
var g = b.guardJwt.gate({ profile: "strict" });
|
|
397
|
+
try {
|
|
398
|
+
var clean = await g.check({ identifier: BENIGN_JWT });
|
|
399
|
+
check("gate: benign token -> serve", clean.ok === true && clean.action === "serve");
|
|
400
|
+
|
|
401
|
+
var none = await g.check({ token: ALG_NONE_JWT });
|
|
402
|
+
check("gate: alg=none -> action !== serve", none.action !== "serve");
|
|
403
|
+
|
|
404
|
+
// No token in ctx -> nothing to guard -> serve.
|
|
405
|
+
var empty = await g.check({});
|
|
406
|
+
check("gate: no identifier field -> serve", empty.action === "serve");
|
|
407
|
+
} finally {
|
|
408
|
+
await g.close();
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
async function run() {
|
|
413
|
+
testKidSafe();
|
|
414
|
+
testSanitize();
|
|
415
|
+
testValidateAlgNone();
|
|
416
|
+
testValidatePayloadDecode();
|
|
417
|
+
testSanitizePayloadDecode();
|
|
418
|
+
await testGatePayloadDecode();
|
|
419
|
+
testValidateAlgAllowlist();
|
|
420
|
+
testValidateTypConfusion();
|
|
421
|
+
testValidateCritUnknown();
|
|
422
|
+
testValidateClaimSanity();
|
|
423
|
+
testValidateKidTraversalHeader();
|
|
424
|
+
testValidateSegmentCaps();
|
|
425
|
+
testValidateInputContract();
|
|
426
|
+
testValidateCharThreats();
|
|
427
|
+
testValidateBadOpts();
|
|
428
|
+
testCompliancePosture();
|
|
429
|
+
await testGate();
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
module.exports = { run: run };
|
|
433
|
+
if (require.main === module) {
|
|
434
|
+
run().then(function () { console.log("OK"); })
|
|
435
|
+
.catch(function (e) { console.error(e); process.exit(1); });
|
|
436
|
+
}
|
|
@@ -289,6 +289,30 @@ function testByteCapMultibyte() {
|
|
|
289
289
|
threw && threw.code === "guard-managesieve-command/line-too-long");
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
+
function testProfilePrototypeKeyRefused() {
|
|
293
|
+
// A profile name that collides with a JS prototype-key must resolve to
|
|
294
|
+
// bad-profile, never silently disable the caps. Pre-fix the resolver
|
|
295
|
+
// read PROFILES[profileName] by bracket access, so PROFILES["constructor"]
|
|
296
|
+
// was the inherited Object function — truthy — and `if (!caps)` never
|
|
297
|
+
// fired; the line / script / script-name caps then compared against
|
|
298
|
+
// `undefined` (always false) and failed open.
|
|
299
|
+
var protoKeys = ["constructor", "__proto__", "toString", "valueOf", "hasOwnProperty"];
|
|
300
|
+
for (var i = 0; i < protoKeys.length; i += 1) {
|
|
301
|
+
var threw = null;
|
|
302
|
+
try { guardManageSieveCommand.validate("CAPABILITY", { profile: protoKeys[i] }); }
|
|
303
|
+
catch (e) { threw = e; }
|
|
304
|
+
check("profile '" + protoKeys[i] + "' refused as bad-profile",
|
|
305
|
+
threw && threw.code === "guard-managesieve-command/bad-profile");
|
|
306
|
+
}
|
|
307
|
+
// Concrete fail-open proof: a PUTSCRIPT literal past the strict 64 KiB
|
|
308
|
+
// cap must NOT be accepted under a prototype-key profile.
|
|
309
|
+
var threwLit = null;
|
|
310
|
+
try { guardManageSieveCommand.validate('PUTSCRIPT "x" {99999999}', { profile: "constructor" }); }
|
|
311
|
+
catch (e) { threwLit = e; }
|
|
312
|
+
check("prototype-key profile does not fail open on the script cap",
|
|
313
|
+
threwLit && threwLit.code === "guard-managesieve-command/bad-profile");
|
|
314
|
+
}
|
|
315
|
+
|
|
292
316
|
function run() {
|
|
293
317
|
testByteCapMultibyte();
|
|
294
318
|
testBSurface();
|
|
@@ -298,6 +322,7 @@ function run() {
|
|
|
298
322
|
testScriptNameShape();
|
|
299
323
|
testLiteralShapeAndCaps();
|
|
300
324
|
testBadInputRefused();
|
|
325
|
+
testProfilePrototypeKeyRefused();
|
|
301
326
|
testCompliancePosture();
|
|
302
327
|
}
|
|
303
328
|
|
|
@@ -70,6 +70,22 @@ function testGuardMarkdownEntityBypass() {
|
|
|
70
70
|
"[x](javascript:alert(1))\n", { profile: "strict" });
|
|
71
71
|
check("decimal-entity javascript: scheme detected",
|
|
72
72
|
rvDec.issues.some(function (i) { return i.kind === "link-scheme"; }));
|
|
73
|
+
|
|
74
|
+
// Named entities + entity-encoded leading space: a browser resolves 	 /
|
|
75
|
+
// 
 and trims a leading C0-control-or-space run before parsing the URL,
|
|
76
|
+
// so `java	script:` and ` javascript:` navigate as javascript:. Decoding
|
|
77
|
+
// numeric-only, or not trimming the entity space, let these bypass -> fail-open.
|
|
78
|
+
var mdWs = [
|
|
79
|
+
["named 	", "[x](java	script:alert(1))"],
|
|
80
|
+
["named 
", "[x](java
script:alert(1))"],
|
|
81
|
+
["entity space  ", "[x]( javascript:alert(1))"],
|
|
82
|
+
["entity space  ", "[x]( javascript:alert(1))"],
|
|
83
|
+
];
|
|
84
|
+
for (var w = 0; w < mdWs.length; w++) {
|
|
85
|
+
var rvW = b.guardMarkdown.validate(mdWs[w][1], { profile: "strict" });
|
|
86
|
+
check("markdown whitespace/entity-hidden scheme (" + mdWs[w][0] + ") detected",
|
|
87
|
+
rvW.issues.some(function (i) { return i.kind === "link-scheme"; }));
|
|
88
|
+
}
|
|
73
89
|
}
|
|
74
90
|
|
|
75
91
|
function testGuardMarkdownAutolinkScheme() {
|