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

[BUG] During proxy-based authentication, remoteIpHeader seems not being verified against internalProxies #4414

Closed
simonelbaz opened this issue Jun 7, 2024 · 4 comments
Labels
bug Something isn't working untriaged Require the attention of the repository maintainers and may need to be prioritized

Comments

@simonelbaz
Copy link

simonelbaz commented Jun 7, 2024

Describe the bug

Hi,

During proxy-based authentication, the IP address contained in remoteIpHeader seems not verified with the list of internalProxies.
User can set any IP address, the request is authorized.
From my understanding, only the internalProxies list should be accepted.

It verifies the remoteIpHeader presence, the IP address format but not the address value.

Thanks for your feedback

Related component

Clients

To Reproduce

config.yml:

---

_meta:
  type: "config"
  config_version: 2

config:
  dynamic:
    http:
      xff:
        enabled: true
        internalProxies: '192\.168\.176\.40' # regex pattern
        remoteIpHeader:  'x-forwarded-for-dashboards'
    authc:
      proxy_auth_domain:
        description: "Authenticate via proxy"
        http_enabled: true
        transport_enabled: true
        order: 0
        http_authenticator:
          type: proxy
          challenge: false
          config:
            user_header: "x-proxy-user"
            roles_header: "x-proxy-roles"
        authentication_backend:
          type: noop
      kerberos_auth_domain:
        http_enabled: false
        transport_enabled: false
        order: 2
        http_authenticator:
          type: kerberos
          challenge: true
          config:
            # If true a lot of kerberos/security related debugging output will be logged to standard out
            krb_debug: false
            # If true then the realm will be stripped from the user name
            strip_realm_from_principal: true
        authentication_backend:
          type: noop
      basic_internal_auth_domain:
        description: "Authenticate via HTTP Basic against internal users database"
        http_enabled: true
        transport_enabled: true
        order: 1
        http_authenticator:
          type: basic
          challenge: true
        authentication_backend:
          type: intern

The curl command:

curl -vL "https://oc01.mydomain.test:9200" -H "x-proxy-user: xxx" -H "x-proxy-roles: admin" -H "x-forwarded-for-dashboards: 1.1.1.1"

Result of the command:

*   Trying 192.168.176.52:9200...
* Connected to oc01.mydomain.test (192.168.176.52) port 9200 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Request CERT (13):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Certificate (11):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: O=xxx; CN=oc01.mydomain.test
*  start date: Jun  4 18:43:36 2024 GMT
*  expire date: Jun  3 18:43:36 2034 GMT
*  subjectAltName: host "oc01.mydomain.test" matched cert's "oc01.mydomain.test"
*  issuer: C=FR; ST=France; L=Paris; O=xxx; OU=xxx; CN=xxx; emailAddress=xxx
*  SSL certificate verify ok.
> GET / HTTP/1.1
> Host: oc01.mydomain.test:9200
> User-Agent: curl/7.74.0
> Accept: */*
> x-proxy-user: ELBAZsi
> x-proxy-roles: admin
> x-forwarded-for-dashboards: 1.1.1.1
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: application/json; charset=UTF-8
< content-length: 571
<
{
  "name" : "oc01.mydomain.test",
  "cluster_name" : "xxx-logs",
  "cluster_uuid" : "1qfaG3b4R02_zOrzDSfgAg",
  "version" : {
    "distribution" : "opensearch",
    "number" : "2.14.0",
    "build_type" : "deb",
    "build_hash" : "aaa555453f4713d652b52436874e11ba258d8f03",
    "build_date" : "2024-05-09T18:50:48.052504416Z",
    "build_snapshot" : false,
    "lucene_version" : "9.10.0",
    "minimum_wire_compatibility_version" : "7.10.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "The OpenSearch Project: https://opensearch.org/"
}
* Connection #0 to host oc01.mydomain.test left intact

Expected behavior

Opensearch should not authorize the request if remoteIpHeader value does not match internalProxies list

Additional Details

Plugins
Please list all plugins currently enabled.

Screenshots
If applicable, add screenshots to help explain your problem.

Host/Environment (please complete the following information):

  • OS: [Debian 11]
  • Version [Opensearch Dashboards 2.14, Opensearch 2.14]

Additional context
Add any other context about the problem here.

@simonelbaz simonelbaz added bug Something isn't working untriaged Require the attention of the repository maintainers and may need to be prioritized labels Jun 7, 2024
@peterzhuamazon peterzhuamazon transferred this issue from opensearch-project/OpenSearch Jun 7, 2024
@peterzhuamazon
Copy link
Member

peterzhuamazon commented Jun 7, 2024

Seems like related to security plugin.
Transfer the issue.

Thanks.

@derek-ho
Copy link
Contributor

derek-ho commented Jun 7, 2024

Hi @simonelbaz would you mind sharing your opensearch_dashboards.yml config? Just re-read the issue and it seems related to backend only

@cwperks
Copy link
Member

cwperks commented Jun 7, 2024

@simonelbaz From my understanding of the code, its the IP address of the initiator of the request that's verified against internalProxies not what's passed in the XFF header. See https://github.com/opensearch-project/security/blob/main/src/main/java/org/opensearch/security/http/RemoteIpDetector.java#L119-L144

// originalRemoteAddr need to be in the list of internalProxies

The XFF header comes into the picture in the Backend Registry here. The XFFResolver is responsible for getting the original IP Address of the request. For non-proxied requests that's the IP address of the web request, but for proxied requests it extracts that through the XFF header.

In your example, where are you sending the request from?

@simonelbaz
Copy link
Author

simonelbaz commented Jun 8, 2024

In your example, where are you sending the request from?

The curl command is ran from the proxy having the following IP address: 192.168.176.40 (the same as internalProxies)

So there is no security issue from the code snippet you mention.

Thanks for your feedback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working untriaged Require the attention of the repository maintainers and may need to be prioritized
Projects
None yet
Development

No branches or pull requests

4 participants