Four scanners on the same Juice Shop source — four different lenses. Together they filed 235 findings, but they cluster, and where they independently converge is the signal.
Audn live red-team (103, 18 reproduced live). Codex commit-diff review (20, patched). Aikido SAST + SCA + secrets (36, ~52s). Mythos Claude-native whole-repo deep static (76) — the broadest static reasoner, and it reads code + tests + challenge definitions to separate intended from unintended.
All four independently agree on 4 areas — SSRF, code injection/RCE, JWT signature-not-verified, and unpinned CI supply chain — the closest thing to "certainly real" here. The new story: Mythos closes the availability blind spot the first three barely touched — 10 DoS / resource-exhaustion findings, 4 uncaught-exception process crashes, and ReDoS — plus the deepest IDOR set (12), each mapped to its intended challenge.
Each still owns an irreducible lane: Audn = live proof + business-logic/crypto; Aikido = SCA dependency CVEs + secrets breadth; Codex = changeset regressions + fix patches; Mythos = DoS/robustness depth + the broadest, most reachability-aware static reasoning. Run them as layers — fast static baseline, PR gate, deep pre-merge review, and a live merge-gate pentest. Remaining blind spots shrink to three: live infra/edge posture (unresolved), complete SCA/SBOM, and live exploit confirmation of the ~215 static findings.
Same target (ozguratwayve/juice). The severity mixes and "scanner DNA" chips show the split: Audn ranges across a live-confirmed critical tier, Codex a tight introduced-issue set, Aikido a static baseline heavy on secrets, and Mythos a broad deep-static sweep weighted toward High-severity logic, DoS and robustness.
Audn separates "facts about the running system" from "patterns in the source": 16 confirmed (static+live) + 2 observed live, vs 63 static-only leads. Codex, Aikido and Mythos are all fully static — every one of their 132 findings sits, in Audn's terms, at the unverified tier (however precise Mythos's reachability reasoning is).
Pick by the job. Fast static baseline → Aikido. PR diff gate → Codex. Deep whole-repo review → Mythos. Prove exploitability → Audn.
| Dimension | Audn | Codex | Aikido | Mythos |
|---|---|---|---|---|
| Core method | SAST + live red-team | Diff review | SAST+SCA+secrets+CI | Deep whole-repo static |
| Scope | Whole app, deployed | One changeset | Whole repo | Whole repo + tests + challenge defs |
| Findings | 103 | 20 | 36 | 76 |
| Live confirmation | 18 + tiers | None | None | None (static) |
| Dependency CVEs (SCA) | No | No | Yes (3) | No |
| DoS / robustness | Light (3+1) | 1 | None | Heavy (10+4) |
| Remediation | Prose + paths | Patch | Fix-time + guidance | Precise fix criteria |
| Intentional vs unintended | No | Yes | No | Yes (per challenge) |
| Speed | 2h 28m | Light | ~52s | Medium |
| Sweet spot | Pentest | PR gate | Continuous baseline | Deep pre-merge review |
Overlap is mapped at the issue-area level (the taxonomies differ). Each tool owns a distinct lane; the areas all four independently reach are the highest-confidence issues in the whole set.
The only scanner that ran against a deployed target and reproduced 18 findings live. Owns the business-logic / crypto lane too — weak password recovery, unbounded coupons, wallet overspend — and grades its own certainty (confirmed vs lead).
Diff-scoped review that flags what a commit introduced — regressions, a privacy leak (Google Fonts), a Windows i18n bug, Junie-skill SSRF — and ships a patch per finding. The only "what did this PR break" view.
The only tool that runs SCA — 3 dependency CVEs (jsonwebtoken, express-jwt, sanitize-html) — plus a broad secrets sweep across 40+ files incl. tests, in ~52 seconds.
Claude-native whole-repo review, 76 findings — the broadest static reasoning. Uniquely owns the availability lane: 10 DoS / resource-exhaustion, 4 uncaught-exception process crashes, ReDoS — plus the deepest IDOR set (12), each mapped to the intended challenge.
A live red-team, a diff reviewer, a commercial SAST/SCA platform, and a Claude-native deep static scanner all landing on the same class = as close to "definitely real" as it gets.
Hard-coded key + algorithm confusion in lib/insecurity.ts — every tool reaches it (Audn #22/#35, Codex #3/#4, Aikido, Mythos).
image_actions.yml / ci.yml — flagged by all four (Audn #54, Codex #1/#2, Aikido, Mythos).
Server-side eval / template injection in userProfile.ts, dataErasure.ts, b2bOrder.ts — all four reach the class (Mythos deepest, 5).
Server-side request forgery via profile-image URL / chat parts — reached by all four.
14 of Mythos's findings are DoS / resource-exhaustion or process-crashing uncaught exceptions — a class Audn touched lightly (exploit-focused), Codex once, and Aikido not at all. Hover a chip for location + CWE.
Even with four scanners, these classes came from a single tool — proof they're complementary, not redundant.
jsonwebtoken, express-jwt, sanitize-html.Two of the earlier blind spots are now covered — dependency CVEs (Aikido) and DoS/robustness (Mythos). What still isn't covered by any of the four:
Aikido's 3 CVEs; still partial (missing lockfile → add one for full transitive SCA).
Mythos's 10 resource-exhaustion + 4 uncaught-exception findings close the class the other three skipped.
All of Codex, Aikido and Mythos are static; Audn ran live but its transport/header/container items were never reached (#61) or probed with no verdict (#21). The real TLS, the HTTP security headers the edge returns, container hardening — still unresolved, not measured. One curl -I closes most of it.
Audn confirmed 18 live; the other ~215 findings (Codex 20 + Aikido 36 + Mythos 76 + Audn's 85 unconfirmed) are static. Mythos reasons hard about reachability, but nothing except Audn proved it against a running instance.
Only Aikido does SCA and it flagged a missing lockfile; no full transitive graph, license posture, or signed SBOM across the four.
Where each tool put its attention. ●●● strong (8+), ●● moderate (3–7), ● light (1–2), — none. Green rows = all four reached the class; the left rule marks a class only one tool reached. The clearest single view of the four-way spread.
| Vulnerability class | Audn | Codex | Aikido | Mythos |
|---|---|---|---|---|
| SQL Injection | ●2 | —— | ●1 | ●2 |
| NoSQL Injection | ●●3 | —— | ●1 | —— |
| XSS | ●●6 | —— | ●●3 | ●●●8 |
| XXE | ●1 | —— | —— | ●1 |
| SSRF | ●1 | ●2 | ●1 | ●1 |
| Path Traversal | ●●6 | —— | ●2 | ●●3 |
| Code Injection / RCE | ●2 | ●1 | ●2 | ●●5 |
| Insecure Deserialization | —— | —— | ●1 | ●1 |
| Broken Access Control / IDOR | ●●●16 | ●2 | —— | ●●●12 |
| JWT / Token Auth | ●●3 | ●2 | ●1 | ●2 |
| Broken Authentication | ●●3 | —— | —— | ●●3 |
| Auth Rate-Limiting | ●●3 | —— | —— | ●2 |
| Weak Password Recovery | ●1 | —— | —— | —— |
| Weak Credentials/Hashing | ●2 | —— | —— | —— |
| Hardcoded Secrets/Creds | ●●●11 | —— | ●●●17 | ●1 |
| Sensitive Data Exposure | ●●●13 | ●2 | —— | ●●6 |
| Open Redirect | ●1 | —— | ●1 | ●1 |
| CSRF | ●2 | —— | —— | ●2 |
| Broken Anti-Automation | ●2 | —— | —— | ●1 |
| Business Logic | ●2 | —— | —— | —— |
| Race Condition | ●2 | ●2 | —— | —— |
| Improper Input Validation | ●●4 | ●2 | —— | ●●7 |
| Cleartext Transmission | ●2 | —— | —— | —— |
| DoS / Resource Exhaustion | ●●3 | ●1 | —— | ●●●10 |
| Robustness / Uncaught Exception | ●1 | —— | —— | ●●4 |
| Supply Chain / CI-CD | ●●●8 | ●●6 | ●●3 | ●●4 |
| Dependency CVE (SCA) | —— | —— | ●●3 | —— |
| Insufficient Verification | ●●3 | —— | —— | —— |
Counts are findings tagged to each class (Codex/Aikido/Mythos aggregated from their finding lists). Note Mythos's dominance in DoS/Resource-Exhaustion and Robustness, Aikido's sole Dependency-CVE row, and Audn's IDOR/Sensitive-Data depth.
Every finding from all four reports, filterable — 235 total, the working index behind the analysis.
| Sev | Finding | CWE | Location | Category |
|---|---|---|---|---|
| Critical | Reset-password rate limiter keyed on client-chosen X-Forwarded-For/req.ip under trust proxy: unbounded brute force of … | CWE-307 | server.ts:340 | Authentication brute force |
| Critical | Unauthenticated POST /api/SecurityAnswers binds caller-chosen UserId: plant recovery answer, reset any answerless acco… | CWE-639 | server.ts:394 | Authentication bypass |
| Critical | Unauthenticated /rest/track-order $where injection: 60-char cap does not stop process kill or in-process code executio… | CWE-95 | routes/trackOrder.ts:13 | Code injection |
| Critical | Unauthenticated in-process JavaScript execution via MarsDB $where in product reviews lookup | CWE-95 | routes/showProductReviews.ts:31 | Code injection |
| Critical | Unauthenticated RCE via js-yaml 3.x !!js/function + JSON.stringify toJSON in complaint YAML upload | CWE-502 | routes/fileUpload.ts:104 | Insecure deserialization |
| Critical | denyAll() guard is a JWT verifier that accepts alg=none, opening every forbidden finale verb | CWE-347 | lib/insecurity.ts:52 | Improper signature verification |
| Critical | Login SQL injection via interpolated email: password-less login as any account and UNION read of the whole DB (intende… | CWE-89 | routes/login.ts:34 | SQL injection |
| High | 2FA TOTP brute force: verify limiter keyed on spoofable X-Forwarded-For-derived req.ip | CWE-307 | server.ts:458 | Authentication brute force |
| High | Unauthenticated /api/Recycles/:id JSON-parsed id dumps every user's recycle requests; POST binds foreign UserId | CWE-862 | routes/recycles.ts:11 | Missing authorization |
| High | Unauthenticated PUT /api/Hints/:id lets anyone rewrite hint text and re-parent hints, not just unlock them | CWE-915 | server.ts:375 | Mass assignment |
| High | PUT /api/Products/:id has no guard: anonymous tampering of every product's name, price, image and description (documen… | CWE-306 | server.ts:368 | Missing authentication |
| High | Forged continue code marks every challenge solved and broadcasts all CTF flags to any socket.io client without solving… | CWE-345 | routes/restoreProgress.ts:16 | Authentication bypass |
| High | Username evaluated with eval() on GET /profile: server-side JavaScript/command execution (documented sstiChallenge / u… | CWE-95 | routes/userProfile.ts:54 | Code injection |
| High | Uploaded image files are compiled as Handlebars layouts: attacker-authored template execution | CWE-1336 | routes/dataErasure.ts:103 | Server-side template injection |
| High | Username spliced into Pug template source yields RCE even when SSTi challenge is disabled | CWE-1336 | routes/userProfile.ts:62 | Server-side template injection |
| High | Client-chosen multipart Content-Type becomes a permanent Prometheus label: unbounded series growth | CWE-770 | routes/metrics.ts:73 | Resource exhaustion |
| High | Unauthenticated repeat-notification appends to the unbounded global notification queue on every call; the whole queue … | CWE-770 | lib/challengeUtils.ts:71 | Resource exhaustion |
| High | Code-fix cache permanently stores an entry for every arbitrary request-supplied key: unbounded heap growth from unauth… | CWE-770 | routes/vulnCodeFixes.ts:18 | Resource exhaustion |
| High | Photo-wall upload persists unbounded, unvalidated files into the served directory for any network client, written befo… | CWE-770 | server.ts:698 | Resource exhaustion |
| High | Backend i18n catalog learns attacker-supplied phrases: unbounded in-memory and on-disk growth with synchronous full re… | CWE-770 | server.ts:298 | Resource exhaustion |
| High | Quadratic regex on unauthenticated socket.io 'verifySvgInjectionChallenge' payload stalls the event loop | CWE-1333 | lib/startup/registerWebsocketEvents.ts:45 | ReDoS |
| High | Quadratic regex on unauthenticated XML upload output stalls the single-process server | CWE-1333 | lib/utils.ts:220 | ReDoS |
| High | Per-request full scan and bigram similarity over all complaints enables stored CPU exhaustion | CWE-400 | routes/verify.ts:371 | Algorithmic complexity DoS |
| High | Unauthenticated wallet-address submissions permanently grow an in-memory Set without bound | CWE-770 | routes/web3Wallet.ts:15 | Resource exhaustion |
| High | Hard-coded valid admin test-account credentials shipped in the login component bundle (documented exposedCredentialsCh… | CWE-798 | frontend/src/app/login/login.component.ts:61 | Hard-coded credentials |
| High | Startup snippet scan parses the SQLite database file as source: stale user text with a snippet marker aborts every boo… | CWE-20 | lib/codingChallenges.ts:5 | Improper Input Validation |
| High | Unauthenticated socket.io event with non-string payload throws uncaught TypeError and kills the server process | CWE-1287 | lib/startup/registerWebsocketEvents.ts:40 | Improper Input Validation |
| High | Backslash path traversal in /ftp, /ftp/quarantine, /encryptionkeys and /support/logs file servers escapes the served d… | CWE-22 | routes/keyServer.ts:11 | Path traversal |
| High | Zip-slip in unauthenticated complaint upload overwrites per-request-compiled Pug templates: RCE | CWE-23 | routes/fileUpload.ts:27 | Path traversal |
| High | Un-awaited quantityCheck on PUT /api/BasketItems/:id rejects unhandled: authenticated user kills the process | CWE-248 | routes/basketItems.ts:65 | Uncaught exception |
| High | Failed avatar download at startup causes unhandled rejection that terminates the server | CWE-248 | lib/startup/customizeApplication.ts:44 | Uncaught exception |
| High | Promotion page crashes process when subtitles configured as URL (startup/consumer filename mismatch) | CWE-248 | routes/videoHandler.ts:80 | Uncaught exception |
| High | Product search SQL injection lets one anonymous GET hang the shared SQLite connection and libuv threadpool indefinitel… | CWE-89 | routes/search.ts:21 | SQL injection |
| High | Unauthenticated SSRF via URL-typed image/file parts in chatbot messages | CWE-918 | routes/chat.ts:191 | Server-Side Request Forgery |
| High | Public application-configuration endpoint discloses seeded security answers and OSINT challenge answers | CWE-201 | routes/appConfiguration.ts:9 | Information disclosure |
| High | Anonymous serve-index listings and downloads of /ftp, /support/logs, /encryptionkeys, /.well-known (documented challen… | CWE-548 | server.ts:269 | Directory listing exposure |
| High | Customer order confirmation PDFs (unmasked email, purchases) written into the publicly listed /ftp directory and reada… | CWE-538 | routes/order.ts:40 | Sensitive data exposure |
| High | Public product-review listing discloses the email addresses of every user who liked a review | CWE-359 | routes/showProductReviews.ts:36 | Information disclosure |
| High | Password reset response returns the victim's full user row (totpSecret, password hash), turning a guessed security ans… | CWE-201 | routes/resetPassword.ts:42 | Information exposure |
| High | Public GET /rest/memories serialises each memory owner's full User row (MD5 password hash, totpSecret, deluxeToken, la… | CWE-200 | routes/memory.ts:22 | Information disclosure |
| High | Mutable third-party action refs run with write-scoped GITHUB_TOKEN on release-branch pushes | CWE-829 | .github/workflows/image_actions.yml:29 | Supply chain |
| High | Unpinned lint toolchain runs with persisted write token; its output is auto-committed to release branches | CWE-494 | .github/workflows/lint-fixer.yml:3 | Supply chain compromise |
| High | E2E spec makes the CI server process download and execute an unpinned, unverified binary from a maintainer's personal … | CWE-494 | test/cypress/e2e/profile.spec.ts:50 | Unverified code download |
| High | Forgeable z85 coupons with unbounded discount (forgedCouponChallenge; >100% overlaps negativeOrderChallenge) | CWE-649 | lib/insecurity.ts:97 | Missing integrity check |
| High | Stored XSS: data export JSON written unescaped via document.write into same-origin window | CWE-79 | frontend/src/app/data-export/data-export.component.ts:71 | Cross-site scripting |
| High | Score board renders challenge records as trusted HTML; anonymous challenge rewrite yields stored XSS on every visitor | CWE-79 | frontend/src/app/score-board/score-board.component.ts:82 | Cross-site scripting |
| High | Stored XSS: product descriptions marked trusted HTML and rendered via innerHTML | CWE-79 | frontend/src/app/search-result/search-result.component.ts:108 | Cross-site scripting |
| High | Reflected DOM XSS via order tracking id (reflectedXssChallenge): server echoes unmatched id, client marks it trusted H… | CWE-79 | frontend/src/app/track-result/track-result.component.ts:45 | Cross-site scripting |
| High | Stored XSS against administrators: user email persisted unsanitised (persistedXssUserChallenge enabled) and rendered a… | CWE-79 | models/user.ts:59 | Cross-site scripting |
| High | Reflected DOM XSS: search query parameter rendered via bypassSecurityTrustHtml | CWE-79 | frontend/src/app/search-result/search-result.component.ts:136 | Cross-site scripting |
| High | Stored XSS via SVG profile image fetched from attacker URL and served on the app origin | CWE-79 | routes/profileImageUrlUpload.ts:28 | Cross-site scripting |
| High | Safety Mode does not disable XXE/YAML-bomb parsing: gate checks a never-disabled challenge | CWE-611 | routes/fileUpload.ts:73 | XML external entity injection |
| Medium | PUT-only Address/BasketItem guards leave PATCH unguarded if finale-rest binds update to PATCH | CWE-862 | server.ts:450 | Missing authorization |
| Medium | Deluxe upgrade granted without payment when paymentMode is neither 'wallet' nor 'card' (documented freeDeluxeChallenge… | CWE-841 | routes/deluxe.ts:24 | Privilege escalation |
| Medium | GET /rest/basket/:id returns any user's basket to any authenticated caller (documented basketAccessChallenge) | CWE-639 | routes/basket.ts:18 | Insecure direct object reference |
| Medium | Orders keyed by vowel-masked email leak look-alike users' order history (dataExportChallenge) | CWE-639 | routes/orderHistory.ts:13 | Insecure direct object reference |
| Medium | BasketItem API: list and by-id GET/PUT/DELETE act on any user's basket items without basket-ownership check | CWE-639 | server.ts:358 | Insecure direct object reference |
| Medium | GET /api/Users, /api/Users/:id and /rest/user/authentication-details expose all users' records to any authenticated ac… | CWE-862 | server.ts:362 | Missing authorization |
| Medium | GET /api/Complaints returns every user's complaint text to any authenticated account; POST /api/Complaints stores a ca… | CWE-862 | server.ts:380 | Missing authorization |
| Medium | PUT /api/Addresss/:id updates any user's address; appendUserId re-owns it to the caller | CWE-639 | server.ts:450 | Insecure direct object reference |
| Medium | Checkout and coupon routes act on any basket id without ownership check | CWE-639 | routes/order.ts:34 | Insecure direct object reference |
| Medium | finale search on GET /api/Users?q= matches excluded password and totpSecret columns (oracle for hash/2FA-secret extrac… | CWE-203 | server.ts:483 | Observable discrepancy |
| Medium | Password change skips current-password verification when `current` is omitted (changePasswordBenderChallenge); passwor… | CWE-620 | routes/changePassword.ts:39 | Unverified password change |
| Medium | Google OAuth implicit-flow callback accepts any access_token, enabling login CSRF into attacker account | CWE-352 | frontend/src/app/oauth/oauth.component.ts:27 | Cross-site request forgery |
| Medium | Unvalidated feedback rating drives Array(rating).fill() on the Administration page, hanging or breaking it | CWE-770 | frontend/src/app/administration/administration.component.ts:133 | Uncontrolled resource consumption |
| Medium | Negative basket quantities pass the stock/limit checks and a negative order total credits the buyer's wallet and infla… | CWE-1284 | routes/basketItems.ts:92 | Improper Input Validation |
| Medium | POST /api/BasketItems: ownership check reads the first BasketId, the write reads the last — duplicate-key parser diffe… | CWE-436 | routes/basketItems.ts:21 | Interpretation conflict |
| Medium | testDecal query parameter controls SVG image href on deluxe page (svgInjectionChallenge) | CWE-99 | frontend/src/app/deluxe-user/deluxe-user.component.ts:57 | Resource injection |
| Medium | Startup asset download persists unvalidated remote response bytes into the served static tree | CWE-829 | lib/utils.ts:114 | Untrusted remote content inclusion |
| Medium | Security answers stored as HMAC-SHA256 under a hard-coded public key: offline recovery of every user's recovery secret | CWE-321 | lib/insecurity.ts:42 | Hard-coded cryptographic key |
| Medium | Redirect allowlist uses substring match: open redirect to any URL (intended challenges redirectChallenge / redirectCry… | CWE-601 | lib/insecurity.ts:133 | Open redirect |
| Medium | Empty layout render dereferences null error in hbs completion callback; with the view template cached the TypeError is… | CWE-476 | routes/dataErasure.ts:110 | NULL pointer dereference |
| Medium | Product image field concatenated into CSS background-image url() lets anonymous product tampering load an external bea… | CWE-79 | frontend/src/app/product/product.component.html:34 | CSS injection |
| Low | POST /profile changes the username on cookie-only authentication with no CSRF defence (documented csrfChallenge) | CWE-352 | routes/updateUserProfile.ts:17 | Cross-site request forgery |
| Low | Accounting inventory table dereferences missing Quantity row; any customer-created product breaks the page | CWE-476 | frontend/src/app/accounting/accounting.component.html:94 | Improper Input Validation |
| Low | Unvalidated language cookie steers translation loader to attacker-uploaded JSON via path traversal | CWE-22 | frontend/src/app/navbar/navbar.component.ts:203 | Path traversal |
| # | Sev | Finding | CWE | Location | Confidence | Overlap |
|---|---|---|---|---|---|---|
| #1 | Critical | Sensitive information written to log file LIVE | CWE-532 | server.ts:280 | Confirmed | Audn only |
| #2 | Critical | Unthrottled password-reset (spoofable X-Forwarded-For) LIVE | CWE-307 | server.ts:340 | Confirmed | Audn only |
| #3 | Critical | OAuth derives predictable password from email LIVE | CWE-521 | frontend/src/app/oauth/oauth.component.ts:27 | Confirmed | Audn only |
| #4 | Critical | Wallet recovery mnemonic committed in plaintext LIVE | CWE-321 | data/static/users.yml:259 | Confirmed | Audn only |
| #5 | Critical | Hard-coded admin credentials in seed data LIVE | CWE-798 | data/static/users.yml:167 | Confirmed | Audn only |
| #6 | Critical | Hard-coded security-question answers LIVE | CWE-798 | config/7ms.yml:143 | Confirmed | Audn only |
| #7 | Critical | Weak password recovery via seeded answers LIVE | CWE-640 | routes/resetPassword.ts:18 | Confirmed | Audn only |
| #8 | Critical | Hard-coded credentials in login handler LIVE | CWE-798 | routes/login.ts:59 | Confirmed | Audn only |
| #9 | High | SQL injection in product search LIVE | CWE-89 | routes/search.ts:21 | Confirmed | Audn only |
| #10 | High | NoSQL injection in track-order LIVE | CWE-943 | routes/trackOrder.ts:15 | Confirmed | Audn only |
| #11 | High | NoSQL injection in product reviews LIVE | CWE-943 | routes/showProductReviews.ts:31 | Confirmed | Audn only |
| #12 | High | Weak (MD5) password hashing LIVE | CWE-916 | models/user.ts:73 | Confirmed | Audn only |
| #13 | High | Stored XSS in product LIVE | CWE-79 | models/product.ts:42 | Confirmed | Audn only |
| #14 | High | Sensitive info exposure via memories LIVE | CWE-200 | routes/memory.ts:22 | Confirmed | Audn only |
| #15 | High | Unthrottled 2FA verification LIVE | CWE-307 | routes/2fa.ts:16 | Confirmed | Audn only |
| #16 | High | Challenge flag exposed in notification LIVE | CWE-200 | lib/challengeUtils.ts:52 | Confirmed | Audn only |
| #17 | Critical | Spoofable X-Forwarded-For bypasses reset rate limit LIVE | | Observed | Audn only | |
| #18 | Critical | Public access logs contain cleartext change-password URLs LIVE | | Observed | Audn only | |
| #19 | Critical | ZIP upload overwrites arbitrary application files | CWE-22 | routes/fileUpload.ts:27 | Probed | Audn only |
| #20 | Critical | Search query causes DOM-based XSS | CWE-79 | frontend/src/app/search-result/search-result.component.ts:135 | Probed | Audn only |
| #21 | Critical | Mutable base images enter production builds | CWE-829 | Dockerfile:1 | Probed | Audn+Codex |
| #22 | Critical | Hard-coded JWT private key enables token forgery | CWE-321 | lib/insecurity.ts:20 | Probed | Audn+Codex |
| #23 | Critical | Release tag enables cross-repo command injection | CWE-78 | .github/workflows/update-news-www.yml:18 | Probed | Audn+Codex |
| #24 | Critical | Tracking ID enables reflected XSS | CWE-79 | frontend/src/app/track-result/track-result.component.ts:45 | Probed | Audn only |
| #25 | Critical | Build argument injects arbitrary npm packages | CWE-88 | Dockerfile:18 | Probed | Audn+Codex |
| #26 | High | Anonymous XML upload discloses local files (XXE) | CWE-611 | server.ts:307 | Probed | Audn only |
| #27 | High | Profile image URL enables SSRF | CWE-918 | server.ts:307 | Probed | Audn only |
| #28 | High | Unbounded upload can exhaust server disk | CWE-400 | server.ts:698 | Probed | Audn only |
| #29 | High | Backslashes bypass quarantine path validation | CWE-22 | routes/quarantineServer.ts:10 | Probed | Audn only |
| #30 | High | Order data enables remote code execution | CWE-94 | routes/b2bOrder.ts:19 | Probed | Audn only |
| #31 | High | Stored username enables server-side code execution | CWE-95 | routes/userProfile.ts:54 | Probed | Audn only |
| #32 | High | Remote installer executes without integrity verification | CWE-494 | .github/workflows/ci.yml:357 | Probed | Audn+Codex |
| #33 | High | Remote SVG upload enables stored XSS | CWE-79 | server.ts:310 | Probed | Audn only |
| #34 | High | Lockless installs execute mutable dependency code | CWE-829 | .npmrc:1 | Probed | Audn+Codex |
| #35 | High | JWT verification trusts attacker-selected algorithm | CWE-347 | lib/insecurity.ts:52 | Probed | Audn+Codex |
| #36 | High | Release tag injects commands into legacy website update | CWE-78 | .github/workflows/update-news-www-legacy.yml:18 | Probed | Audn+Codex |
| #37 | Critical | Login query permits authentication bypass | CWE-89 | routes/login.ts:32 | Static lead | Audn only |
| #38 | High | Null-suffix bypass enables Windows file traversal | CWE-22 | routes/fileServer.ts:16 | Static lead | Audn only |
| #39 | High | Password change skips current-password check | CWE-620 | routes/changePassword.ts:39 | Static lead | Audn only |
| #40 | High | Endpoint exposes complete runtime configuration | CWE-200 | routes/appConfiguration.ts:10 | Static lead | Audn only |
| #41 | High | Repository code executes with CI secrets | CWE-200 | .github/workflows/ci.yml:229 | Static lead | Audn only |
| #42 | High | Security-answer bypass permits unverified erasure | CWE-620 | routes/dataErasure.ts:74 | Static lead | Audn only |
| #43 | Medium | Production error handler exposes stack traces | CWE-209 | server.ts:314 | Static lead | Audn only |
| #44 | Medium | Metrics endpoint exposed without authentication | CWE-200 | server.ts:725 | Static lead | Audn only |
| #45 | Medium | Anonymous FTP directory listing exposes hidden files | CWE-548 | server.ts:267 | Static lead | Audn only |
| #46 | Medium | Anonymous users can modify products | CWE-862 | server.ts:368 | Static lead | Audn only |
| #47 | Medium | YAML aliases block the Node.js event loop | CWE-400 | routes/fileUpload.ts:101 | Static lead | Audn only |
| #48 | Medium | Substring allowlist permits arbitrary redirects | CWE-601 | routes/redirect.ts:13 | Static lead | Audn only |
| #49 | Medium | Unbounded image download exhausts storage | CWE-400 | routes/profileImageUrlUpload.ts:24 | Static lead | Audn only |
| #50 | Medium | Users can edit reviews owned by others | CWE-639 | routes/updateProductReviews.ts:16 | Static lead | Audn only |
| #51 | Medium | NoSQL selector updates every product review | CWE-943 | routes/updateProductReviews.ts:17 | Static lead | Audn only |
| #52 | Medium | Ordinary users can enumerate all user profiles | CWE-862 | routes/authenticatedUsers.ts:10 | Static lead | Audn only |
| #53 | Medium | Arbitrary field selection exposes credential material | CWE-200 | routes/currentUser.ts:20 | Static lead | Audn only |
| #54 | Medium | Mutable actions receive repo write capability | CWE-829 | .github/workflows/image_actions.yml:29 | Static lead | Audn+Codex |
| #55 | Medium | Unversioned Playwright install can overwrite master | CWE-829 | .github/workflows/frontend-bundle-analysis.yml:39 | Static lead | Audn only |
| #56 | Medium | Unvalidated seed data can create administrators | CWE-20 | data/staticData.ts:55 | Static lead | Audn only |
| #57 | Medium | Application name injects executable HTML | CWE-79 | lib/startup/customizeApplication.ts:83 | Static lead | Audn only |
| #58 | Medium | Anonymous callers can forge product reviews | CWE-862 | routes/createProductReviews.ts:14 | Static lead | Audn only |
| #59 | Medium | Unverified JWT controls chatbot order identity | CWE-347 | routes/chat.ts:42 | Static lead | Audn+Codex |
| #60 | Medium | Coupon policy enforced only by the LLM | CWE-862 | routes/chat.ts:176 | Static lead | Audn+Codex |
| #61 | Medium | Default deployment exposes credentials over plain HTTP | CWE-319 | server.ts:130 | Static lead | Audn only |
| #62 | Medium | Bender account password exposed client-side | CWE-798 | frontend/src/hacking-instructor/challenges/loginBender.ts:75 | Static lead | Audn only |
| #63 | Medium | Jim account password exposed client-side | CWE-798 | frontend/src/hacking-instructor/challenges/loginJim.ts:64 | Static lead | Audn only |
| #64 | Medium | CAPTCHA response discloses its answer | CWE-200 | routes/captcha.ts:22 | Static lead | Audn only |
| #65 | Medium | Solved CAPTCHAs remain valid for unlimited reuse | CWE-294 | routes/captcha.ts:35 | Static lead | Audn only |
| #66 | Medium | Failed requests satisfy global anti-cheat checks | CWE-345 | lib/antiCheat.ts:51 | Static lead | Audn only |
| #67 | Medium | Committed CTF key permits flag forgery | CWE-321 | ctf.key:1 | Static lead | Audn only |
| #68 | Medium | Product link uses cleartext HTTP | CWE-319 | config/addo.yml:57 | Static lead | Audn only |
| #69 | Medium | Client clock controls campaign coupon validity | CWE-602 | frontend/src/app/payment/payment.component.ts:152 | Static lead | Audn only |
| #70 | Medium | Feedback accepts ratings outside valid range | CWE-20 | models/feedback.ts:57 | Static lead | Audn only |
| #71 | Medium | Basket IDOR exposes other users carts | CWE-639 | routes/basket.ts:18 | Static lead | Audn only |
| #72 | Medium | Duplicate BasketId bypasses ownership check | CWE-639 | routes/basketItems.ts:21 | Static lead | Audn only |
| #73 | Medium | Coupon update lacks basket ownership check | CWE-639 | routes/coupon.ts:11 | Static lead | Audn only |
| #74 | Medium | User-controlled layout enables local file disclosure | CWE-22 | routes/dataErasure.ts:103 | Static lead | Audn only |
| #75 | Medium | CAPTCHA answer disclosed in API response | CWE-200 | routes/imageCaptcha.ts:24 | Static lead | Audn only |
| #76 | Medium | Missing CAPTCHA record bypasses verification | CWE-693 | routes/imageCaptcha.ts:42 | Static lead | Audn only |
| #77 | Medium | Wallet debit permits concurrent overspending | CWE-362 | routes/order.ts:148 | Static lead | Audn only |
| #78 | Medium | Checkout lacks basket ownership validation | CWE-639 | routes/order.ts:34 | Static lead | Audn only |
| #79 | Medium | Array ID exposes multiple recycle records | CWE-639 | routes/recycles.ts:11 | Static lead | Audn only |
| #80 | Medium | Premium content served without authorization | CWE-862 | routes/premiumReward.ts:12 | Static lead | Audn only |
| #81 | Medium | Response discrepancy enables account enumeration | CWE-204 | routes/securityQuestion.ts:12 | Static lead | Audn only |
| #82 | Medium | Arbitrary wallet balance top-ups | CWE-20 | routes/wallet.ts:23 | Static lead | Audn only |
| #83 | Medium | Client header spoofs stored login IP | CWE-345 | routes/saveLoginIp.ts:18 | Static lead | Audn only |
| #84 | Medium | Masked-email collisions expose other users orders | CWE-639 | routes/orderHistory.ts:13 | Static lead | Audn only |
| #85 | Medium | Authentication token contains the TOTP seed | CWE-200 | routes/2fa.ts:26 | Static lead | Audn only |
| #86 | Medium | Unverified issue references defeat spam enforcement | CWE-840 | .github/workflows/pr-compliance.yml:275 | Static lead | Audn only |
| #87 | Medium | Any commenter can rebase pull requests | CWE-862 | .github/workflows/rebase.yml:3 | Static lead | Audn only |
| #88 | Medium | Lossy email masking breaks order ownership | CWE-187 | routes/chat.ts:158 | Static lead | Audn+Codex |
| #89 | Medium | New commits bypass completed compliance decisions | CWE-367 | .github/workflows/pr-compliance.yml:3 | Static lead | Audn only |
| #90 | Medium | JWT algorithm confusion accepts forged tokens | CWE-347 | routes/verify.ts:111 | Static lead | Audn+Codex |
| #91 | Medium | Anonymous users can access arbitrary orders | CWE-639 | routes/trackOrder.ts:12 | Static lead | Audn only |
| #92 | Medium | OAuth flow omits state validation | CWE-352 | frontend/src/app/login/login.component.ts:147 | Static lead | Audn only |
| #93 | Medium | Unanchored coupon validation accepts unbounded discounts | CWE-20 | lib/insecurity.ts:102 | Static lead | Audn only |
| #94 | Medium | Generated users share a hard-coded password | CWE-798 | data/datacreator.ts:310 | Static lead | Audn only |
| #95 | Low | Concurrent requests inflate review likes | CWE-362 | routes/likeProductReviews.ts:25 | Static lead | Audn only |
| #96 | Low | Public wallet address accepted as ownership proof | CWE-345 | routes/nftMint.ts:41 | Static lead | Audn+Codex |
| #97 | Low | Profile update lacks CSRF enforcement | CWE-352 | routes/updateUserProfile.ts:16 | Static lead | Audn only |
| #98 | Low | Wallet ownership is never verified | CWE-862 | routes/web3Wallet.ts:14 | Static lead | Audn+Codex |
| #99 | Low | TOTP secrets stored unencrypted | CWE-312 | routes/2fa.ts:105 | Static lead | Audn only |
| #100 | Info | Active user credentials embedded in client code | CWE-798 | frontend/src/hacking-instructor/challenges/exposedCredentials.ts:51 | Likely FP | Audn only |
| #101 | Info | Feedback XSS compromises administrator sessions | CWE-79 | frontend/src/app/administration/administration.component.ts:86 | Likely FP | Audn only |
| #102 | Info | Backslashes bypass log path validation | CWE-22 | routes/logfileServer.ts:9 | Likely FP | Audn only |
| #103 | Info | Backslashes bypass key-file path restriction | CWE-22 | routes/keyServer.ts:10 | Likely FP | Audn only |
| # | Sev | Issue | Engine | Location | Overlap |
|---|---|---|---|---|---|
| #1 | Critical | jsonwebtoken — attacker can abuse missing input validation | Dependency | dependency (jsonwebtoken) | Aikido only |
| #2 | Critical | Remote Code Execution via eval()-type functions | Code | userProfile.ts | Audn+Aikido |
| #3 | Critical | Unsafe YAML load can lead to RCE | Code | vulnCodeSnippet.ts, vulnCodeFixes.ts | Aikido only |
| #4 | High | NoSQL injection attack possible | Code | deluxe.ts, wallet.ts +19 | Audn+Aikido |
| #5 | High | JWT signature is not verified | Code | insecurity.ts, authenticatedUsers.ts | A+C+K |
| #6 | High | Path traversal via Express sendFile() | Code | fileServer.ts | Audn+Aikido |
| #7 | High | SQL injection via string concatenation | Code | dbSchemaChallenge_1.ts, unionSqlInjectionChallenge_1.ts +3 | Audn+Aikido |
| #8 | High | Open redirect usable in social engineering | Code | redirect.ts | Audn+Aikido |
| #9 | High | Server-Side Template Injection via express.render() | Code | dataErasure.ts | Audn+Aikido |
| #10 | High | express-jwt — attacker can abuse improper authorization | Dependency | dependency (express-jwt) | Aikido only |
| #11 | High | 6 exposed secrets | Secret | users.yml | Audn+Aikido |
| #12 | High | 4 exposed secrets | Secret | login.ts, login.js | Audn+Aikido |
| #13 | High | document.write() methods can lead to XSS | Code | index.ts | Aikido only |
| #14 | High | XSS via window.location.href | Code | order-history.component.ts | Aikido only |
| #15 | High | File inclusion via reading file | Code | validatePreconditions.ts, rsnUtil.ts +9 | Aikido only |
| #16 | High | 3rd party GitHub Actions should be pinned | CI/IaC | image_actions.yml, ci.yml | A+C+K |
| #17 | Medium | sanitize-html — XSS attack possible | Dependency | dependency (sanitize-html) | Aikido only |
| #18 | Medium | 1 exposed secret | Secret | .travis.yml | Aikido only |
| #19 | Medium | 1 exposed secret | Secret | server.js | Aikido only |
| #20 | Medium | 1 exposed secret | Secret | users.json | Aikido only |
| #21 | Medium | 33 exposed secrets | Secret | datacreator.js, chat.test.ts +21 | Aikido only |
| #22 | Medium | HTTP request might enable SSRF | Code | profileImageUrlUpload.ts | Audn+Aikido |
| #23 | Medium | Binary pulled from remote without integrity check | CI/IaC | ci.yml | A+C+K |
| #24 | Medium | XSS via bypassSecurityTrustUrl | Code | track-result.component.ts, search-result.component.ts +2 | Audn+Aikido |
| #25 | Low | actions/checkout persists Git credentials | CI/IaC | ci.yml, codeql-analysis.yml +11 | Aikido only |
| #26 | Low | 1 exposed secret | Secret | oauth.component.spec.ts | Aikido only |
| #27 | Low | Exposed JWT | Secret | last-login-ip.component.spec.ts | Aikido only |
| #28 | Low | Exposed JWT | Secret | app.guard.spec.ts | Aikido only |
| #29 | Low | Exposed JWT | Secret | verify.unit.test.ts +4 | Aikido only |
| #30 | Low | 6 exposed secrets | Secret | checkKeys.test.ts, web3.test.ts +1 | Aikido only |
| #31 | Low | 4 exposed secrets | Secret | 2fa.test.ts | Aikido only |
| #32 | Low | 1 exposed secret | Secret | 2faSetupSpec.js | Aikido only |
| #33 | Low | 1 exposed secret | Secret | totpSetup.spec.ts | Aikido only |
| #34 | Low | 5 exposed secrets | Secret | currentUserSpec.js +1 | Aikido only |
| #35 | Low | 2 exposed secrets | Secret | 2faSpec.js, 2fa.test.ts | Aikido only |
| #36 | Low | 6 exposed secrets | Secret | user.test.ts, userApiSpec.js | Aikido only |
| # | Sev | Finding | Key files | Overlap |
|---|---|---|---|---|
| #1 | High | Unpinned CI image actions receive repository token | .github/workflows/image_actions.yml | Audn+Codex |
| #2 | High | Unpinned image workflow actions expose CI token | .github/workflows/image_actions.yml | Audn+Codex |
| #3 | High | 2FA temporary JWTs accepted as bearer auth | server.ts, lib/insecurity.ts | Audn+Codex |
| #4 | High | Global forged-JWT registration enables account takeover | lib/insecurity.ts | Audn+Codex |
| #5 | High | Release tag command injection in legacy website workflow | .github/workflows/update-news-www-legacy.yml | Audn+Codex |
| #6 | High | Unpinned npm installs in release and Docker builds | package-lock.json, Dockerfile | Audn+Codex |
| #7 | High | Chat order tool trusts unverified JWT identity | routes/chat.ts | Audn+Codex |
| #8 | High | Chat order tool trusts unsigned JWT identity | routes/chat.ts | Audn+Codex |
| #9 | Medium | Unbounded complaint similarity scan enables DoS | routes/verify.ts, models/complaint.ts | Codex only |
| #10 | Medium | Lazy Web3 imports race creates duplicate listeners | routes/nftMint.ts, routes/web3Wallet.ts | Audn+Codex |
| #11 | Medium | Lazy ethers import races Web3 listener creation | routes/nftMint.ts, routes/web3Wallet.ts | Audn+Codex |
| #12 | Medium | CI smoke test re-enables npm lifecycle scripts | .github/workflows/ci.yml | Audn+Codex |
| #13 | Medium | Junie skill curls untrusted reference URLs | .junie/skills/add-reference/SKILL.md | Codex only |
| #14 | Medium | Unsafe Junie curl crawling exposes local/internal resources | .junie/skills/add-reference/SKILL.md | Codex only |
| #15 | Medium | External Google Font leaks visitor metadata | config/ctf.yml, index.html | Codex only |
| #16 | Low | Unconditional Google Fonts load leaks CTF visitor metadata | server.ts, index.html | Codex only |
| #17 | Low | Windows i18n restore uses Unix-only basename parsing | lib/startup/restoreOverwrittenFilesWithOriginals.ts | Codex only |
| #18 | Info | Challenge name mismatch hides Hacking Instructor | data/static/challenges.yml | Codex only |
| #19 | Info | Complaint length test no longer checks max boundary | complaint.component.spec.ts | Codex only |
| #20 | Info | Missing snippet metadata now causes 500 errors | routes/vulnCodeSnippet.ts | Codex only |
Four gates from commit to main, ordered by cost and depth: cheap/fast/frequent first, expensive/live last. Mythos slots in as the deep whole-repo review before the merge, complementing Codex's fast diff scope; Audn stays at the merge-to-main gate as you called it.
Codex and Mythos overlap (both AI code review) but differ in scope: Codex is diff-scoped and fast (every PR), Mythos is whole-repo and deep (pre-merge or scheduled). If you run only one AI reviewer, Mythos gives breadth; Codex gives the "what this PR introduced" delta and a patch. Audn's ~2h 28m means the merge gate isn't instant — run it against the preview as soon as the PR is approved.