Auditor
Reset links are single-use, expire quickly and do not reveal whether an account exists.
1.1.1: 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.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. The units are the REQUEST function and the CONFIRMATION function of the reset flow (plus 2 module hops): a weak token source is HIGH; the absent-account branch (if (!user), is None, DoesNotExist, firstOrFail) answering 4xx, an exception or a 'no account' message is HIGH, a message of its own is MEDIUM; a confirmation without token consumption or without an expiry check is MEDIUM; framework flows pass when not overridden; reset vocabulary without a request or confirmation unit is not-applicable. Not judged: timing, expiry length, token hashing. (1.0.2: never analyses temporary files (*.tmp.*; spec.excludes follows AUDITOR_ANALYSIS_EXCLUDES). (1.0.1: never analyses test, spec, fixture and mock paths nor the auditor's own scripts (spec.excludes = AUDITOR_ANALYSIS_EXCLUDES); a fixture-looking secret (sk_test_, example, dummy) in real code is LOW, informative; every model call stays under the engine prompt cap (spec.promptMaxChars = AUDITOR_AI_PROMPT_MAX_CHARS): assess mode sends the candidate set in parts and aggregates the verdicts (a HIGH in any part is a FAIL, an unsatisfied part is a FAIL).)))
| // the units of analysis are the REQUEST function (reads the address, issues the token or the mail) and the CONFIRMATION function (reads the token, sets the password) |
| const WEAK_TOKEN = /(?:token|code|reset\w*)\s*=\s*[^\n]{0,80}\b(?:Math\.random\(|random\.random\(|\brand\(|mt_rand\(|uniqid\(|Date\.now\(\)|time\(\))/; // in the request unit or its callees -> HIGH |
| const ABSENT_USER = /^\s*!\s*\$?(?:user|account)\b|\bnot\s+\$?user\b|\buser\s+is\s+None\b|\bDoesNotExist\b/i; // the absent-account branch of the request unit |
| // 4xx status, exception or a 'no account found' message in that branch -> HIGH; a message the success path never answers -> MEDIUM; the same message -> ok |
| const SINGLE_USE = /\bdelete(?:One|Many)?\s*\(|\bused(?:_?at|At)?\s*[:=]|\bconsumed|\binvalidate|check_?token\s*\(/i; // missing in the confirmation unit and its callees (<= 2 module hops) -> MEDIUM |
| const EXPIRY_CHECK = /\bexpires?(?:_?at|At|In)?\b|\bttl\b|PASSWORD_RESET_TIMEOUT|\bcreated_?at\b[^\n]{0,80}(?:[<>]|timedelta)|\btokenExpired/i; // missing there -> MEDIUM |
The full script is disclosed on request in a read-only viewer (never published on GitHub); the attestation binds to this exact hash.