GHSA-685j-v6qp-54w7: 
JavaScript Analyse et atténuation de la vulnérabilité

Summary

The built-in request logger writes the full request URL, query string included, to stdout and logs/tina4.log. OAuth authorization codes, password-reset tokens and API keys passed as query parameters end up in the log. It is on by default with TINA4_DEBUG=true, and in production with TINA4_LOG_REQUESTS=true. The opt-in RequestLogger class does the same. Python, PHP and Ruby log the path only.

Reproduction (3.13.155, current v3 tip)

Serve any route, request /auth/callback?code=s3cret&token=s3cret2, then read the log: GET http://app.example/auth/callback?code=s3cret&token=s3cret2 -> 200 Reproduced in 3 of 3 configurations: dev default, production with TINA4_LOG_REQUESTS=true, and the RequestLogger class.

Fix

requestLogger() and RequestLogger.afterLog (packages/core/src/middleware.ts) log req.path instead of req.url, through one small helper. The log line keeps method, path, status and duration. A regression block in test/middleware.test.ts fails 3 of 3 on the unfixed tree and passes with the fix (37 passed). Full run-all.ts suite: no new failures against the same tip. Severity: limited to people who can read the application's logs.

Patch (applies to v3 tip)

diff --git a/packages/core/src/middleware.ts b/packages/core/src/middleware.ts
index 29fd1d6..34a2449 100644
--- a/packages/core/src/middleware.ts
+++ b/packages/core/src/middleware.ts
@@ -913,9 +913,9 @@ export class RequestLogger {
     const duration = Date.now() - ((req as any).startTime ?? Date.now());
     const status = res.raw.statusCode;
     const method = req.method ?? "?";
-    const url = req.url ?? "/";
+    const path = logPath(req);
     const color = status >= 400 ? "\x1b[31m" : status >= 300 ? "\x1b[33m" : "\x1b[32m";
-    console.log(`  ${color}${status}\x1b[0m ${method} ${url} \x1b[90m${duration}ms\x1b[0m`);
+    console.log(`  ${color}${status}\x1b[0m ${method} ${path} \x1b[90m${duration}ms\x1b[0m`);
     return [req, res];
   }
 }
@@ -1231,6 +1231,13 @@ export function attachCsrfFromEnv(): boolean {
   return false;
 }
 
+// The path only, never req.url: createRequest sets that to the absolute URL
+// with its query string, and OAuth codes, reset tokens and API keys ride in
+// the query straight into the log. Python, PHP and Ruby log the path too.
+function logPath(req: Tina4Request): string {
+  return req.path ?? (req.url ?? "/").split("?")[0];
+}
+
 // Built-in request logger middleware.
 //
 // v3.13.14: routes through the Tina4 Log (was a bare console.log) so the
@@ -1248,8 +1255,7 @@ export function requestLogger(): Middleware {
       const duration = Date.now() - start;
       const status = res.raw.statusCode;
       const method = req.method ?? "?";
-      const url = req.url ?? "/";
-      Log.info(`${method} ${url} -> ${status} (${duration}ms)`);
+      Log.info(`${method} ${logPath(req)} -> ${status} (${duration}ms)`);
     });
 
     next();
diff --git a/test/middleware.test.ts b/test/middleware.test.ts
index 2de593e..171aa5f 100644
--- a/test/middleware.test.ts
+++ b/test/middleware.test.ts
@@ -10,7 +10,7 @@ file, You can obtain one at https://mozilla.org/MPL/2.0/.
  * Unit tests for the middleware chain (middleware.ts).
  * Run with: npx tsx test/middleware.test.ts
  */
-import { MiddlewareChain, cors, requestLogger } from "../packages/core/src/index.ts";
+import { MiddlewareChain, cors, requestLogger, RequestLogger } from "../packages/core/src/index.ts";
 import type { Tina4Request, Tina4Response, Middleware } from "../packages/core/src/index.ts";
 
 // ADR-0018 made the CORS default DENY. These assertions are about the CORS
@@ -388,6 +388,36 @@ console.log("\n--- Request Logger behaviour ---");
   assert("TINA4_LOG_REQUESTS=false silences even in dev", !offOut.includes("GET /widgets"));
 }
 
+// --- request logs carry the path, never the query string ---
+// createRequest sets req.url to the absolute URL with its query; codes and
+// tokens in it must not reach stdout or logs/tina4.log.
+console.log("\n--- Request log omits the query string ---");
+{
+  const { EventEmitter } = await import("node:events");
+  const secretUrl = "http://app.example/auth/callback?code=s3ntinel-code&token=s3ntinel-token";
+  const savedDebug = process.env.TINA4_DEBUG;
+  process.env.TINA4_DEBUG = "true";
+  let captured = "";
+  const orig = console.log;
+  console.log = (...a: unknown[]) => { captured += a.join(" ") + "\n"; };
+  try {
+    const raw: any = new EventEmitter();
+    raw.statusCode = 200;
+    requestLogger()({ method: "GET", url: secretUrl, path: "/auth/callback" } as any, { raw } as any, () => {});
+    raw.emit("finish");
+    const req: any = { method: "GET", url: secretUrl, path: "/auth/callback" };
+    RequestLogger.beforeLog(req, { raw } as any);
+    RequestLogger.afterLog(req, { raw } as any);
+  } finally {
+    console.log = orig;
+    if (savedDebug === undefined) delete process.env.TINA4_DEBUG;
+    else process.env.TINA4_DEBUG = savedDebug;
+  }
+  assert("requestLogger logs the path", captured.includes("GET /auth/callback -> 200 ("));
+  assert("RequestLogger class logs the path", /200\S* GET \/auth\/callback /.test(captured));
+  assert("neither logger writes the query string", !captured.includes("s3ntinel"));
+}
+
 // Summary
 console.log(`\n${"=".repeat(50)}`);
 console.log(`  Results: \x1b[32m${pass} passed\x1b[0m, \x1b[31m${fail} failed\x1b[0m`);

Source: NVD

Connexe JavaScript Vulnérabilités :

CVE ID

Gravité

Partition

Technologies

Nom du composant

Exploit CISA KEV

A corrigé

Date de publication

CVE-2026-120415MEDIUM5.9
  • JavaScript logoJavaScript
  • undici
NonOuiNov 05, 2026
CVE-2026-116630MEDIUM5.9
  • JavaScript logoJavaScript
  • undici
NonOuiNov 05, 2026
GHSA-9rmh-cqxg-g7fmLOWN/A
  • JavaScript logoJavaScript
  • tina4-nodejs
NonOuiNov 05, 2026
GHSA-685j-v6qp-54w7LOWN/A
  • JavaScript logoJavaScript
  • @tina4/core
NonOuiNov 05, 2026
GHSA-q2gc-fpw5-3v3cMEDIUMN/A
  • JavaScript logoJavaScript
  • tina4-python
NonOuiNov 05, 2026

Évaluation gratuite des vulnérabilités

Évaluez votre posture de sécurité cloud

Évaluez vos pratiques de sécurité cloud dans 9 domaines de sécurité afin d’évaluer votre niveau de risque et d’identifier les lacunes dans vos défenses.

Évaluation de la demande

Ressources Wiz supplémentaires

Obtenez une démo personnalisée

Prêt(e) à voir Wiz en action ?

"La meilleure expérience utilisateur que j’ai jamais vue, offre une visibilité totale sur les workloads cloud."
David EstlickRSSI
"Wiz fournit une interface unique pour voir ce qui se passe dans nos environnements cloud."
Adam FletcherChef du service de sécurité
"Nous savons que si Wiz identifie quelque chose comme critique, c’est qu’il l’est réellement."
Greg PoniatowskiResponsable de la gestion des menaces et des vulnérabilités