Bug 2058424 - ConsolePlugin proxy always passes Authorization header even if `authorize` property is omitted or false
Summary: ConsolePlugin proxy always passes Authorization header even if `authorize` pr...
Keywords:
Status: VERIFIED
Alias: None
Product: OpenShift Container Platform
Classification: Red Hat
Component: Management Console
Version: 4.10
Hardware: Unspecified
OS: Unspecified
unspecified
high
Target Milestone: ---
: 4.11.0
Assignee: Jakub Hadvig
QA Contact: Xiyun Zhao
URL:
Whiteboard:
Depends On:
Blocks: 2059186
TreeView+ depends on / blocked
 
Reported: 2022-02-24 21:40 UTC by Mike Turley
Modified: 2022-07-21 07:57 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: No Doc Update
Doc Text:
Clone Of:
Environment:
Last Closed:
Target Upstream Version:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Github openshift console pull 11102 0 None open [WIP] Bug 2058424: Don't pass Authorization header when not needed 2022-02-25 17:31:03 UTC

Description Mike Turley 2022-02-24 21:40:01 UTC
Description of problem:

As described in the Dynamic Plugin SDK enhancement, a plugin can set up a proxy to another service in the cluster via a `proxy` property on the ConsolePlugin resource. See "In case the plugin needs to communicate with some in-cluster service" here: https://github.com/openshift/enhancements/blob/master/enhancements/console/dynamic-plugins.md#delivering-plugins

This proxy configuration has an optional property called `authorize` which this document describes as defaulting to false. This is reflected on the ConsolePlugin CRD:
https://github.com/openshift/api/blob/e83d48817f01601c3ff7c39f53fc28342965bc55/console/v1alpha1/0000_10_consoleplugin.crd.yaml#L65
> By default the access token is not part of the proxied request.


Version-Release number of selected component (if applicable): 4.10-rc1

If possible, we'd like to target 4.10 for this plugin's GA release.

How reproducible: 100%

Steps to Reproduce:
1. Set up a Dynamic Plugin with a service proxy configured in the ConsolePlugin spec, with the authorize flag omitted or false
2. Make a request to the proxied URL that does not include an Authorization header, or includes one with a custom bearer token.
3. Look in the logs of the service being proxied and see that an Authorization header was indeed passed.
4. Compare the bearer token in that header to the one observable in the dev tools of the Console UI being passed in other API requests.

Actual results:

I have tried excluding that flag and setting it to false, and in both cases the access token indeed ends up part of the proxied request. If I pass my own bearer token with the request, it gets replaced with the built-in one for the current user.

Expected results:

If the authorize flag is omitted or false, the Authorization header should be left alone (excluded if not present in the request, or left as-is if present in the request). Headers of the original request should be retained as-is in the request received by the proxied service.

Additional info:

Issue observed in https://github.com/konveyor/crane-ui-plugin and reported there as https://issues.redhat.com/browse/MIG-1093

Comment 1 Mike Turley 2022-02-24 21:40:47 UTC
See discussion on Slack here: https://coreos.slack.com/archives/C011BL0FEKZ/p1645734204061589

@

Comment 2 Mike Turley 2022-02-24 21:42:09 UTC
@spadgett@redhat.com seems to have found the root cause:

> I suspect this line always adds the header: https://github.com/openshift/console/blob/master/pkg/server/server.go#L541
> Potential fix, although I haven’t fully tested yet: https://github.com/openshift/console/pull/11102

Comment 5 Xiyun Zhao 2022-03-23 01:29:55 UTC
This bug has been verified on payload 4.11.0-0.nightly-2022-03-20-160505

Verification Step:
1. Login OCP CLI and set up related resources by using the oc-manifest.yaml that provide by https://github.com/openshift/console/blob/master/dynamic-demo-plugin/oc-manifest.yaml. In this case, the authorize flag is omitted and will be setup as false automatically after resource being created 
   $ oc apply -f oc-manifest.yaml
2. Check the details of the created console Plugin in YAML, verify if 'spec.proxy.authorize' is set up as false 
3. Enable the plugin on Administration -> Cluster Settings -> Configuation Tab -> choose Console(operator.openshift.io) -> Console plugins Tab -> Enable the plugin by using the edit button on status column
4. Login to the Openshift UI, open the JavaScript console in browser's developer tools
5. Make a request to the proxy endpoint and include an Authorization header with own bearer token (or a fake one) and check the response. (replacing the URL with format /api/proxy/plugin/:pluginName/:proxyAlias/)
   fetch(
     'https://console-openshift-console.apps.qe-daily-0323.qe.devcluster.openshift.com/api/proxy/plugin/console-demo-plugin/thanos-querier/',
     { headers: { Authorization: 'Bearer foo' } }
     )
   .then((response) => response.json())
   .then((data) => console.log(data)); 
6. Verify the promiseState in the response is not 'rejected'

Result:
2. 'spec.proxy.authorize' is set up as false automatically
6. the response of PromiseState is pending

Comment 6 Xiyun Zhao 2022-03-31 08:23:11 UTC
This bug has been verified on payload 4.11.0-0.nightly-2022-03-20-160505

Verification Step:
1. Login OCP CLI and set up related resources by using the oc-manifest.yaml that provide by https://github.com/openshift/console/blob/master/dynamic-demo-plugin/oc-manifest.yaml. In this case, the authorize flag is omitted and will be setup as false automatically after resource being created 
   $ oc apply -f oc-manifest.yaml
2. Check the details of the created console Plugin in YAML, verify if 'spec.proxy.authorize' is set up as false 
3. Enable the plugin on Administration -> Cluster Settings -> Configuation Tab -> choose Console(operator.openshift.io) -> Console plugins Tab -> Enable the plugin by using the edit button on status column
4. Login to the Openshift UI, open the JavaScript console in browser's developer tools
5. Navigate to the proxied URL https://my.console.ui.url/test-proxy-service,verify if any content can be shown under 'Proxy: consoleFetchJSON'
6. Make a request to the proxy endpoint and include an Authorization header with own bearer token (or a fake one) and check the response. (replacing the URL with format /api/proxy/plugin/:pluginName/:proxyAlias/)
   fetch(
     'https://my.console.ui.url/api/proxy/plugin/console-demo-plugin/thanos-querier/',
     { headers: { Authorization: 'Bearer foo' } }
     )
   .then((response) => response.json())
   .then((data) => console.log(data)); 
7. Verify the promiseState in the response is 'rejected'
8. Update authorize flag to true on the Administration -> Cluster Settings -> Configuation Tab -> choose Console(operator.openshift.io)Console plugins Tab -> Select and go to console Plugin details page -> Yaml Tab. Update authorize to true on spec.proxy.authorize
9. Repeat Step 6, Verify if user is able to open the page of https://my.console.ui.url/api/proxy/plugin/console-demo-plugin/thanos-querier/,and page can be loaded

Result:
2. 'spec.proxy.authorize' is set up as false automatically
5. Page is load without any error, no content would be found under 'Proxy: consoleFetchJSON' section
6. The response of PromiseState is rejected on Chrome developer mode
9  Page is load without any error, and message as below can be found under 'Proxy.consoleFetchJSON' section
   {
  "status": "success",
  "data": {
    "groups": [
      {
        "name": "CloudCredentialOperator",
        "file": "/etc/prometheus/rules/prometheus-k8s-rulefiles-0/openshift-cloud-credential-operator-cloud-credential-operator-alerts-53ea2bc2-d936-4ae8-80ee-082981bd0580.yaml",
        "rules": [
          {
            "state": "inactive",
            "name": "CloudCredentialOperatorDeprovisioningFailed",
            "query": "cco_credentials_requests_conditions{condition=\"CredentialsDeprovisionFailure\"} > 0",
            "duration": 300,
            "labels": {
              "prometheus": "openshift-monitoring/k8s",
              "severity": "warning"
            },
            "annotations": {
              "description": "While processing a CredentialsRequest marked for deletion, the Cloud Credential Operator encountered an issue. Check the conditions of all CredentialsRequests with 'oc get credentialsrequest -A' to find any CredentialsRequest(s) with a .status.condition showing a condition type of CredentialsDeprovisionFailure set to True for more details on the issue.",
              "message": "CredentialsRequest(s) unable to be cleaned up",
              "summary": "One or more CredentialsRequest CRs are unable to be deleted."


Note You need to log in before you can comment on or make changes to this bug.