Skip to content
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

fix(security): Restore CORS functionality broken in EdgeX 3.0 #4638

Merged
merged 1 commit into from
Aug 17, 2023
Merged

fix(security): Restore CORS functionality broken in EdgeX 3.0 #4638

merged 1 commit into from
Aug 17, 2023

Conversation

bnevis-i
Copy link
Collaborator

@bnevis-i bnevis-i commented Aug 16, 2023

Closes #4627

When Kong and security-proxy-setup was removed in EdgeX 3.0,
the ability to support CORS through the API gateway was also inadvertently removed.

This PR -- which fixes the Docker deployment only (snap support forthcoming) --
statically includes the common configuration CORS settings and uses those to
enable CORS for all proxied services or none at all,
according to the common config or EDGEX_SERVICE_CORSCONFIGURATION_* overrides,
which may be set on the security-proxy-setup container
via docker-compose. These changes also introduce a new stage gate,
that block NGINX startup until security-proxy-setup has been completed.
(In EdgeX 2.x, Kong started first and security-proxy-setup after that.
To complete the CORS configuration for NGINX, we need to reverse that order.)

PR Checklist

Please check if your PR fulfills the following requirements:

  • I am not introducing a breaking change (if you are, flag in conventional commit message with BREAKING CHANGE: describing the break)
  • I am not introducing a new dependency (add notes below if you are)
  • I have added unit tests for the new feature or bug fix (if not, why?) Requires integration testing
  • I have fully tested (add details below) this the new feature or bug fix (if not, why?)
  • I have opened a PR for the related docs change (if not, why?)
    <link to docs PR>

Testing Instructions

Testing is somewhat involved.

First, create the following file on disk:

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title>cors-test</title>
        <script type='text/javascript'>
function main()
{
  try {
    fetch('https://localhost:8443/core-data/api/v3/ping', {
      mode: "cors",
      headers: {
        "Content-Type": "application/json"
      }
    });
  } catch(err) {
    alert(err); // Failed to fetch
  }
}
        </script>
    </head>
    <body onLoad='main();'></body>
</html>

Note: Content-Type is required to trigger CORS preflight. See https://auth0.com/blog/cors-tutorial-a-guide-to-cross-origin-resource-sharing/

Launch an http server for it using

python -m http.server --directory . 8888

Next, make the following changes to the docker-compose scripts

git diff
diff --git a/compose-builder/add-security.yml b/compose-builder/add-security.yml
index 07c4bcb..61ad482 100644
--- a/compose-builder/add-security.yml
+++ b/compose-builder/add-security.yml
@@ -196,13 +196,17 @@ services:
     container_name: edgex-security-proxy-setup
     hostname: edgex-security-proxy-setup
     entrypoint: ["/edgex-init/proxy_setup_wait_install.sh"]
-    read_only: true
+    read_only: false
     networks:
       - edgex-network
     env_file:
       - common-security.env
       - common-sec-stage-gate.env
     environment:
+      EDGEX_ADD_PROXY_ROUTE: "foo.http://localhost:12345"
+      EDGEX_SERVICE_CORSCONFIGURATION_ENABLECORS: 'true'
+      EDGEX_SERVICE_CORSCONFIGURATION_CORSALLOWEDORIGIN: '*'
+      EDGEX_SERVICE_CORSCONFIGURATION_CORSMAXAGE: '1'
       ROUTES_CORE_CONSUL_HOST: edgex-core-consul
       ROUTES_CORE_DATA_HOST: edgex-core-data
       ROUTES_CORE_METADATA_HOST: edgex-core-metadata
diff --git a/compose-builder/common-sec-stage-gate.env b/compose-builder/common-sec-stage-gate.env
index f40b67f..5d86369 100644
--- a/compose-builder/common-sec-stage-gate.env
+++ b/compose-builder/common-sec-stage-gate.env
@@ -31,3 +31,4 @@ STAGEGATE_REGISTRY_PORT=8500
 STAGEGATE_REGISTRY_READYPORT=54324
 STAGEGATE_READY_TORUNPORT=54329
 PROXY_SETUP_HOST=edgex-security-proxy-setup
+STAGEGATE_PROXYSETUP_READYPORT=54325

Launch the new containers with

make run dev

(be sure to make docker in edgex-go first)

Next, in the browser, open the following page:
https://cors-errors.info/header-checker
This page allows pasting of request and response headers to validate the CORS request is being correctly handled.

Once more, in the browser, open:
https://localhost:8443
Accept the temporary certificate served by NGINX. You will need to re-accept the cert everytime you do a make clean in edgex-compose.

Finally, hit
http://localhost:8888/
in the browser and open the developer tools, network tab and console.
Refresh the browser with F5.

Inspect the OPTIONS CORS preflight request in the network traffic bar.
Paste the raw request and response headers into the CORS validation web site.
Verify that the protocols are correctly followed.

Next, do the same for the CORS GET request.

The site should report no protocol violations.

To do the same with an authenticated request, run make get-token and modify the HTML above to include the header:

"Content-Type": "application/json",
"Authorization": "Bearer TOKEN-CONTENTS"

Repeat the test and ensure you get a 200 OK response from the CORS ping command.

Note that the SERVICE_CORSCONFIGURATION_CORSMAXAGE: '1' setting affects the browser's caching of CORS information. If CORS information has been cached in the browser, the OPTIONS request will not be made, which makes the testing invalid. In that case, clear the browser cache, introduce this change, and start over.

New Dependency Instructions (If applicable)

@bnevis-i bnevis-i marked this pull request as ready for review August 16, 2023 19:40
Closes #4627

When Kong and security-proxy-setup was removed in EdgeX 3.0,
the ability to support CORS through the API gateway was also inadvertently removed.

This PR -- which fixes the Docker deployment only (snap support forthcoming) --
statically includes the common configuration CORS settings and uses those to
enable CORS for all proxied services or none at all,
according to the common config or EDGEX_SERVICE_CORSCONFIGURATION_* overrides,
which may be set on the security-proxy-setup container
via docker-compose. These changes also introduce a new stage gate,
that block NGINX startup until security-proxy-setup has been completed.
(In EdgeX 2.x, Kong started first and security-proxy-setup after that.
To complete the CORS configuration for NGINX, we need to reverse that order.)

Signed-off-by: Bryon Nevis <bryon.nevis@intel.com>
@sonarcloud
Copy link

sonarcloud bot commented Aug 16, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
10.1% 10.1% Duplication

@bnevis-i bnevis-i merged commit 5be6da0 into edgexfoundry:main Aug 17, 2023
9 checks passed
@jim-wang-intel
Copy link
Contributor

tested it with instructions and works perfectly!

This pull request was closed.
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.

CORS configuration for NGINX proxy is broken
2 participants