Auditor
Every payment gateway in use follows the same token-only, signature-verified pattern; no gateway is handled through a raw-card path.
1.1.3: WHERE A FILE RUNS is decided from the FILE (and, when the file alone does not say, from the import graph of the checkout), never from a list of folder names of one particular repository, and a file whose server nature is UNPROVEN is never reported as server code. A monorepo has a SHARED layer — a package the browser bundle and the services both import — and the old rule read every ambiguous file as server: WebCrypto of the browser (`crypto.subtle` in a shared e2ee service that a client component imports) came out as "key generation in server code", once per product sharing the layer. The evidence is now, strongest first: the language (Python, PHP); a `server-only`/`client-only` import or a `'use server'`/`'use client'` directive; a location the framework declares as server (route.ts, middleware, pages/api, app/api, *.server.*, +server, wsgi/asgi); a browser runtime in the code (DOM member, Web Worker scope, `new Worker(`, a React client hook, a browser-environment polyfill such as fake-indexeddb or jsdom); a server runtime in the code (Node built-in, server-only package such as express/mongodb/winston/@aws-sdk, HTTP response sink, Lambda handler export); the IMPORT GRAPH (a module a client-declared file imports runs in the browser, a module that imports a server-proven module runs on a server); the folder convention (`workers/` is no longer one of them: a worker folder is a browser convention as often as a server one); a universal Web API of the browser with no server evidence at all; otherwise unproven, which is never server. Found by the attestation campaign of the platform (2026-09-25): 73 of the 252 high findings of every project were this one classification. (1.1.2: a callee whose root is a name that `Object.prototype` also carries (`build().toString()` tokenizes to the bare callee `toString`; also `constructor`, `valueOf`, `hasOwnProperty`) was looked up in the plain object that holds the imported names, so it resolved to the INHERITED FUNCTION instead of to nothing and the whole check died with "name.includes is not a function". Only a real binding counts now, and the name of a unit is always read as a string. Found on a 1 319-file checkout (2fa-available and session-expiry-rotation, 2026-09-24); the same line was in the 15 scripts that walk the call graph, so all fifteen ship the fix. (1.1.1: the browser asset folders of the server-rendered frameworks (static/, wwwroot/ and Laravel resources/js/) are classified as browser code, like public/ and assets/ already were: browser JavaScript of a Django, Flask or Go application was being analysed as server code (false positive found by the control bench of the audit scripts). (1.1.0: deterministic: the rule runs over the static analysis kit (tokens, function units, calls, imports, routes) with no AI engine; exact decisionRule and languages published; not-applicable with the reason when the checkout gives nothing to evaluate. Per gateway: the raw-card rules of gateway-tokens-only, webhook handlers verified through the call graph, and a client tokenisation OR hosted-checkout signal; crypto rails are exempt from the tokenisation rule.)))
| // per gateway (files attributed by SDK, namespace, host or path): three facts from the static analysis kit |
| // raw card on the server: a server FUNCTION reading the PAN/CVV out of the request, or passing a raw card to tokens/sources/paymentMethods/charges.create -> HIGH |
| // webhook handlers: a FUNCTION receiving a request of the provider; verification searched in its body and call graph (<= 3 module hops) -> none: HIGH |
| // client tokenisation: gateway SDK in browser code (Elements, hosted fields, drop-in, Buttons) or a hosted checkout session/preference/payment link -> missing on a card gateway: MEDIUM |
| const CARDLESS_GATEWAY = new Set(['nowpayments', 'coinbase', 'bitfinex']); // crypto rails carry no card |
| // fewer than 2 gateways -> not-applicable |
The full script is disclosed on request in a read-only viewer (never published on GitHub); the attestation binds to this exact hash.