From 0c210f14baed991df8b381a0cfb5e1677209ef7c Mon Sep 17 00:00:00 2001 From: Huabing Zhao Date: Fri, 6 Sep 2024 00:48:17 +0800 Subject: [PATCH] Add nonce support to the oauth2 example verifications (#129) Signed-off-by: Huabing Zhao --- single-page-app/docker-compose.yml | 6 ++ single-page-app/verify.sh | 99 +++++++++++++++++++++++------- 2 files changed, 84 insertions(+), 21 deletions(-) diff --git a/single-page-app/docker-compose.yml b/single-page-app/docker-compose.yml index 3de32f45..ddc834bb 100644 --- a/single-page-app/docker-compose.yml +++ b/single-page-app/docker-compose.yml @@ -44,6 +44,12 @@ services: - ${SECRETS_PATH:-./secrets}:/etc/envoy/secrets - ${XDS_PATH:-./xds}:/var/lib/envoy - ${UI_PATH:-./ui}/dist:/var/www/html + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:10001"] + interval: 1s + timeout: 1s + retries: 5 + start_period: 1s myhub: build: diff --git a/single-page-app/verify.sh b/single-page-app/verify.sh index 645d1054..582917dd 100755 --- a/single-page-app/verify.sh +++ b/single-page-app/verify.sh @@ -118,29 +118,66 @@ test_auth () { "${proxy_scheme}://localhost:${proxy_port}" \ "${curl_args[@]}" + # To enhance security,the nonce will always be used in the OAuth2 flow once PR https://github.com/envoyproxy/envoy/pull/35919 is merged. + # Nonce-less verification will remain for backward compatibility with previous releases. + # TODO: zhaohuabing - Remove the nonce-less verification after a reasonable transition period, such as one year. + run_log "Check whether the nonce is used in the OAuth2 filter" + SUPPORT_NONCE="false" + LOCATION=$(_curl "${curl_args[@]}" --head "${proxy_scheme}://localhost:${proxy_port}/login" | grep location) + if [[ "$LOCATION" == *"nonce%3D"* ]]; then + SUPPORT_NONCE="true" + fi + run_log "Inititiate login" responds_with_header \ "HTTP/1.1 302 Found" \ "${proxy_scheme}://localhost:${proxy_port}/login" \ "${curl_args[@]}" - responds_with_header \ - "location: http://localhost:${PORT_MYHUB}/authorize?client_id=0123456789&redirect_uri=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Fauthorize&response_type=code&scope=user%3Aemail&state=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Flogin" \ - "${proxy_scheme}://localhost:${proxy_port}/login" \ - "${curl_args[@]}" + if [[ "$SUPPORT_NONCE" == "true" ]]; then + responds_with_header \ + "location: http://localhost:${PORT_MYHUB}/authorize?client_id=0123456789&redirect_uri=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Fauthorize&response_type=code&scope=user%3Aemail&state=url%3D${proxy_scheme}%253A%252F%252Flocalhost%253A${proxy_port}%252Flogin%26nonce%3D" \ + "${proxy_scheme}://localhost:${proxy_port}/login" \ + "${curl_args[@]}" + responds_with_header \ + "set-cookie: OauthNonce=" \ + "${proxy_scheme}://localhost:${proxy_port}/login" \ + "${curl_args[@]}" + else + responds_with_header \ + "location: http://localhost:${PORT_MYHUB}/authorize?client_id=0123456789&redirect_uri=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Fauthorize&response_type=code&scope=user%3Aemail&state=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Flogin" \ + "${proxy_scheme}://localhost:${proxy_port}/login" \ + "${curl_args[@]}" + fi run_log "Fetch the myhub authorization page" - responds_with_header \ - "HTTP/1.1 302 Found" \ - "http://localhost:${PORT_MYHUB}/authorize?client_id=0123456789&redirect_uri=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Fauthorize&response_type=code&scope=user%3Aemail&state=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Flogin" \ - "${curl_args[@]}" - responds_with_header \ - "Location: ${proxy_scheme}://localhost:${proxy_port}/authorize?code=" \ - "http://localhost:${PORT_MYHUB}/authorize?client_id=0123456789&redirect_uri=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Fauthorize&response_type=code&scope=user%3Aemail&state=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Flogin" \ - "${curl_args[@]}" + if [[ "$SUPPORT_NONCE" == "true" ]]; then + responds_with_header \ + "HTTP/1.1 302 Found" \ + "http://localhost:${PORT_MYHUB}/authorize?client_id=0123456789&redirect_uri=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Fauthorize&response_type=code&scope=user%3Aemail&state=url%3D${proxy_scheme}%253A%252F%252Flocalhost%253A${proxy_port}%252Flogin%26nonce%3D12345678" \ + "${curl_args[@]}" + responds_with_header \ + "Location: ${proxy_scheme}://localhost:${proxy_port}/authorize?code=" \ + "http://localhost:${PORT_MYHUB}/authorize?client_id=0123456789&redirect_uri=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Fauthorize&response_type=code&scope=user%3Aemail&state=url%3D${proxy_scheme}%253A%252F%252Flocalhost%253A${proxy_port}%252Flogin%26nonce%3D12345678" \ + "${curl_args[@]}" + else + responds_with_header \ + "HTTP/1.1 302 Found" \ + "http://localhost:${PORT_MYHUB}/authorize?client_id=0123456789&redirect_uri=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Fauthorize&response_type=code&scope=user%3Aemail&state=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Flogin" \ + "${curl_args[@]}" + responds_with_header \ + "Location: ${proxy_scheme}://localhost:${proxy_port}/authorize?code=" \ + "http://localhost:${PORT_MYHUB}/authorize?client_id=0123456789&redirect_uri=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Fauthorize&response_type=code&scope=user%3Aemail&state=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Flogin" \ + "${curl_args[@]}" + fi run_log "Return to the app and receive creds" - CODE=$(_curl "${curl_args[@]}" --head "http://localhost:${PORT_MYHUB}/authorize?client_id=0123456789&redirect_uri=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Fauthorize&response_type=code&scope=user%3Aemail&state=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Flogin" | grep Location | cut -d= -f2 | cut -d\& -f1) - RESPONSE=$(_curl "${curl_args[@]}" --head "${proxy_scheme}://localhost:${proxy_port}/authorize?code=$CODE&state=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Flogin") + if [[ "$SUPPORT_NONCE" == "true" ]]; then + CODE=$(_curl "${curl_args[@]}" --head "http://localhost:${PORT_MYHUB}/authorize?client_id=0123456789&redirect_uri=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Fauthorize&response_type=code&scope=user%3Aemail&state=url%3D${proxy_scheme}%253A%252F%252Flocalhost%253A${proxy_port}%252Flogin%26nonce%3D12345678" | grep Location | cut -d= -f2 | cut -d\& -f1) + RESPONSE=$(_curl "${curl_args[@]}" --cookie "OauthNonce=12345678" --head "${proxy_scheme}://localhost:${proxy_port}/authorize?code=$CODE&state=url%3D${proxy_scheme}%253A%252F%252Flocalhost%253A${proxy_port}%252Flogin%26nonce%3D12345678") + else + CODE=$(_curl "${curl_args[@]}" --head "http://localhost:${PORT_MYHUB}/authorize?client_id=0123456789&redirect_uri=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Fauthorize&response_type=code&scope=user%3Aemail&state=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Flogin" | grep Location | cut -d= -f2 | cut -d\& -f1) + RESPONSE=$(_curl "${curl_args[@]}" --head "${proxy_scheme}://localhost:${proxy_port}/authorize?code=$CODE&state=${proxy_scheme}%3A%2F%2Flocalhost%3A${proxy_port}%2Flogin") + fi echo "$RESPONSE" | grep "HTTP/1.1 302 Found" echo "$RESPONSE" | grep "location: ${proxy_scheme}://localhost:${proxy_port}/login" echo "$RESPONSE" | grep "set-cookie: OauthHMAC=" @@ -289,16 +326,36 @@ run_log "Inititiate dev login (Github)" responds_with_header \ "HTTP/1.1 302 Found" \ "http://localhost:${PORT_DEV_PROXY}/login" -responds_with_header \ - "location: https://github.com/login/oauth/authorize?client_id=XXX&redirect_uri=http%3A%2F%2Flocalhost%3A${PORT_DEV_PROXY}%2Fauthorize&response_type=code&scope=user%3Aemail&state=http%3A%2F%2Flocalhost%3A${PORT_DEV_PROXY}%2Flogin" \ - "http://localhost:${PORT_DEV_PROXY}/login" +if [[ "$SUPPORT_NONCE" == "true" ]]; then + responds_with_header \ + "location: https://github.com/login/oauth/authorize?client_id=XXX&redirect_uri=http%3A%2F%2Flocalhost%3A${PORT_DEV_PROXY}%2Fauthorize&response_type=code&scope=user%3Aemail&state=url%3Dhttp%253A%252F%252Flocalhost%253A${PORT_DEV_PROXY}%252Flogin%26nonce%3D" \ + "http://localhost:${PORT_DEV_PROXY}/login" + responds_with_header \ + "set-cookie: OauthNonce=" \ + "http://localhost:${PORT_DEV_PROXY}/login" +else + responds_with_header \ + "location: https://github.com/login/oauth/authorize?client_id=XXX&redirect_uri=http%3A%2F%2Flocalhost%3A${PORT_DEV_PROXY}%2Fauthorize&response_type=code&scope=user%3Aemail&state=http%3A%2F%2Flocalhost%3A${PORT_DEV_PROXY}%2Flogin" \ + "http://localhost:${PORT_DEV_PROXY}/login" +fi run_log "Test production app (Github)" responds_with \ "Envoy single page app example" \ "https://localhost:${PORT_PROXY}" \ -k -responds_with_header \ - "location: https://github.com/login/oauth/authorize?client_id=XXX&redirect_uri=https%3A%2F%2Flocalhost%3A${PORT_PROXY}%2Fauthorize&response_type=code&scope=user%3Aemail&state=https%3A%2F%2Flocalhost%3A${PORT_PROXY}%2Flogin" \ - "https://localhost:${PORT_PROXY}/login" \ - -k +if [[ "$SUPPORT_NONCE" == "true" ]]; then + responds_with_header \ + "location: https://github.com/login/oauth/authorize?client_id=XXX&redirect_uri=https%3A%2F%2Flocalhost%3A${PORT_PROXY}%2Fauthorize&response_type=code&scope=user%3Aemail&state=url%3Dhttps%253A%252F%252Flocalhost%253A${PORT_PROXY}%252Flogin%26nonce%3D" \ + "https://localhost:${PORT_PROXY}/login" \ + -k + responds_with_header \ + "set-cookie: OauthNonce=" \ + "https://localhost:${PORT_PROXY}/login" \ + -k +else + responds_with_header \ + "location: https://github.com/login/oauth/authorize?client_id=XXX&redirect_uri=https%3A%2F%2Flocalhost%3A${PORT_PROXY}%2Fauthorize&response_type=code&scope=user%3Aemail&state=https%3A%2F%2Flocalhost%3A${PORT_PROXY}%2Flogin" \ + "https://localhost:${PORT_PROXY}/login" \ + -k +fi