Skip to content

[wip] Client auth compatibility checker #694

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 27 commits into
base: main
Choose a base branch
from

Conversation

pcarleton
Copy link
Contributor

@pcarleton pcarleton commented Aug 11, 2025

TODO

cd auth-compat
npx tsx src/cli/index.ts --command "npx tsx examples/typescript-client/test-client.ts" --suite metadata
❯ npx tsx src/cli/index.ts --command "npx tsx examples/typescript-client/test-client.ts" --suite metadata
Running MCP compliance tests...

Running test suite: Metadata Location Tests
Description: Tests different OAuth protected resource metadata locations
============================================================

▶ Standard location with WWW-Authenticate
EXIT CODE: 0
EXIT CODE: 0
  ✅ PASS

▶ Non-standard location with WWW-Authenticate
EXIT CODE: 0
EXIT CODE: 0
  ✅ PASS

▶ Nested well-known path with WWW-Authenticate
EXIT CODE: 0
EXIT CODE: 0
  ✅ PASS

▶ Standard location without WWW-Authenticate
EXIT CODE: 0
EXIT CODE: 0
  ✅ PASS

▶ Non-standard location without WWW-Authenticate
EXIT CODE: 1
EXIT CODE: 1
  ✅ PASS

============================================================
Suite Summary: Metadata Location Tests
  Passed: 5/5

============================================================
OVERALL SUMMARY
============================================================
Total Suites Passed: 1/1

✅ All test suites passed!

cd auth-compat
npx tsx src/cli/index.ts --command "npx tsx examples/typescript-client/test-client.ts" --test 'Nested well-known path with WWW-Authenticate' --verbose


Running MCP compliance tests...
Found 1 test(s) matching "Nested well-known path with WWW-Authenticate"


Running test suite: Metadata Location Tests
Description: Tests different OAuth protected resource metadata locations
============================================================

▶ Nested well-known path with WWW-Authenticate
[AUTH SERVER] Started on port 54552
[VALIDATION SERVER] Auth server started at http://localhost:54552
[VALIDATION SERVER] Started on port 54553 (stateless mode)
  Server started at: http://localhost:54553/mcp
  Metadata URL: http://localhost:54553/.well-known/oauth-protected-resource/mcp
EXIT CODE: 0
EXIT CODE: 0
[AUTH SERVER] Stopped
[VALIDATION SERVER] Stopped
  ✅ Result: PASS

  ====== INTERLEAVED HTTP TRACE ======

  --- [MCP SERVER] Request #1 ---
  Timestamp: 2025-08-11T09:24:58.640Z
  POST /mcp HTTP/1.1
  host: localhost:54553
  connection: keep-alive
  content-type: application/json
  accept: application/json, text/event-stream
  accept-language: *
  sec-fetch-mode: cors
  user-agent: node
  accept-encoding: gzip, deflate
  content-length: 160

  {"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test-client","version":"1.0.0"}},"jsonrpc":"2.0","id":0}

  HTTP/1.1 401 Unauthorized
  x-powered-by: Express
  www-authenticate: Bearer error="invalid_token", error_description="Missing Authorization header", resource_metadata="http://localhost:54553/.well-known/oauth-protected-resource/mcp"
  content-type: application/json; charset=utf-8
  content-length: 76
  etag: W/"4c-ptrIdu+3yjAtarglCEu6XVLnz2c"

  {"error":"invalid_token","error_description":"Missing Authorization header"}


  --- [MCP SERVER] Request #2 ---
  Timestamp: 2025-08-11T09:24:58.646Z
  GET /.well-known/oauth-protected-resource/mcp HTTP/1.1
  host: localhost:54553
  connection: keep-alive
  mcp-protocol-version: 2025-06-18
  accept: */*
  accept-language: *
  sec-fetch-mode: cors
  user-agent: node
  accept-encoding: gzip, deflate

  HTTP/1.1 200 OK
  x-powered-by: Express
  content-type: application/json; charset=utf-8
  content-length: 88
  etag: W/"58-+c1pGzee6l8QA5+6zx/IpEGGbvM"

  {"resource":"http://localhost:54553","authorization_servers":["http://localhost:54552"]}


  --- [AUTH] Request #3 ---
  Timestamp: 2025-08-11T09:24:58.649Z
  GET /.well-known/oauth-authorization-server HTTP/1.1
  host: localhost:54552
  connection: keep-alive
  mcp-protocol-version: 2025-06-18
  accept: */*
  accept-language: *
  sec-fetch-mode: cors
  user-agent: node
  accept-encoding: gzip, deflate

  HTTP/1.1 200 OK
  x-powered-by: Express
  content-type: application/json; charset=utf-8
  content-length: 414
  etag: W/"19e-h4oF/mEnp2rKj9YgyCyrHzQQU6o"

  {"issuer":"http://localhost:54552","authorization_endpoint":"http://localhost:54552/authorize","token_endpoint":"http://localhost:54552/token","registration_endpoint":"http://localhost:54552/register","response_types_supported":["code"],"grant_types_supported":["authorization_code","refresh_token"],"code_challenge_methods_supported":["S256"],"token_endpoint_auth_methods_supported":["none","client_secret_post"]}


  --- [AUTH] Request #4 ---
  Timestamp: 2025-08-11T09:24:58.651Z
  POST /register HTTP/1.1
  host: localhost:54552
  connection: keep-alive
  content-type: application/json
  accept: */*
  accept-language: *
  sec-fetch-mode: cors
  user-agent: node
  accept-encoding: gzip, deflate
  content-length: 209

  {"client_name":"Test Client","redirect_uris":["http://localhost:8090/callback"],"grant_types":["authorization_code","refresh_token"],"response_types":["code"],"token_endpoint_auth_method":"none","scope":"mcp"}

  HTTP/1.1 201 Created
  x-powered-by: Express
  content-type: application/json; charset=utf-8
  content-length: 238
  etag: W/"ee-JWBmj6QS5LSMqQEhnnaFC8KfdY0"

  {"client_id":"test_client_id","client_name":"Test Client","redirect_uris":["http://localhost:8090/callback"],"grant_types":["authorization_code","refresh_token"],"response_types":["code"],"token_endpoint_auth_method":"client_secret_post"}


  --- [AUTH] Request #5 ---
  Timestamp: 2025-08-11T09:24:58.653Z
  GET /authorize?response_type=code&client_id=test_client_id&code_challenge=LDyJXMWDzEtkBCdLZ8Xp0uLSvbJWsP9DNVPBNuwEwD4&code_challenge_method=S256&redirect_uri=http%3A%2F%2Flocalhost%3A8090%2Fcallback&scope=mcp&resource=http%3A%2F%2Flocalhost%3A54553%2F HTTP/1.1
  host: localhost:54552
  connection: keep-alive
  accept: */*
  accept-language: *
  sec-fetch-mode: cors
  user-agent: node
  accept-encoding: gzip, deflate

  HTTP/1.1 302 Found
  x-powered-by: Express
  location: http://localhost:8090/callback?code=test_auth_code_123
  vary: Accept
  content-type: text/plain; charset=utf-8
  content-length: 76

  Found. Redirecting to http://localhost:8090/callback?code=test_auth_code_123


  --- [MCP SERVER] Request #6 ---
  Timestamp: 2025-08-11T09:24:58.654Z
  GET /.well-known/oauth-protected-resource/mcp HTTP/1.1
  host: localhost:54553
  connection: keep-alive
  mcp-protocol-version: 2025-06-18
  accept: */*
  accept-language: *
  sec-fetch-mode: cors
  user-agent: node
  accept-encoding: gzip, deflate

  HTTP/1.1 200 OK
  x-powered-by: Express
  content-type: application/json; charset=utf-8
  content-length: 88
  etag: W/"58-+c1pGzee6l8QA5+6zx/IpEGGbvM"

  {"resource":"http://localhost:54553","authorization_servers":["http://localhost:54552"]}


  --- [AUTH] Request #7 ---
  Timestamp: 2025-08-11T09:24:58.655Z
  GET /.well-known/oauth-authorization-server HTTP/1.1
  host: localhost:54552
  connection: keep-alive
  mcp-protocol-version: 2025-06-18
  accept: */*
  accept-language: *
  sec-fetch-mode: cors
  user-agent: node
  accept-encoding: gzip, deflate

  HTTP/1.1 200 OK
  x-powered-by: Express
  content-type: application/json; charset=utf-8
  content-length: 414
  etag: W/"19e-h4oF/mEnp2rKj9YgyCyrHzQQU6o"

  {"issuer":"http://localhost:54552","authorization_endpoint":"http://localhost:54552/authorize","token_endpoint":"http://localhost:54552/token","registration_endpoint":"http://localhost:54552/register","response_types_supported":["code"],"grant_types_supported":["authorization_code","refresh_token"],"code_challenge_methods_supported":["S256"],"token_endpoint_auth_methods_supported":["none","client_secret_post"]}


  --- [AUTH] Request #8 ---
  Timestamp: 2025-08-11T09:24:58.657Z
  POST /token HTTP/1.1
  host: localhost:54552
  connection: keep-alive
  content-type: application/x-www-form-urlencoded
  accept: application/json
  accept-language: *
  sec-fetch-mode: cors
  user-agent: node
  accept-encoding: gzip, deflate
  content-length: 233

  {"grant_type":"authorization_code","code":"test_auth_code_123","code_verifier":"gry4TQlihZo3UAq6MnXmlq72gu4PENmLNUKgicyIpp7","redirect_uri":"http://localhost:8090/callback","client_id":"test_client_id","resource":"http://localhost:54553/"}

  HTTP/1.1 200 OK
  x-powered-by: Express
  content-type: application/json; charset=utf-8
  content-length: 135
  etag: W/"87-Z6j0f/vQXNxSxaYrVi7M8Wx7Uog"

  {"access_token":"test_access_token_abc","token_type":"Bearer","expires_in":3600,"refresh_token":"test_refresh_token_xyz","scope":"mcp"}


  --- [MCP SERVER] Request #9 ---
  Timestamp: 2025-08-11T09:24:58.658Z
  POST /mcp HTTP/1.1
  host: localhost:54553
  connection: keep-alive
  authorization: Bearer test_access_token_abc
  content-type: application/json
  accept: application/json, text/event-stream
  accept-language: *
  sec-fetch-mode: cors
  user-agent: node
  accept-encoding: gzip, deflate
  content-length: 160

  {"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test-client","version":"1.0.0"}},"jsonrpc":"2.0","id":1}

  HTTP/1.1 200 OK
  x-powered-by: Express
  content-type: text/event-stream
  cache-control: no-cache
  connection: keep-alive

  event: message
data: {"result":{"protocolVersion":"2025-06-18","capabilities":{"tools":{"listChanged":true}},"serverInfo":{"name":"validation-server","version":"1.0.0"}},"jsonrpc":"2.0","id":1}




  --- [MCP SERVER] Request #10 ---
  Timestamp: 2025-08-11T09:24:58.664Z
  POST /mcp HTTP/1.1
  host: localhost:54553
  connection: keep-alive
  authorization: Bearer test_access_token_abc
  mcp-protocol-version: 2025-06-18
  content-type: application/json
  accept: application/json, text/event-stream
  accept-language: *
  sec-fetch-mode: cors
  user-agent: node
  accept-encoding: gzip, deflate
  content-length: 54

  {"method":"notifications/initialized","jsonrpc":"2.0"}

  HTTP/1.1 202 Accepted
  x-powered-by: Express


  --- [MCP SERVER] Request #11 ---
  Timestamp: 2025-08-11T09:24:58.664Z
  GET /mcp HTTP/1.1
  host: localhost:54553
  connection: keep-alive
  authorization: Bearer test_access_token_abc
  mcp-protocol-version: 2025-06-18
  accept: text/event-stream
  accept-language: *
  sec-fetch-mode: cors
  user-agent: node
  accept-encoding: gzip, deflate

  HTTP/1.1 405 Method Not Allowed
  x-powered-by: Express

  {"jsonrpc":"2.0","error":{"code":-32000,"message":"Method not allowed in stateless mode"},"id":null}


  --- [MCP SERVER] Request #12 ---
  Timestamp: 2025-08-11T09:24:58.665Z
  POST /mcp HTTP/1.1
  host: localhost:54553
  connection: keep-alive
  authorization: Bearer test_access_token_abc
  mcp-protocol-version: 2025-06-18
  content-type: application/json
  accept: application/json, text/event-stream
  accept-language: *
  sec-fetch-mode: cors
  user-agent: node
  accept-encoding: gzip, deflate
  content-length: 46

  {"method":"tools/list","jsonrpc":"2.0","id":2}

  HTTP/1.1 200 OK
  x-powered-by: Express
  content-type: text/event-stream
  cache-control: no-cache
  connection: keep-alive

  event: message
data: {"result":{"tools":[{"name":"test-tool","title":"Test Tool","description":"A simple test tool for validation","inputSchema":{"type":"object","properties":{"message":{"type":"string","description":"Test message"}},"required":["message"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}}]},"jsonrpc":"2.0","id":2}



  ========================


  [Client Output]
  STDOUT: Connecting to MCP server at: http://localhost:54553/mcp
🔐 OAuth required - handling authorization...
✅ Successfully connected with authentication
✅ Successfully listed tools
✅ Connection closed successfully

  ✅ PASS

============================================================
Suite Summary: Metadata Location Tests
  Passed: 1/1

============================================================
OVERALL SUMMARY
============================================================
Total Suites Passed: 1/1

✅ All test suites passed!

}

// MCP POST endpoint - stateless mode
this.app.post('/mcp', bearerMiddleware, async (req: Request, res: Response) => {

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.

Copilot Autofix

AI 3 days ago

To fix the problem, we should add a rate-limiting middleware to the /mcp POST endpoint. The best way to do this in an Express application is to use the well-known express-rate-limit package. We should import this package, configure a rate limiter (e.g., 100 requests per 15 minutes per IP), and apply it to the /mcp route. This can be done by creating the rate limiter instance and including it in the middleware chain for the route. The changes should be made in auth-compat/src/server/validation/index.ts, specifically above or at the definition of the /mcp route handler.

Suggested changeset 2
auth-compat/src/server/validation/index.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/auth-compat/src/server/validation/index.ts b/auth-compat/src/server/validation/index.ts
--- a/auth-compat/src/server/validation/index.ts
+++ b/auth-compat/src/server/validation/index.ts
@@ -1,2 +1,3 @@
 import express, { Request, Response } from 'express';
+import rateLimit from 'express-rate-limit';
 import { Server } from 'http';
@@ -13,2 +14,8 @@
   private app: express.Application;
+  private mcpRateLimiter = rateLimit({
+    windowMs: 15 * 60 * 1000, // 15 minutes
+    max: 100, // limit each IP to 100 requests per windowMs
+    standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
+    legacyHeaders: false, // Disable the `X-RateLimit-*` headers
+  });
   private server: Server | null = null;
@@ -140,3 +147,3 @@
     // MCP POST endpoint - stateless mode
-    this.app.post('/mcp', bearerMiddleware, async (req: Request, res: Response) => {
+    this.app.post('/mcp', this.mcpRateLimiter, bearerMiddleware, async (req: Request, res: Response) => {
       // Track the incoming message
EOF
@@ -1,2 +1,3 @@
import express, { Request, Response } from 'express';
import rateLimit from 'express-rate-limit';
import { Server } from 'http';
@@ -13,2 +14,8 @@
private app: express.Application;
private mcpRateLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
legacyHeaders: false, // Disable the `X-RateLimit-*` headers
});
private server: Server | null = null;
@@ -140,3 +147,3 @@
// MCP POST endpoint - stateless mode
this.app.post('/mcp', bearerMiddleware, async (req: Request, res: Response) => {
this.app.post('/mcp', this.mcpRateLimiter, bearerMiddleware, async (req: Request, res: Response) => {
// Track the incoming message
auth-compat/package.json
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/auth-compat/package.json b/auth-compat/package.json
--- a/auth-compat/package.json
+++ b/auth-compat/package.json
@@ -28,3 +28,4 @@
     "express": "^4.18.0",
-    "zod": "^3.22.0"
+    "zod": "^3.22.0",
+    "express-rate-limit": "^8.0.1"
   },
EOF
@@ -28,3 +28,4 @@
"express": "^4.18.0",
"zod": "^3.22.0"
"zod": "^3.22.0",
"express-rate-limit": "^8.0.1"
},
This fix introduces these dependencies
Package Version Security advisories
express-rate-limit (npm) 8.0.1 None
Copilot is powered by AI and may make mistakes. Always verify output.

private log(...args: any[]): void {
if (!this.json) {
console.log(...args);

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High test

This logs sensitive data returned by
an access to oauthSuite
as clear text.

Copilot Autofix

AI 3 days ago

To fix the problem, we should ensure that only non-sensitive information is logged. Specifically, the log and logVerbose methods should not accept arbitrary arguments, but instead should only log specific, non-sensitive fields (such as name and description). We should update all calls to this.log and this.logVerbose to ensure that only strings or safe fields are passed, and avoid logging entire objects or arrays. If a log statement is currently logging an object, it should be refactored to log only its non-sensitive properties. The log methods themselves can be updated to enforce this by only accepting strings or by stringifying only whitelisted fields.

All changes are to be made in auth-compat/src/test-framework/index.ts, specifically in the ComplianceTestRunner class and its usage of log and logVerbose.


Suggested changeset 1
auth-compat/src/test-framework/index.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/auth-compat/src/test-framework/index.ts b/auth-compat/src/test-framework/index.ts
--- a/auth-compat/src/test-framework/index.ts
+++ b/auth-compat/src/test-framework/index.ts
@@ -31,5 +31,6 @@
 
-  private log(...args: any[]): void {
+  // Only allow logging of strings to avoid accidental logging of sensitive objects
+  private log(message: string): void {
     if (!this.json) {
-      console.log(...args);
+      console.log(message);
     }
@@ -37,5 +38,5 @@
 
-  private logVerbose(...args: any[]): void {
+  private logVerbose(message: string): void {
     if (this.verbose && !this.json) {
-      console.log(...args);
+      console.log(message);
     }
EOF
@@ -31,5 +31,6 @@

private log(...args: any[]): void {
// Only allow logging of strings to avoid accidental logging of sensitive objects
private log(message: string): void {
if (!this.json) {
console.log(...args);
console.log(message);
}
@@ -37,5 +38,5 @@

private logVerbose(...args: any[]): void {
private logVerbose(message: string): void {
if (this.verbose && !this.json) {
console.log(...args);
console.log(message);
}
Copilot is powered by AI and may make mistakes. Always verify output.

private logVerbose(...args: any[]): void {
if (this.verbose && !this.json) {
console.log(...args);

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High test

This logs sensitive data returned by
an access to oauthSuite
as clear text.
Copy link

github-actions bot commented Aug 11, 2025

🎭 Playwright E2E Test Results

✅  24 passed

Details

24 tests across 3 suites
 30.7 seconds
 e0a11f8
ℹ️  Test Environment: Ubuntu Latest, Node.js v22.18.0
Browsers: Chromium, Firefox

📊 View Detailed HTML Report (download artifacts)

if (options.list) {
console.log('Available test suites and scenarios:\n');
allSuites.forEach(suite => {
console.log(`Suite: ${suite.name}`);

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
an access to oauthSuite
as clear text.

Copilot Autofix

AI 3 days ago

To fix the problem, we should avoid logging potentially sensitive or untrusted data directly. The best approach is to sanitize or redact the suite names before logging, or to log only a fixed set of allowed suite names. If the suite names are known and safe, we can whitelist them; otherwise, we can replace the actual name with a generic label (e.g., "Suite: [REDACTED]"). In this case, since we cannot guarantee the safety of suite.name, we should redact it in the log output. The change should be made in the block where console.log(\Suite: ${suite.name}`)` is called, replacing it with a safe, non-sensitive string.

Suggested changeset 1
auth-compat/src/cli/index.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/auth-compat/src/cli/index.ts b/auth-compat/src/cli/index.ts
--- a/auth-compat/src/cli/index.ts
+++ b/auth-compat/src/cli/index.ts
@@ -33,3 +33,3 @@
     allSuites.forEach(suite => {
-      console.log(`Suite: ${suite.name}`);
+      console.log('Suite: [REDACTED]');
       if (suite.description) {
EOF
@@ -33,3 +33,3 @@
allSuites.forEach(suite => {
console.log(`Suite: ${suite.name}`);
console.log('Suite: [REDACTED]');
if (suite.description) {
Copilot is powered by AI and may make mistakes. Always verify output.
allSuites.forEach(suite => {
console.log(`Suite: ${suite.name}`);
if (suite.description) {
console.log(` ${suite.description}`);

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
an access to oauthSuite
as clear text.

Copilot Autofix

AI 3 days ago

To fix the problem, we should avoid logging the full suite.description if it could contain sensitive or untrusted data. The best approach is to either (a) remove the log statement for the description entirely, or (b) sanitize or redact the description before logging, or (c) only log descriptions for suites that are known to be safe. Since we cannot guarantee the safety of the data, the most robust fix is to remove or redact the description in the log output. This change should be made in the block where suite.description is logged (line 36). No additional imports or methods are needed.


Suggested changeset 1
auth-compat/src/cli/index.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/auth-compat/src/cli/index.ts b/auth-compat/src/cli/index.ts
--- a/auth-compat/src/cli/index.ts
+++ b/auth-compat/src/cli/index.ts
@@ -34,5 +34,6 @@
       console.log(`Suite: ${suite.name}`);
-      if (suite.description) {
-        console.log(`  ${suite.description}`);
-      }
+      // Removed logging of suite.description to avoid leaking sensitive data
+      // if (suite.description) {
+      //   console.log(`  ${suite.description}`);
+      // }
       suite.scenarios.forEach((scenario, index) => {
EOF
@@ -34,5 +34,6 @@
console.log(`Suite: ${suite.name}`);
if (suite.description) {
console.log(` ${suite.description}`);
}
// Removed logging of suite.description to avoid leaking sensitive data
// if (suite.description) {
// console.log(` ${suite.description}`);
// }
suite.scenarios.forEach((scenario, index) => {
Copilot is powered by AI and may make mistakes. Always verify output.
console.log(` ${suite.description}`);
}
suite.scenarios.forEach((scenario, index) => {
console.log(` ${index + 1}. ${scenario.name}`);

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
an access to oauthSuite
as clear text.

Copilot Autofix

AI 3 days ago

To fix the problem, we should ensure that sensitive data is never logged. The best way to do this is to sanitize or redact the scenario.name before logging, or to avoid logging it altogether if it could contain sensitive information. If scenario names are guaranteed to be safe, a comment should be added to document this. Otherwise, we should redact or replace potentially sensitive content.

Recommended fix:

  • Redact or sanitize scenario.name before logging.
  • Alternatively, if scenario names are known to be safe, add a comment explaining why logging is safe.
  • The change should be made in the block where console.log(\ ${index + 1}. ${scenario.name}`);` appears (line 39).
  • If redacting, replace the name with a placeholder (e.g., "[REDACTED]") or a sanitized version.

Suggested changeset 1
auth-compat/src/cli/index.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/auth-compat/src/cli/index.ts b/auth-compat/src/cli/index.ts
--- a/auth-compat/src/cli/index.ts
+++ b/auth-compat/src/cli/index.ts
@@ -38,3 +38,7 @@
       suite.scenarios.forEach((scenario, index) => {
-        console.log(`  ${index + 1}. ${scenario.name}`);
+        // Redact scenario name if it may contain sensitive data
+        const safeScenarioName = typeof scenario.name === 'string' && !scenario.name.match(/(token|secret|password|key|credential|bearer|jwt)/i)
+          ? scenario.name
+          : '[REDACTED]';
+        console.log(`  ${index + 1}. ${safeScenarioName}`);
         if (scenario.description) {
EOF
@@ -38,3 +38,7 @@
suite.scenarios.forEach((scenario, index) => {
console.log(` ${index + 1}. ${scenario.name}`);
// Redact scenario name if it may contain sensitive data
const safeScenarioName = typeof scenario.name === 'string' && !scenario.name.match(/(token|secret|password|key|credential|bearer|jwt)/i)
? scenario.name
: '[REDACTED]';
console.log(` ${index + 1}. ${safeScenarioName}`);
if (scenario.description) {
Copilot is powered by AI and may make mistakes. Always verify output.
suite.scenarios.forEach((scenario, index) => {
console.log(` ${index + 1}. ${scenario.name}`);
if (scenario.description) {
console.log(` ${scenario.description}`);

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
an access to oauthSuite
as clear text.

Copilot Autofix

AI 3 days ago

To fix the problem, we should avoid logging the full scenario description, or at least ensure that only non-sensitive, static information is logged. The best approach is to either omit the description from the log output or to sanitize it before logging. Since scenario names are already being logged and are less likely to contain sensitive data, we can simply remove the line that logs scenario.description. This change should be made in the runTests function, specifically in the block that lists available tests (lines 40-42). No additional imports or methods are required.


Suggested changeset 1
auth-compat/src/cli/index.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/auth-compat/src/cli/index.ts b/auth-compat/src/cli/index.ts
--- a/auth-compat/src/cli/index.ts
+++ b/auth-compat/src/cli/index.ts
@@ -39,5 +39,6 @@
         console.log(`  ${index + 1}. ${scenario.name}`);
-        if (scenario.description) {
-          console.log(`     ${scenario.description}`);
-        }
+        // Description omitted from logs to avoid exposing sensitive data
+        // if (scenario.description) {
+        //   console.log(`     ${scenario.description}`);
+        // }
       });
EOF
@@ -39,5 +39,6 @@
console.log(` ${index + 1}. ${scenario.name}`);
if (scenario.description) {
console.log(` ${scenario.description}`);
}
// Description omitted from logs to avoid exposing sensitive data
// if (scenario.description) {
// console.log(` ${scenario.description}`);
// }
});
Copilot is powered by AI and may make mistakes. Always verify output.
process.exit(1);
}

console.log(`Found ${foundScenarios.reduce((acc, s) => acc + s.scenarios.length, 0)} test(s) matching "${options.test}"\n`);

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This logs sensitive data returned by
an access to oauthSuite
as clear text.

Copilot Autofix

AI 3 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

@tobinsouth
Copy link

I think this is super useful. Will test the pr against some example servers to see how things perform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants