From 608bc6e837bf523c89faaad0d313e70a43045aee Mon Sep 17 00:00:00 2001 From: Bobby Ho Date: Tue, 30 Jun 2026 08:02:55 -0700 Subject: [PATCH] fix(scripts/oauth2): fix test-mcp-oauth2.sh for macOS and OAuth 2.1 compliance (#26825) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `test-mcp-oauth2.sh` script had three bugs that caused tests 2, 3, and 4 to fail when run on macOS. `grep -oP` uses PCRE lookbehind (`\K`), which is not supported by BSD grep on macOS. Replaced with `grep -oE … | sed 's/code=//'` which works on both platforms. The token exchange requests in tests 2, 3, and 4 omitted `redirect_uri`, which is required by RFC 6749 §4.1.3 whenever `redirect_uri` was included in the authorization request. The server correctly rejects these with `invalid_grant`, masking the actual PKCE validation. Test 4's resource parameter flow was missing PKCE parameters entirely. The server enforces PKCE on all authorization code flows per OAuth 2.1, so the authorization request returned 400 and the script exited silently due to `set -euo pipefail`. --- scripts/oauth2/test-mcp-oauth2.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/scripts/oauth2/test-mcp-oauth2.sh b/scripts/oauth2/test-mcp-oauth2.sh index 4585cab499..9139010f6a 100755 --- a/scripts/oauth2/test-mcp-oauth2.sh +++ b/scripts/oauth2/test-mcp-oauth2.sh @@ -77,7 +77,7 @@ REDIRECT_URL=$(curl -s -X POST "$AUTH_URL" \ -w '\n%{redirect_url}' \ -o /dev/null) -CODE=$(echo "$REDIRECT_URL" | grep -oP 'code=\K[^&]+') +CODE=$(echo "$REDIRECT_URL" | grep -oE 'code=[^&]+' | sed 's/code=//') if [ -n "$CODE" ]; then echo -e "${GREEN}✓ Got authorization code with PKCE${NC}" @@ -93,6 +93,7 @@ TOKEN_RESPONSE=$(curl -s -X POST "$BASE_URL/oauth2/tokens" \ -d "code=$CODE" \ -d "client_id=$CLIENT_ID" \ -d "client_secret=$CLIENT_SECRET" \ + -d "redirect_uri=http://localhost:9876/callback" \ -d "code_verifier=$CODE_VERIFIER") if echo "$TOKEN_RESPONSE" | jq -e '.access_token' >/dev/null; then @@ -110,7 +111,7 @@ REDIRECT_URL=$(curl -s -X POST "$AUTH_URL" \ -H "Coder-Session-Token: $SESSION_TOKEN" \ -w '\n%{redirect_url}' \ -o /dev/null) -CODE=$(echo "$REDIRECT_URL" | grep -oP 'code=\K[^&]+') +CODE=$(echo "$REDIRECT_URL" | grep -oE 'code=[^&]+' | sed 's/code=//') ERROR_RESPONSE=$(curl -s -X POST "$BASE_URL/oauth2/tokens" \ -H "Content-Type: application/x-www-form-urlencoded" \ @@ -118,6 +119,7 @@ ERROR_RESPONSE=$(curl -s -X POST "$BASE_URL/oauth2/tokens" \ -d "code=$CODE" \ -d "client_id=$CLIENT_ID" \ -d "client_secret=$CLIENT_SECRET" \ + -d "redirect_uri=http://localhost:9876/callback" \ -d "code_verifier=wrong-verifier") if echo "$ERROR_RESPONSE" | jq -e '.error' >/dev/null; then @@ -130,14 +132,16 @@ fi echo -e "${YELLOW}Test 4: Resource Parameter Support${NC}" RESOURCE="https://api.example.com" STATE=$(openssl rand -hex 16) -RESOURCE_AUTH_URL="$BASE_URL/oauth2/authorize?client_id=$CLIENT_ID&response_type=code&redirect_uri=http://localhost:9876/callback&state=$STATE&resource=$RESOURCE" +RESOURCE_CODE_VERIFIER=$(openssl rand -base64 32 | tr -d "=+/" | cut -c -43) +RESOURCE_CODE_CHALLENGE=$(echo -n "$RESOURCE_CODE_VERIFIER" | openssl dgst -sha256 -binary | base64 | tr -d "=" | tr '+/' '-_') +RESOURCE_AUTH_URL="$BASE_URL/oauth2/authorize?client_id=$CLIENT_ID&response_type=code&redirect_uri=http://localhost:9876/callback&state=$STATE&resource=$RESOURCE&code_challenge=$RESOURCE_CODE_CHALLENGE&code_challenge_method=S256" REDIRECT_URL=$(curl -s -X POST "$RESOURCE_AUTH_URL" \ -H "Coder-Session-Token: $SESSION_TOKEN" \ -w '\n%{redirect_url}' \ -o /dev/null) -CODE=$(echo "$REDIRECT_URL" | grep -oP 'code=\K[^&]+') +CODE=$(echo "$REDIRECT_URL" | grep -oE 'code=[^&]+' | sed 's/code=//') TOKEN_RESPONSE=$(curl -s -X POST "$BASE_URL/oauth2/tokens" \ -H "Content-Type: application/x-www-form-urlencoded" \ @@ -145,6 +149,8 @@ TOKEN_RESPONSE=$(curl -s -X POST "$BASE_URL/oauth2/tokens" \ -d "code=$CODE" \ -d "client_id=$CLIENT_ID" \ -d "client_secret=$CLIENT_SECRET" \ + -d "redirect_uri=http://localhost:9876/callback" \ + -d "code_verifier=$RESOURCE_CODE_VERIFIER" \ -d "resource=$RESOURCE") if echo "$TOKEN_RESPONSE" | jq -e '.access_token' >/dev/null; then