@blamejs/blamejs-shop 0.5.12 → 0.5.13
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 +2 -0
- package/lib/asset-manifest.json +1 -1
- 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
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) blamejs contributors
|
|
3
|
+
"use strict";
|
|
4
|
+
/**
|
|
5
|
+
* @module b.safeObject
|
|
6
|
+
* @nav Validation
|
|
7
|
+
* @title Safe object access
|
|
8
|
+
* @order 100
|
|
9
|
+
*
|
|
10
|
+
* @intro
|
|
11
|
+
* Prototype-pollution-safe own-property access. Interpolators, template
|
|
12
|
+
* engines, and structured readers that look up a key by name on an
|
|
13
|
+
* attacker-influenced object must treat an inherited / prototype-chain key
|
|
14
|
+
* (`__proto__`, `constructor`, `toString`) as ABSENT — never read it into
|
|
15
|
+
* rendered output. This composes that guard into one primitive so every
|
|
16
|
+
* consumer routes through the same hardened read instead of hand-rolling
|
|
17
|
+
* `Object.prototype.hasOwnProperty.call(o, k) ? o[k] : undefined` (which a
|
|
18
|
+
* `__proto__` accessor property can still defeat).
|
|
19
|
+
*
|
|
20
|
+
* @card
|
|
21
|
+
* Prototype-pollution-safe own-property get/set — the single guard every
|
|
22
|
+
* interpolator composes.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @primitive b.safeObject.ownProp
|
|
27
|
+
* @signature b.safeObject.ownProp(obj, key)
|
|
28
|
+
* @since 0.17.13
|
|
29
|
+
* @status stable
|
|
30
|
+
* @related b.safeObject.ownSet
|
|
31
|
+
*
|
|
32
|
+
* Returns the value of `obj`'s OWN property `key`, or `undefined` when `key`
|
|
33
|
+
* is not an own property (inherited / prototype-chain keys read as absent).
|
|
34
|
+
* Uses `Object.getOwnPropertyDescriptor` rather than `hasOwnProperty` + index
|
|
35
|
+
* read, so a `__proto__`-injected accessor property cannot run on read. A
|
|
36
|
+
* defined-but-`undefined` own value returns `undefined` (callers treat that as
|
|
37
|
+
* absent, matching the prior guarded reads).
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* b.safeObject.ownProp({ a: 1 }, "a"); // → 1
|
|
41
|
+
* b.safeObject.ownProp({}, "toString"); // → undefined (inherited)
|
|
42
|
+
* b.safeObject.ownProp({}, "__proto__"); // → undefined
|
|
43
|
+
*/
|
|
44
|
+
function ownProp(obj, key) {
|
|
45
|
+
if (obj === null || obj === undefined) return undefined;
|
|
46
|
+
var d = Object.getOwnPropertyDescriptor(obj, key);
|
|
47
|
+
return d ? d.value : undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @primitive b.safeObject.ownSet
|
|
52
|
+
* @signature b.safeObject.ownSet(obj, key, value)
|
|
53
|
+
* @since 0.17.13
|
|
54
|
+
* @status stable
|
|
55
|
+
* @related b.safeObject.ownProp
|
|
56
|
+
*
|
|
57
|
+
* Sets `obj[key] = value` as a plain own data property via
|
|
58
|
+
* `Object.defineProperty`, so a `__proto__` / `constructor` / accessor key on
|
|
59
|
+
* the prototype chain cannot intercept the write or pollute the prototype.
|
|
60
|
+
* Returns `obj`.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* var o = {};
|
|
64
|
+
* b.safeObject.ownSet(o, "__proto__", { polluted: 1 });
|
|
65
|
+
* ({}).polluted; // → undefined (Object.prototype not touched)
|
|
66
|
+
*/
|
|
67
|
+
function ownSet(obj, key, value) {
|
|
68
|
+
Object.defineProperty(obj, key, {
|
|
69
|
+
value: value,
|
|
70
|
+
writable: true,
|
|
71
|
+
enumerable: true,
|
|
72
|
+
configurable: true,
|
|
73
|
+
});
|
|
74
|
+
return obj;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = {
|
|
78
|
+
ownProp: ownProp,
|
|
79
|
+
ownSet: ownSet,
|
|
80
|
+
};
|
|
@@ -138,6 +138,53 @@ function validate(base, rel, opts) {
|
|
|
138
138
|
catch (e) { return { ok: false, code: e.code || "safe-path/unknown", message: e.message }; }
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
/**
|
|
142
|
+
* @primitive b.safePath.confineToBase
|
|
143
|
+
* @signature b.safePath.confineToBase(base, rel, opts?)
|
|
144
|
+
* @since 0.17.16
|
|
145
|
+
* @status stable
|
|
146
|
+
* @related b.safePath.resolve, b.staticServe.create
|
|
147
|
+
*
|
|
148
|
+
* The lexical traversal-containment core, WITHOUT the user-input
|
|
149
|
+
* strictness of `resolve` (no reserved-name / ADS / bidi / control-char
|
|
150
|
+
* refusal). Resolve `rel` against `base` using the TARGET platform's path
|
|
151
|
+
* semantics and confirm the result stays strictly inside `base`; return
|
|
152
|
+
* the confined absolute path, or `null` if it escapes.
|
|
153
|
+
*
|
|
154
|
+
* This is the barrier `resolve` layers its user-input checks on top of,
|
|
155
|
+
* and the one a consumer composes when it wants ONLY traversal containment
|
|
156
|
+
* and runs its OWN, separately-calibrated filename validation — as
|
|
157
|
+
* b.staticServe does, keeping its per-file basename gate (b.guardFilename)
|
|
158
|
+
* a distinct step rather than fusing `resolve`'s all-segment user-input
|
|
159
|
+
* strictness into the containment barrier.
|
|
160
|
+
*
|
|
161
|
+
* @opts
|
|
162
|
+
* platform: string, // "windows" forces win32 path semantics regardless of host
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* var p = b.safePath.confineToBase("/srv/www", "docs/a.html");
|
|
166
|
+
* // → "/srv/www/docs/a.html" (null if rel escaped /srv/www)
|
|
167
|
+
*/
|
|
168
|
+
function confineToBase(base, rel, opts) {
|
|
169
|
+
opts = opts || {};
|
|
170
|
+
if (typeof base !== "string" || base.length === 0) return null;
|
|
171
|
+
if (typeof rel !== "string") return null;
|
|
172
|
+
var platform = opts.platform || process.platform;
|
|
173
|
+
var isWin = platform === "win32" || platform === "windows";
|
|
174
|
+
// Resolve + contain using the TARGET platform's path module, NOT the
|
|
175
|
+
// runtime's: the runtime path module would treat the OTHER platform's
|
|
176
|
+
// separator as an ordinary filename character and miss a backslash
|
|
177
|
+
// traversal on a POSIX host (and inversely false-refuse legitimate paths).
|
|
178
|
+
var pathMod = isWin ? nodePath.win32 : nodePath.posix;
|
|
179
|
+
var baseResolved = pathMod.resolve(base);
|
|
180
|
+
var joined = pathMod.resolve(baseResolved, rel);
|
|
181
|
+
var sepChar = pathMod.sep;
|
|
182
|
+
if (joined !== baseResolved && joined.slice(0, baseResolved.length + 1) !== baseResolved + sepChar) {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
return joined;
|
|
186
|
+
}
|
|
187
|
+
|
|
141
188
|
function _resolveCore(base, rel, opts) {
|
|
142
189
|
if (typeof base !== "string" || base.length === 0) {
|
|
143
190
|
_refuse("safe-path/bad-input", "b.safePath.resolve: base must be a non-empty string");
|
|
@@ -219,11 +266,11 @@ function _resolveCore(base, rel, opts) {
|
|
|
219
266
|
// that hole AND stops the inverse false-refusal of legitimate in-base paths.
|
|
220
267
|
var pathMod = isWin ? nodePath.win32 : nodePath.posix;
|
|
221
268
|
var baseResolved = pathMod.resolve(base);
|
|
222
|
-
var joined =
|
|
223
|
-
|
|
224
|
-
if (joined !== baseResolved && joined.slice(0, baseResolved.length + 1) !== baseResolved + sepChar) {
|
|
269
|
+
var joined = confineToBase(base, rel, { platform: platform });
|
|
270
|
+
if (joined === null) {
|
|
225
271
|
_refuse("safe-path/escapes-base",
|
|
226
|
-
"b.safePath.resolve: rel resolves outside base ('" +
|
|
272
|
+
"b.safePath.resolve: rel resolves outside base ('" +
|
|
273
|
+
pathMod.resolve(baseResolved, rel) + "' not inside '" + baseResolved + "')");
|
|
227
274
|
}
|
|
228
275
|
if (opts.realpath === true) {
|
|
229
276
|
// realpath resolves symlinks on the RUNTIME filesystem, so it must use the
|
|
@@ -266,5 +313,6 @@ module.exports = {
|
|
|
266
313
|
resolve: resolve,
|
|
267
314
|
resolveOrNull: resolveOrNull,
|
|
268
315
|
validate: validate,
|
|
316
|
+
confineToBase: confineToBase,
|
|
269
317
|
SafePathError: SafePathError,
|
|
270
318
|
};
|
|
@@ -97,15 +97,23 @@ function resolve(rawTarget, opts) {
|
|
|
97
97
|
try { parsed = safeUrl.parse(rawTarget, { allowedProtocols: safeUrl.ALLOW_HTTP_TLS }); }
|
|
98
98
|
catch (_e) { return fallback; }
|
|
99
99
|
|
|
100
|
+
// parsed.origin / host / hostname come lowercased from the WHATWG URL
|
|
101
|
+
// parser (scheme + host are case-insensitive per RFC 3986). Canonicalize
|
|
102
|
+
// each operator allowlist entry the same way before comparing, so a
|
|
103
|
+
// mixed-case operator entry ("HTTPS://Example.com" / "Example.COM") still
|
|
104
|
+
// matches instead of silently never matching and falling through to the
|
|
105
|
+
// fallback. The attacker-controlled rawTarget is already normalized, so
|
|
106
|
+
// this only makes the operator's intended allowlist work — never widens it.
|
|
100
107
|
if (baseOrigin !== null && parsed.origin === baseOrigin) return rawTarget;
|
|
101
108
|
if (allowedOrigins) {
|
|
102
109
|
for (var i = 0; i < allowedOrigins.length; i += 1) {
|
|
103
|
-
if (parsed.origin === allowedOrigins[i]) return rawTarget;
|
|
110
|
+
if (parsed.origin === String(allowedOrigins[i]).toLowerCase()) return rawTarget;
|
|
104
111
|
}
|
|
105
112
|
}
|
|
106
113
|
if (allowedHosts) {
|
|
107
114
|
for (var j = 0; j < allowedHosts.length; j += 1) {
|
|
108
|
-
|
|
115
|
+
var allowedHost = String(allowedHosts[j]).toLowerCase();
|
|
116
|
+
if (parsed.host === allowedHost || parsed.hostname === allowedHost) {
|
|
109
117
|
return rawTarget;
|
|
110
118
|
}
|
|
111
119
|
}
|
|
@@ -996,8 +996,11 @@ function unknown() { return any(); }
|
|
|
996
996
|
* // → "object/unknown-key"
|
|
997
997
|
*
|
|
998
998
|
* // Prototype-pollution attempt rejected even with passthrough.
|
|
999
|
+
* // A hostile __proto__ only becomes an own key through JSON input;
|
|
1000
|
+
* // object-literal `__proto__:` sets the prototype instead.
|
|
999
1001
|
* var loose = user.passthrough();
|
|
1000
|
-
* var
|
|
1002
|
+
* var hostile = JSON.parse('{ "email": "a@b.com", "age": 30, "__proto__": { "admin": true } }');
|
|
1003
|
+
* var report = loose.safeParse(hostile);
|
|
1001
1004
|
* report.ok;
|
|
1002
1005
|
* // → false
|
|
1003
1006
|
* report.errors[0].code;
|
|
@@ -429,7 +429,39 @@ function _parseScript(tokens, caps, requiredCaps) {
|
|
|
429
429
|
}
|
|
430
430
|
if (t.k === "tag") {
|
|
431
431
|
consume("tag");
|
|
432
|
-
|
|
432
|
+
// `:comparator <string>` binds the FOLLOWING string as its value
|
|
433
|
+
// (RFC 5228 section 2.7.3). It must be attached to the tag, NOT left in
|
|
434
|
+
// the positional stream -- otherwise the comparator name lands at
|
|
435
|
+
// positional[0] and shifts every real positional arg (the header/address
|
|
436
|
+
// name and the key list) by one, silently breaking the test so it never
|
|
437
|
+
// matches and the message falls through to implicit keep (a filter
|
|
438
|
+
// bypass). In the base grammar `:comparator` is the only value-taking tag.
|
|
439
|
+
if (t.v === "comparator") {
|
|
440
|
+
var cv = peek();
|
|
441
|
+
if (cv.k !== "str") {
|
|
442
|
+
throw new SafeSieveError("safe-sieve/parse-error",
|
|
443
|
+
"safeSieve.parse: :comparator must be followed by a comparator-name string");
|
|
444
|
+
}
|
|
445
|
+
consume("str");
|
|
446
|
+
// Validate the comparator name against the implemented set, exactly as
|
|
447
|
+
// `require ["comparator-<name>"]` does -- otherwise an unsupported
|
|
448
|
+
// comparator (e.g. i;unicode-casemap) would be accepted here and the
|
|
449
|
+
// interpreter would silently treat it as octet (exact) matching,
|
|
450
|
+
// bypassing the capability guard. Fail closed on anything not
|
|
451
|
+
// implemented.
|
|
452
|
+
var compCap = "comparator-" + cv.v;
|
|
453
|
+
if (!Object.prototype.hasOwnProperty.call(KNOWN_CAPABILITIES, compCap)) {
|
|
454
|
+
throw new SafeSieveError("safe-sieve/unknown-capability",
|
|
455
|
+
"safeSieve.parse: unknown comparator \"" + cv.v + "\"");
|
|
456
|
+
}
|
|
457
|
+
if (KNOWN_CAPABILITIES[compCap] === false) {
|
|
458
|
+
throw new SafeSieveError("safe-sieve/unimplemented-capability",
|
|
459
|
+
"safeSieve.parse: unimplemented comparator \"" + cv.v + "\"");
|
|
460
|
+
}
|
|
461
|
+
tags.push({ name: t.v, val: cv.v });
|
|
462
|
+
} else {
|
|
463
|
+
tags.push({ name: t.v });
|
|
464
|
+
}
|
|
433
465
|
continue;
|
|
434
466
|
}
|
|
435
467
|
if (t.k === "num") {
|
|
@@ -494,6 +494,93 @@ function toPositional(sql, dialect) {
|
|
|
494
494
|
return out;
|
|
495
495
|
}
|
|
496
496
|
|
|
497
|
+
/**
|
|
498
|
+
* @primitive b.safeSql.normalizeForScan
|
|
499
|
+
* @signature b.safeSql.normalizeForScan(sql)
|
|
500
|
+
* @since 0.17.4
|
|
501
|
+
* @status stable
|
|
502
|
+
* @related b.safeSql.countPlaceholders, b.safeSql.toPositional, b.safeSql.assertSingleStatement
|
|
503
|
+
*
|
|
504
|
+
* Produce a parse-only copy of `sql` whose token boundaries are real
|
|
505
|
+
* whitespace, so a regex tokenizer that assumes whitespace-separated tokens
|
|
506
|
+
* cannot be evaded. SQL lets two tokens abut with NO whitespace whenever a
|
|
507
|
+
* comment OR a quoted-identifier boundary separates them (an `INSERT` whose
|
|
508
|
+
* quoted table name abuts `INTO`, or a slash-star comment wedged between a
|
|
509
|
+
* keyword and the table); a keyword/table detector hand-rolled with `\s+`
|
|
510
|
+
* boundaries silently misses those forms even though the engine executes them.
|
|
511
|
+
* This scan replaces every line (`--`) and slash-star block comment with a
|
|
512
|
+
* single space and inserts a separating space wherever a quoted string /
|
|
513
|
+
* identifier (`'...'` / `"..."` / a backtick-quoted name) abuts a word
|
|
514
|
+
* character on either side — a word char directly before the opening quote OR
|
|
515
|
+
* directly after the closing quote. The same quote- and comment-aware single
|
|
516
|
+
* pass as `countPlaceholders` / `toPositional` (doubled-quote escapes
|
|
517
|
+
* respected), so a comment marker inside a string literal is copied verbatim,
|
|
518
|
+
* never collapsed. The executed SQL is unchanged — this copy only feeds a
|
|
519
|
+
* scanner.
|
|
520
|
+
*
|
|
521
|
+
* @example
|
|
522
|
+
* var b = require("blamejs");
|
|
523
|
+
* b.safeSql.normalizeForScan('INSERT INTO"t"(a) VALUES(?)');
|
|
524
|
+
* // → 'INSERT INTO "t"(a) VALUES(?)'
|
|
525
|
+
*
|
|
526
|
+
* b.safeSql.normalizeForScan('UPDATE"residents"SET x=1');
|
|
527
|
+
* // → 'UPDATE "residents" SET x=1'
|
|
528
|
+
*
|
|
529
|
+
* b.safeSql.normalizeForScan("SELECT 1-- note");
|
|
530
|
+
* // → "SELECT 1 "
|
|
531
|
+
*/
|
|
532
|
+
function normalizeForScan(sql) {
|
|
533
|
+
var s = String(sql);
|
|
534
|
+
var out = "";
|
|
535
|
+
var i = 0;
|
|
536
|
+
var len = s.length;
|
|
537
|
+
while (i < len) {
|
|
538
|
+
var c = s.charAt(i);
|
|
539
|
+
var nx = i + 1 < len ? s.charAt(i + 1) : "";
|
|
540
|
+
if (c === "'" || c === '"' || c === "`") {
|
|
541
|
+
// A quoted token abutting a word character gets a separating space so the
|
|
542
|
+
// downstream whitespace-anchored tokenizer sees the boundary — on BOTH
|
|
543
|
+
// sides: before the opening quote when a word char precedes it
|
|
544
|
+
// (`INTO"t"`), and after the closing quote when a word char follows it
|
|
545
|
+
// (`"t"SET` / `UPDATE"residents"SET`). A quoted identifier separates
|
|
546
|
+
// tokens with no whitespace in either direction, so a one-sided boundary
|
|
547
|
+
// still lets a write hide from the scan. Between, copy the whole quoted
|
|
548
|
+
// run verbatim (doubled-quote escapes preserved) so a comment marker
|
|
549
|
+
// inside the literal is never collapsed.
|
|
550
|
+
if (out.length > 0 && /\w/.test(out.charAt(out.length - 1))) out += " ";
|
|
551
|
+
out += c;
|
|
552
|
+
i += 1;
|
|
553
|
+
while (i < len) {
|
|
554
|
+
var q = s.charAt(i);
|
|
555
|
+
out += q;
|
|
556
|
+
if (q === c) {
|
|
557
|
+
if (s.charAt(i + 1) === c) { out += c; i += 2; continue; }
|
|
558
|
+
i += 1; break;
|
|
559
|
+
}
|
|
560
|
+
i += 1;
|
|
561
|
+
}
|
|
562
|
+
if (i < len && /\w/.test(s.charAt(i))) out += " ";
|
|
563
|
+
continue;
|
|
564
|
+
}
|
|
565
|
+
if (c === "-" && nx === "-") { // line comment → one space
|
|
566
|
+
i += 2;
|
|
567
|
+
while (i < len && s.charAt(i) !== "\n") i += 1;
|
|
568
|
+
out += " ";
|
|
569
|
+
continue;
|
|
570
|
+
}
|
|
571
|
+
if (c === "/" && nx === "*") { // block comment → one space
|
|
572
|
+
i += 2;
|
|
573
|
+
while (i < len && !(s.charAt(i) === "*" && s.charAt(i + 1) === "/")) i += 1;
|
|
574
|
+
i += 2;
|
|
575
|
+
out += " ";
|
|
576
|
+
continue;
|
|
577
|
+
}
|
|
578
|
+
out += c;
|
|
579
|
+
i += 1;
|
|
580
|
+
}
|
|
581
|
+
return out;
|
|
582
|
+
}
|
|
583
|
+
|
|
497
584
|
/**
|
|
498
585
|
* @primitive b.safeSql.DEFAULT_IDENTIFIER_RE
|
|
499
586
|
* @signature b.safeSql.DEFAULT_IDENTIFIER_RE
|
|
@@ -693,6 +780,7 @@ module.exports = {
|
|
|
693
780
|
assertOneOf: assertOneOf,
|
|
694
781
|
countPlaceholders: countPlaceholders,
|
|
695
782
|
toPositional: toPositional,
|
|
783
|
+
normalizeForScan: normalizeForScan,
|
|
696
784
|
SafeSqlError: SafeSqlError,
|
|
697
785
|
// Exposed so consumers can compose their own validators
|
|
698
786
|
DEFAULT_IDENTIFIER_RE: DEFAULT_IDENTIFIER_RE,
|
|
@@ -225,14 +225,18 @@ function _resolveCaps(opts) {
|
|
|
225
225
|
if (typeof opts.profile === "string") {
|
|
226
226
|
name = opts.profile;
|
|
227
227
|
} else if (typeof opts.compliancePosture === "string") {
|
|
228
|
-
name = COMPLIANCE_POSTURES
|
|
228
|
+
name = Object.prototype.hasOwnProperty.call(COMPLIANCE_POSTURES, opts.compliancePosture)
|
|
229
|
+
? COMPLIANCE_POSTURES[opts.compliancePosture] : "strict";
|
|
229
230
|
}
|
|
230
|
-
|
|
231
|
-
if (!
|
|
231
|
+
// Own-property lookup: `name` derives from attacker/operator opts.profile, so
|
|
232
|
+
// a bare `if (!PROFILES[name])` would let a prototype key ("constructor") pass
|
|
233
|
+
// as a known profile and run under an inherited member (fail-open).
|
|
234
|
+
if (!Object.prototype.hasOwnProperty.call(PROFILES, name)) {
|
|
232
235
|
throw new SafeVcardError("safe-vcard/bad-opt",
|
|
233
236
|
"safeVcard.parse: unknown profile '" + name +
|
|
234
237
|
"' (expected strict|balanced|permissive)");
|
|
235
238
|
}
|
|
239
|
+
var caps = PROFILES[name];
|
|
236
240
|
return caps;
|
|
237
241
|
}
|
|
238
242
|
|
|
@@ -135,7 +135,14 @@ function _parseCronField(text, range) {
|
|
|
135
135
|
hi = parseInt(seg[1], 10);
|
|
136
136
|
} else {
|
|
137
137
|
lo = parseInt(part, 10);
|
|
138
|
-
|
|
138
|
+
// A bare number followed by a step (`N/step`) is the Vixie-cron
|
|
139
|
+
// shorthand for `N-max/step` (e.g. `5/15` in minutes = 5,20,35,50,
|
|
140
|
+
// matching crontab.guru and `*/15` = 0,15,30,45). Without a step a
|
|
141
|
+
// bare number is the single value {N}. Anchoring `hi` at range.max
|
|
142
|
+
// when a step is present is what turns the step into a repeat; keeping
|
|
143
|
+
// hi = lo silently collapsed the schedule to a single fire — the same
|
|
144
|
+
// silent-under-firing class rejected for over-range steps above.
|
|
145
|
+
hi = (stepIdx !== -1) ? range.max : lo;
|
|
139
146
|
}
|
|
140
147
|
if (!Number.isFinite(lo) || !Number.isFinite(hi) || lo > hi ||
|
|
141
148
|
lo < range.min || hi > range.max) {
|
|
@@ -340,14 +340,14 @@ async function assertProduction(opts) {
|
|
|
340
340
|
if (opts.extra !== undefined) {
|
|
341
341
|
if (!Array.isArray(opts.extra)) {
|
|
342
342
|
throw new SecurityAssertError(
|
|
343
|
-
"
|
|
344
|
-
"
|
|
343
|
+
"BAD_OPT",
|
|
344
|
+
"security.assertProduction: opts.extra must be an array of functions, got " + typeof opts.extra);
|
|
345
345
|
}
|
|
346
346
|
for (var ei = 0; ei < opts.extra.length; ei++) {
|
|
347
347
|
if (typeof opts.extra[ei] !== "function") {
|
|
348
348
|
throw new SecurityAssertError(
|
|
349
|
-
"
|
|
350
|
-
"
|
|
349
|
+
"BAD_OPT",
|
|
350
|
+
"security.assertProduction: opts.extra[" + ei + "] must be a function");
|
|
351
351
|
}
|
|
352
352
|
var verdict;
|
|
353
353
|
try { verdict = await opts.extra[ei](); }
|
|
@@ -383,8 +383,8 @@ async function assertProduction(opts) {
|
|
|
383
383
|
if (failures.length > 0) {
|
|
384
384
|
var summary = failures.map(function (f) { return " - " + f.code + ": " + f.message; }).join("\n");
|
|
385
385
|
var err = new SecurityAssertError(
|
|
386
|
-
"
|
|
387
|
-
"
|
|
386
|
+
"ASSERT_FAILED",
|
|
387
|
+
"production security policy failed (" + failures.length + " assertion(s)):\n" + summary);
|
|
388
388
|
err.failures = failures;
|
|
389
389
|
throw err;
|
|
390
390
|
}
|
|
@@ -88,6 +88,17 @@
|
|
|
88
88
|
var nodeCrypto = require("node:crypto");
|
|
89
89
|
var nodeFs = require("node:fs");
|
|
90
90
|
|
|
91
|
+
// _svErr — throw shape for this module. A plain Error (zero-dep — no framework
|
|
92
|
+
// error class) carrying a machine-readable `.kind` so a framework caller
|
|
93
|
+
// (b.selfUpdate.verify) can map the failure to its own typed error class
|
|
94
|
+
// without parsing English message text. Operators consuming the module
|
|
95
|
+
// standalone still get the human-readable `.message` unchanged.
|
|
96
|
+
function _svErr(kind, message) {
|
|
97
|
+
var e = new Error(message);
|
|
98
|
+
e.kind = kind;
|
|
99
|
+
return e;
|
|
100
|
+
}
|
|
101
|
+
|
|
91
102
|
// _streamHashAndVerify — read the asset in 64 KiB chunks, feed each
|
|
92
103
|
// chunk into sha256, sha3-512, AND the signature verifier in parallel.
|
|
93
104
|
// Single pass over the file; no in-memory copy. node:crypto's
|
|
@@ -103,18 +114,18 @@ function _detectAlg(pubkeyPem) {
|
|
|
103
114
|
try {
|
|
104
115
|
key = nodeCrypto.createPublicKey(pubkeyPem);
|
|
105
116
|
} catch (e) {
|
|
106
|
-
throw
|
|
117
|
+
throw _svErr("bad-pubkey", "standalone-verifier: pubkey PEM did not parse: " +
|
|
107
118
|
(e && e.message ? e.message : String(e)));
|
|
108
119
|
}
|
|
109
120
|
var t = key.asymmetricKeyType;
|
|
110
121
|
if (t === "ec") {
|
|
111
122
|
var curve = key.asymmetricKeyDetails && key.asymmetricKeyDetails.namedCurve;
|
|
112
123
|
if (curve === "P-384" || curve === "secp384r1") return { alg: "ecdsa-p384", key: key };
|
|
113
|
-
throw
|
|
124
|
+
throw _svErr("unsupported-key", "standalone-verifier: unsupported EC curve '" + curve + "' (need P-384)");
|
|
114
125
|
}
|
|
115
126
|
if (t === "ed25519") return { alg: "ed25519", key: key };
|
|
116
127
|
if (t === "ml-dsa-87" || t === "ml-dsa") return { alg: "ml-dsa-87", key: key };
|
|
117
|
-
throw
|
|
128
|
+
throw _svErr("unsupported-key", "standalone-verifier: unrecognized pubkey type '" + t + "' " +
|
|
118
129
|
"(need ecdsa-p384, ed25519, or ml-dsa-87)");
|
|
119
130
|
}
|
|
120
131
|
|
|
@@ -163,7 +174,7 @@ function _looksLikeDerEcdsa(sig) {
|
|
|
163
174
|
|
|
164
175
|
/**
|
|
165
176
|
* @primitive b.selfUpdate.standaloneVerifier.verify
|
|
166
|
-
* @signature b.selfUpdate.standaloneVerifier.verify(assetPath, signaturePath, pubkeyPem)
|
|
177
|
+
* @signature b.selfUpdate.standaloneVerifier.verify(assetPath, signaturePath, pubkeyPem, opts?)
|
|
167
178
|
* @since 0.9.13
|
|
168
179
|
* @status stable
|
|
169
180
|
* @related b.selfUpdate.verify
|
|
@@ -175,12 +186,21 @@ function _looksLikeDerEcdsa(sig) {
|
|
|
175
186
|
* Streams the asset in 64 KiB chunks through SHA-256 + SHA-3-512 + the
|
|
176
187
|
* signature verifier in parallel — single allocation peak (one buffer
|
|
177
188
|
* sized to fstat(asset).size for Ed25519 / ML-DSA-87, ECDSA P-384 needs
|
|
178
|
-
* no buffer because createVerify is incremental).
|
|
189
|
+
* no buffer because createVerify is incremental). The signature commits
|
|
190
|
+
* to a SHA3-512 digest and the ECDSA encoding is dispatched by structure
|
|
191
|
+
* (DER SEQUENCE vs raw IEEE-P1363), so both encodings of a SHA3-512-signed
|
|
192
|
+
* P-384 sidecar verify.
|
|
179
193
|
*
|
|
180
|
-
* Returns `{ ok, sha3_512, sha256, alg }` on success;
|
|
181
|
-
* unrecognized pubkey shape, missing files, or signature
|
|
182
|
-
* `alg` is one of `"ecdsa-p384"`, `"ed25519"`, `"ml-dsa-87"`
|
|
183
|
-
* detected from the pubkey PEM).
|
|
194
|
+
* Returns `{ ok, sha3_512, sha256, alg, bytes, digests }` on success;
|
|
195
|
+
* throws on unrecognized pubkey shape, missing files, or signature
|
|
196
|
+
* mismatch. `alg` is one of `"ecdsa-p384"`, `"ed25519"`, `"ml-dsa-87"`
|
|
197
|
+
* (auto-detected from the pubkey PEM). `bytes` is the verified asset byte
|
|
198
|
+
* count; `digests` maps each requested `opts.extraDigests` name to its
|
|
199
|
+
* hex digest (computed in the same single pass).
|
|
200
|
+
*
|
|
201
|
+
* @opts
|
|
202
|
+
* maxAssetBytes: number, // asset-size ceiling (default 2 GiB); refuse a larger asset before hashing
|
|
203
|
+
* extraDigests: array, // additional node:crypto digest names to compute in the same stream
|
|
184
204
|
*
|
|
185
205
|
* @example
|
|
186
206
|
* var verifier = require("./standalone-verifier");
|
|
@@ -193,15 +213,26 @@ function _looksLikeDerEcdsa(sig) {
|
|
|
193
213
|
* if (!result.ok) process.exit(1);
|
|
194
214
|
* process.stdout.write("verified " + result.alg + " sha3-512=" + result.sha3_512 + "\n");
|
|
195
215
|
*/
|
|
196
|
-
function verify(assetPath, signaturePath, pubkeyPem) {
|
|
216
|
+
function verify(assetPath, signaturePath, pubkeyPem, opts) {
|
|
217
|
+
opts = opts || {};
|
|
218
|
+
// Asset-size ceiling — override the default via opts.maxAssetBytes (the
|
|
219
|
+
// framework caller passes its own maxBytes). A self-update bundle (SEA) is
|
|
220
|
+
// intentionally large, so the default ceiling is generous (2 GiB), but it
|
|
221
|
+
// stops a signaturePath/assetPath pointed at an unbounded file from OOM-ing.
|
|
222
|
+
var maxAssetBytes = (typeof opts.maxAssetBytes === "number" && isFinite(opts.maxAssetBytes) &&
|
|
223
|
+
opts.maxAssetBytes > 0)
|
|
224
|
+
? opts.maxAssetBytes
|
|
225
|
+
: (2 * 1024 * 1024 * 1024); // allow:raw-byte-literal — zero-dep module, 2 GiB asset ceiling
|
|
226
|
+
var extraDigests = Array.isArray(opts.extraDigests) ? opts.extraDigests : [];
|
|
227
|
+
|
|
197
228
|
if (typeof assetPath !== "string" || assetPath.length === 0) {
|
|
198
|
-
throw
|
|
229
|
+
throw _svErr("bad-input", "standalone-verifier.verify: assetPath must be a non-empty string");
|
|
199
230
|
}
|
|
200
231
|
if (typeof signaturePath !== "string" || signaturePath.length === 0) {
|
|
201
|
-
throw
|
|
232
|
+
throw _svErr("bad-input", "standalone-verifier.verify: signaturePath must be a non-empty string");
|
|
202
233
|
}
|
|
203
234
|
if (typeof pubkeyPem !== "string" || pubkeyPem.indexOf("-----BEGIN ") !== 0) {
|
|
204
|
-
throw
|
|
235
|
+
throw _svErr("bad-input", "standalone-verifier.verify: pubkeyPem must be a PEM-encoded public key string");
|
|
205
236
|
}
|
|
206
237
|
|
|
207
238
|
// Open both files BEFORE parsing the pubkey so we own stable fds
|
|
@@ -212,7 +243,7 @@ function verify(assetPath, signaturePath, pubkeyPem) {
|
|
|
212
243
|
try {
|
|
213
244
|
assetFd = nodeFs.openSync(assetPath, "r");
|
|
214
245
|
} catch (e) {
|
|
215
|
-
throw
|
|
246
|
+
throw _svErr("asset-not-found", "standalone-verifier.verify: asset not found at " + assetPath +
|
|
216
247
|
" — " + (e && e.message ? e.message : String(e)));
|
|
217
248
|
}
|
|
218
249
|
var sigFd;
|
|
@@ -220,7 +251,7 @@ function verify(assetPath, signaturePath, pubkeyPem) {
|
|
|
220
251
|
sigFd = nodeFs.openSync(signaturePath, "r");
|
|
221
252
|
} catch (e) {
|
|
222
253
|
nodeFs.closeSync(assetFd);
|
|
223
|
-
throw
|
|
254
|
+
throw _svErr("sig-not-found", "standalone-verifier.verify: signature not found at " + signaturePath +
|
|
224
255
|
" — " + (e && e.message ? e.message : String(e)));
|
|
225
256
|
}
|
|
226
257
|
var signature;
|
|
@@ -231,7 +262,7 @@ function verify(assetPath, signaturePath, pubkeyPem) {
|
|
|
231
262
|
// from OOM-ing if signaturePath is pointed at a giant file. Zero-dep by
|
|
232
263
|
// contract — inline literal, cannot import C.BYTES.
|
|
233
264
|
if (sigStat.size > 64 * 1024) { // allow:raw-byte-literal — zero-dep module
|
|
234
|
-
throw
|
|
265
|
+
throw _svErr("sig-too-large", "standalone-verifier.verify: signature file implausibly large (" +
|
|
235
266
|
sigStat.size + " bytes)");
|
|
236
267
|
}
|
|
237
268
|
signature = Buffer.allocUnsafe(sigStat.size);
|
|
@@ -241,7 +272,7 @@ function verify(assetPath, signaturePath, pubkeyPem) {
|
|
|
241
272
|
}
|
|
242
273
|
if (signature.length === 0) {
|
|
243
274
|
nodeFs.closeSync(assetFd);
|
|
244
|
-
throw
|
|
275
|
+
throw _svErr("sig-empty", "standalone-verifier.verify: signature file is empty");
|
|
245
276
|
}
|
|
246
277
|
|
|
247
278
|
var detected;
|
|
@@ -249,7 +280,7 @@ function verify(assetPath, signaturePath, pubkeyPem) {
|
|
|
249
280
|
detected = _detectAlg(pubkeyPem);
|
|
250
281
|
} catch (e) {
|
|
251
282
|
nodeFs.closeSync(assetFd);
|
|
252
|
-
throw e;
|
|
283
|
+
throw e; // carries _detectAlg's .kind (bad-pubkey / unsupported-key)
|
|
253
284
|
}
|
|
254
285
|
var alg = detected.alg;
|
|
255
286
|
var key = detected.key;
|
|
@@ -273,15 +304,24 @@ function verify(assetPath, signaturePath, pubkeyPem) {
|
|
|
273
304
|
// time.
|
|
274
305
|
var assetStat = nodeFs.fstatSync(assetFd);
|
|
275
306
|
// Bound the asset alloc before Buffer.allocUnsafe(assetStat.size): a self-update
|
|
276
|
-
// bundle (SEA) is intentionally large, so the ceiling is generous (2 GiB
|
|
277
|
-
// it stops a signaturePath/assetPath
|
|
278
|
-
//
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
307
|
+
// bundle (SEA) is intentionally large, so the ceiling is generous (2 GiB by
|
|
308
|
+
// default, or opts.maxAssetBytes), but it stops a signaturePath/assetPath
|
|
309
|
+
// pointed at an unbounded file from OOM-ing the verifier before any byte is
|
|
310
|
+
// hashed.
|
|
311
|
+
if (assetStat.size > maxAssetBytes) {
|
|
312
|
+
nodeFs.closeSync(assetFd);
|
|
313
|
+
throw _svErr("asset-too-large", "standalone-verifier.verify: asset implausibly large (" +
|
|
314
|
+
assetStat.size + " bytes) — exceeds the " + maxAssetBytes + "-byte asset ceiling");
|
|
282
315
|
}
|
|
283
316
|
var sha256 = nodeCrypto.createHash("sha256");
|
|
284
317
|
var sha3 = nodeCrypto.createHash("sha3-512");
|
|
318
|
+
// Additional operator-requested digests, computed in the same single pass so
|
|
319
|
+
// a framework caller can report an audit digest (sha-512 / shake256 / …)
|
|
320
|
+
// without a second read of the asset.
|
|
321
|
+
var extraHashers = [];
|
|
322
|
+
for (var xd = 0; xd < extraDigests.length; xd += 1) {
|
|
323
|
+
extraHashers.push({ name: extraDigests[xd], hash: nodeCrypto.createHash(extraDigests[xd]) });
|
|
324
|
+
}
|
|
285
325
|
var verifier = (alg === "ecdsa-p384") ? nodeCrypto.createVerify("sha3-512") : null;
|
|
286
326
|
var fullBuf = null;
|
|
287
327
|
var fullOff = 0;
|
|
@@ -305,6 +345,7 @@ function verify(assetPath, signaturePath, pubkeyPem) {
|
|
|
305
345
|
var slice = chunk.subarray(0, n);
|
|
306
346
|
sha256.update(slice);
|
|
307
347
|
sha3.update(slice);
|
|
348
|
+
for (var xh = 0; xh < extraHashers.length; xh += 1) extraHashers[xh].hash.update(slice);
|
|
308
349
|
if (verifier) verifier.update(slice);
|
|
309
350
|
if (fullBuf) {
|
|
310
351
|
slice.copy(fullBuf, fullOff);
|
|
@@ -319,7 +360,7 @@ function verify(assetPath, signaturePath, pubkeyPem) {
|
|
|
319
360
|
// beyond what the clamp let through. Both cases mean the hashers
|
|
320
361
|
// and verifier saw a different byte set than the on-disk file.
|
|
321
362
|
if (fullOff !== assetStat.size) {
|
|
322
|
-
throw
|
|
363
|
+
throw _svErr("size-race", "standalone-verifier.verify: asset '" + assetPath +
|
|
323
364
|
"' changed size during read (expected " + assetStat.size +
|
|
324
365
|
" bytes per fstat, read " + fullOff +
|
|
325
366
|
" bytes) — refusing to return a hash that may not match the on-disk file");
|
|
@@ -327,6 +368,10 @@ function verify(assetPath, signaturePath, pubkeyPem) {
|
|
|
327
368
|
|
|
328
369
|
var sha256Hex = sha256.digest("hex");
|
|
329
370
|
var sha3Hex = sha3.digest("hex");
|
|
371
|
+
var digests = {};
|
|
372
|
+
for (var dh = 0; dh < extraHashers.length; dh += 1) {
|
|
373
|
+
digests[extraHashers[dh].name] = extraHashers[dh].hash.digest("hex");
|
|
374
|
+
}
|
|
330
375
|
|
|
331
376
|
var ok = false;
|
|
332
377
|
if (alg === "ecdsa-p384") {
|
|
@@ -351,7 +396,7 @@ function verify(assetPath, signaturePath, pubkeyPem) {
|
|
|
351
396
|
} else {
|
|
352
397
|
// assetFd was already closed by the read loop's `finally`; this is a
|
|
353
398
|
// pure fail-closed refusal, same as the `if (!ok)` path below.
|
|
354
|
-
throw
|
|
399
|
+
throw _svErr("bad-sig-encoding", "standalone-verifier.verify: ecdsa-p384 signature is neither a " +
|
|
355
400
|
"well-formed DER SEQUENCE nor a raw " + (coordLen * 2) +
|
|
356
401
|
"-byte IEEE-P1363 pair (length " + signature.length +
|
|
357
402
|
") — refusing to guess the encoding");
|
|
@@ -366,7 +411,7 @@ function verify(assetPath, signaturePath, pubkeyPem) {
|
|
|
366
411
|
}
|
|
367
412
|
|
|
368
413
|
if (!ok) {
|
|
369
|
-
throw
|
|
414
|
+
throw _svErr("verify-failed", "standalone-verifier.verify: " + alg + " signature INVALID for " +
|
|
370
415
|
assetPath + " (sha3-512=" + sha3Hex.slice(0, 16) + "...). " + // 16-char hex prefix for forensic display, not bytes
|
|
371
416
|
"Either the asset was tampered with after signing, the signature " +
|
|
372
417
|
"doesn't match this asset, or the pubkey doesn't match the signing key.");
|
|
@@ -377,6 +422,8 @@ function verify(assetPath, signaturePath, pubkeyPem) {
|
|
|
377
422
|
sha3_512: sha3Hex,
|
|
378
423
|
sha256: sha256Hex,
|
|
379
424
|
alg: alg,
|
|
425
|
+
bytes: fullOff,
|
|
426
|
+
digests: digests,
|
|
380
427
|
};
|
|
381
428
|
}
|
|
382
429
|
|