argoproj / argo-cd

Declarative Continuous Deployment for Kubernetes
https://argo-cd.readthedocs.io
Apache License 2.0
16.76k stars 5.08k forks source link

Unauthentic requests possible by means of Server Side Request Forgery #2705

Open peterbosalliandercom opened 4 years ago

peterbosalliandercom commented 4 years ago

Checklist:

Describe the bug

During a security pentest on our cluster the following finding was reported on Argo:

Argo has functionality to connect to Git repositories using HTTPS. When doing this, the server makes a request to the supplied URL and gives some information about the response. This can be used to perform HTTP requests from the viewpoint of the server, making it possible to bypass firewalls and learn more about the local networks the server is on.

To Reproduce

The following steps show that port 22 is open on the Argo server:

  1. Log into the application.
  2. Under “Repositories”, add a new repository using “Connect Git repo using HTTPS”.
  3. Enter the following URL as repository URL: http://localhost:22/
  4. Change the URL to http://localhost/. The server responds with “Unable to connect repository: GET http://localhost:22/info/refs?service=git-upload-pack:EOF”, indicating that a request to the SSH server is performed. image

Expected behavior

Recommendation  Perform validation on the URL. Only allow URLs that point to another host on the internet.  Validate the response from the server after requesting the URL.  Restrict the information from the response that is shared with the user.

Version

all versions

Logs

Paste any relevant application logs here.
jannfis commented 4 years ago

Hi @peterbosalliandercom and thank you for sharing the results of your pen test with us!

Connecting arbitrary Git repositories via SSH and HTTPS is a core feature of ArgoCD. You can further restrict who can use this functionality with RBAC rules.

While I don't fully share the recommendations of this finding, I think an (optional) whitelist of URL patterns to match against when adding repositories would be a good thing to implement.

So, for example, an empty whitelist would allow to connect all repositories. A whitelist of

https://github.examplecorp.com/*
https://github.com/*

would allow connecting any repositories on github.examplecorp.com and github.com, without any port specification (default ports) and would deny creation requests for repositories having different URLs.

Do you think this would satisfy solution of this finding?

alexec commented 4 years ago

@peterbosalliandercom I second Jann, thank you for sharing. Did your pentesters give any indication of severity? Argo CD is to a publically accessible banking app (higher security need), nor is it a blog (lower security need).

peterbosalliandercom commented 4 years ago

Impact was Medium rated

peterbosalliandercom commented 4 years ago

The whitelist is a good solution according to the pentester. How do we implement those?

jannfis commented 4 years ago

Whitelisting can already be implemented at the Project level, by configuring what repositories are allowed to be used by the applications. However, this repository whitelist does not support wildcards or pattern matching yet, so each repository must be specified in full. You need to take care who can create and modify project resources, so that the whitelist cannot be changed by arbitrary users of ArgoCD.

Maybe a global whitelist, as proposed above, would be an additional nice feature to have. This way, we could have a global, non-changeable restrictions which can then be further narrowed down on project level.

@alexec / @alexmt what do you think of that idea?

alexec commented 4 years ago

I'm a bit unclear on exactly what information is being leaked here?

jannfis commented 4 years ago

I'm a bit unclear on exactly what information is being leaked here?

I think the essence of the finding is that you can basically abuse ArgoCD as a low-speed port scanner/prober for target systems reachable by ArgoCD.

I personally think the severity of this finding is pretty low (you need to be authenticated, you need to have either permissions to create repositories or applications within ArgoCD). Mitigation could also be implemented on the cluster level (network policies), but I think having a global restriction of "where are we allowed connect to repositories from" would be a good thing to have.

Sjord commented 4 years ago

SSRF can be used to port-scan from the viewpoint of the server. That gives some information about the environment that can be useful for a hacker, but would have limited impact.

SSRF can have a big impact if you can use it to access AWS instance metadata, for example. In AWS, the special URL http://169.254.169.254/ exposes sensitive information, and is only accessible from the host itself. By using SSRF it may be possible to retrieve part of that information from outside.

I haven't tested whether this is actually possible within Argo. This depends for a great deal on the details of the error message returned. Does the error message contain a part of the HTTP response? In that case it can leak sensitive information from HTTP resources that only the server should be allow to access.

One possible mitigation would be to give a more generic error message, that doesn't expose technical details of why the operation failed. However, this may also make debugging problems more difficult.

alexec commented 4 years ago

@jessesuen @edlee2121 can I get your input on this please?

stale[bot] commented 4 years ago

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

peterbosalliandercom commented 3 years ago

Hi @peterbosalliandercom and thank you for sharing the results of your pen test with us!

Connecting arbitrary Git repositories via SSH and HTTPS is a core feature of ArgoCD. You can further restrict who can use this functionality with RBAC rules.

While I don't fully share the recommendations of this finding, I think an (optional) whitelist of URL patterns to match against when adding repositories would be a good thing to implement.

So, for example, an empty whitelist would allow to connect all repositories. A whitelist of

https://github.examplecorp.com/*
https://github.com/*

would allow connecting any repositories on github.examplecorp.com and github.com, without any port specification (default ports) and would deny creation requests for repositories having different URLs.

Do you think this would satisfy solution of this finding?

@alexmt Is it possible to implement this above suggestion of using wildcards? We need it to keep toe sourcerepos secure and also workable by using wildcards. Could you change this into a feature request ?

peterbosalliandercom commented 3 years ago

@jannfis is this something you can react on?

jannfis commented 3 years ago

@peterbosalliandercom I think this can already be achieved by using a combination of the allowed source repositories restriction on AppProject level and appropriate RBAC rules for create action on repositories.

In case you have tried this already and it didn't work out, please let me know more details so we can figure out a possible solution.