From d1c20bdff75d96a72ee0fe004c01a606df933c23 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 20 Oct 2020 00:40:46 +0200 Subject: [PATCH] fix: localhost API access via ipv6 This adds localhost ipv6 addresses to the allowlist for use in browser context and fixes WebUI on ipv6-only deployments: http://[::1]:5001/webui We were missing CORS/Origin tests for API port so I've added basic ones and included localhost/127.0.0.1/::1 variants. --- core/corehttp/commands.go | 2 + test/sharness/t0112-gateway-cors.sh | 7 -- ...pi-security.sh => t0400-api-no-gateway.sh} | 0 test/sharness/t0401-api-browser-security.sh | 69 +++++++++++++++++++ 4 files changed, 71 insertions(+), 7 deletions(-) rename test/sharness/{t0400-api-security.sh => t0400-api-no-gateway.sh} (100%) create mode 100755 test/sharness/t0401-api-browser-security.sh diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go index 0f9b8d603..c5443f6eb 100644 --- a/core/corehttp/commands.go +++ b/core/corehttp/commands.go @@ -40,6 +40,8 @@ const APIPath = "/api/v0" var defaultLocalhostOrigins = []string{ "http://127.0.0.1:", "https://127.0.0.1:", + "http://[::1]:", + "https://[::1]:", "http://localhost:", "https://localhost:", } diff --git a/test/sharness/t0112-gateway-cors.sh b/test/sharness/t0112-gateway-cors.sh index c7c5c3e40..9670b7ffa 100755 --- a/test/sharness/t0112-gateway-cors.sh +++ b/test/sharness/t0112-gateway-cors.sh @@ -6,16 +6,9 @@ test_description="Test HTTP Gateway CORS Support" -test_config_ipfs_cors_headers() { - ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]' - ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST"]' - ipfs config --json API.HTTPHeaders.Access-Control-Allow-Headers '["X-Requested-With"]' -} - . lib/test-lib.sh test_init_ipfs -test_config_ipfs_cors_headers test_launch_ipfs_daemon thash='QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn' diff --git a/test/sharness/t0400-api-security.sh b/test/sharness/t0400-api-no-gateway.sh similarity index 100% rename from test/sharness/t0400-api-security.sh rename to test/sharness/t0400-api-no-gateway.sh diff --git a/test/sharness/t0401-api-browser-security.sh b/test/sharness/t0401-api-browser-security.sh new file mode 100755 index 000000000..1e36bcead --- /dev/null +++ b/test/sharness/t0401-api-browser-security.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2020 Protocol Labs +# MIT Licensed; see the LICENSE file in this repository. +# + +test_description="Test API browser security" + +. lib/test-lib.sh + +test_init_ipfs + +PEERID=$(ipfs config Identity.PeerID) + +test_launch_ipfs_daemon + +test_expect_success "browser is unable to access API without Origin" ' + curl -sD - -X POST -A "Mozilla" "http://127.0.0.1:$API_PORT/api/v0/id" >curl_output && + grep "HTTP/1.1 403 Forbidden" curl_output +' + +test_expect_success "browser is unable to access API with invalid Origin" ' + curl -sD - -X POST -A "Mozilla" -H "Origin: https://invalid.example.com" "http://127.0.0.1:$API_PORT/api/v0/id" >curl_output && + grep "HTTP/1.1 403 Forbidden" curl_output +' + +test_expect_success "browser is able to access API if Origin is the API port on localhost (ipv4)" ' + curl -sD - -X POST -A "Mozilla" -H "Origin: http://127.0.0.1:$API_PORT" "http://127.0.0.1:$API_PORT/api/v0/id" >curl_output && + grep "HTTP/1.1 200 OK" curl_output && grep "$PEERID" curl_output +' + +test_expect_success "browser is able to access API if Origin is the API port on localhost (ipv6)" ' + curl -sD - -X POST -A "Mozilla" -H "Origin: http://[::1]:$API_PORT" "http://127.0.0.1:$API_PORT/api/v0/id" >curl_output && + grep "HTTP/1.1 200 OK" curl_output && grep "$PEERID" curl_output +' + +test_expect_success "browser is able to access API if Origin is the API port on localhost (localhost name)" ' + curl -sD - -X POST -A "Mozilla" -H "Origin: http://localhost:$API_PORT" "http://127.0.0.1:$API_PORT/api/v0/id" >curl_output && + grep "HTTP/1.1 200 OK" curl_output && grep "$PEERID" curl_output +' + +test_kill_ipfs_daemon + +test_expect_success "setting CORS in API.HTTPHeaders works via CLI" " + ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '[\"https://valid.example.com\"]' && + ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '[\"POST\"]' && + ipfs config --json API.HTTPHeaders.Access-Control-Allow-Headers '[\"X-Requested-With\"]' +" + +test_launch_ipfs_daemon + +# https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request +test_expect_success "OPTIONS with preflight request to API with CORS allowlist succeeds" ' + curl -svX OPTIONS -A "Mozilla" -H "Origin: https://valid.example.com" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: origin, x-requested-with" "http://127.0.0.1:$API_PORT/api/v0/id" 2>curl_output && + cat curl_output +' + +# OPTION Response from Gateway should contain CORS headers, otherwise JS won't work +test_expect_success "OPTIONS response for API with CORS allowslist looks good" ' + grep "< Access-Control-Allow-Origin: https://valid.example.com" curl_output +' + +test_expect_success "browser is able to access API with valid Origin matching CORS allowlist" ' + curl -sD - -X POST -A "Mozilla" -H "Origin: https://valid.example.com" "http://127.0.0.1:$API_PORT/api/v0/id" >curl_output && + grep "HTTP/1.1 200 OK" curl_output && grep "$PEERID" curl_output +' + +test_kill_ipfs_daemon +test_done