-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Prevent OpenURI redirection & private hosts during API image upload #3593
Prevent OpenURI redirection & private hosts during API image upload #3593
Conversation
64228ac
to
348f8c1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a quick look at the CVE and this seems like a good fix to me.
@calebhaye correct me if I'm wrong, but we still need to ensure the user cannot pass a private IP as the hostname, is that right? Also, would it be possible to stub the HTTP requests with VCR? That way we're not calling live URLs in our tests, which may easily break/fail randomly. |
Paperclip’s CVE-2017–0889 Server Side Request Forgery (SSRF) vulnerability (https://medium.com/in-the-weeds/all-about-paperclips-cve-2017-0889-server-side-request-forgery-ssrf-vulnerability-8cb2b1c96fe8) was likely introduced in solidusio#3573. This patch ensures that redirection does not take place in the context of uploading an image via the api, and ensures that a private address is not used for the attachment parameter.
348f8c1
to
c4dfa2a
Compare
Thanks @aldesantis, I added a private IP/host check.
I also added VCR, but I left it as a separate commit, for now. Of course, if we're happy with the implementation I'll squash the commits and we can merge. But if we decide for some reason that VCR isn't the way we want to go, rebasing out the commit will be easy. Thank you for your comment, I'm looking forward to hearing your feedback. |
62d3e39
to
66d53f9
Compare
@@ -1,6 +1,7 @@ | |||
# frozen_string_literal: true | |||
|
|||
require 'spec_helper' | |||
require "private_address_check/tcpsocket_ext" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious why this is needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the code that contains the error that will be raised, and that the spec tests for.
The gem itself seems pretty simple, and we could just copy or fork it, but it has undergone some review, so I figured maybe it's worth keeping. I'm open to a better solution, if anyone has any ideas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could require it only in the sole spec where it was needed
@@ -1,5 +1,7 @@ | |||
# frozen_string_literal: true | |||
|
|||
require 'private_address_check' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should either add this to the gemspec or only require it when the attachment is a URI, making the functionality and dependency optional.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I felt like I might be doing this wrong. Any advice on a proper implementation is welcomed. For now I'll do your latter suggestion.
@calebhaye left a couple of comments, thanks! |
I'm starting to think this shouldn't be handled by Solidus. What about keeping URL upload disabled and allow enabling it with a preference? As far as I got, it's just a matter of adding It may sound drastic but, what about reverting the code in the controller and just adding some documentation on how to enable this adapter in Paperclip? Another thing that I prefer not to do is adding code specific for Paperclip which is deprecated and we are trying to slowly replace with ActiveStorage. What are your thoughts about this? |
@kennyadsl my 2 cents: I like the feature and would like to keep it for the time being, and I think we could easily replicate it with ActiveStorage when the time comes. With that said, it would probably be a good idea to make the behavior optional by adding a configuration option, so that the user is fully aware of the security implications and we are not potentially slipping a vulnerability into the codebase without them knowing. |
Honestly, I have mixed feelings about it. I'm obviously biased because a) I wrote the code, and b) it serves the needs of my business, but beyond my selfishness there may be a valid reason for keeping the feature in place. I guess one relevant question would be can anyone show me an example of the image api working without the feature in place? I wasn't able to get it to work, there is no documentation on it, and when I asked the Slack channel no one was able to give me an example there either. My point is, proving that the alternative works and providing docs for that would be a good place to start. Beyond that, I think we should consider non-ruby devs who want to use Solidus. Having this feature work out of the box without having to write a Rails initializer might be a good thing. That being said, I think it is easy enough to write an initializer to get this sort of functionality, but honestly if I had, I probably would have exposed my app to vulnerabilities. Having the group-think we've had around these implementations and making a decision in the best interest of the end-user seems like the responsible thing to do. |
af5c450
to
9a72d19
Compare
We discussed this via DM on Slack and we considered closing this and reverting the other PR that introduces this security concern (#3573). The API image upload is working, we tried with: curl -v -H "Content-Type: multipart/form-data" -H "Authorization: Bearer your_token" -i -F image[attachment]=@test_image.png http://localhost:3000/api/products/1/images and the image is uploaded correctly. Anyway, we agreed that we should improve the documentation around this with the following:
|
I personally still think we should keep it, but only enable it with a config flag. Just so that others don't introduce security vulnerabilities when they try to add the adapter as per the paperclip docs you referenced, and so we don't waste the thought we've put into this thus far. Showing how to do something safely seems like the best approach, plus we get a handy feature that many developers will use, and it doesn't require writing a custom adapter @kennyadsl what do you think of doing that, rather than throwing away all the code and a feature that is arguably valuable? |
@calebhaye how about extracting this into an extension? It should be fairly easy to do and would solve a lot of problems: users would have to explicitly install the extension, so they'd know the security implications of the feature, but they'd still be able to benefit from all the work and thought that went into the feature. |
Sounds good! I'll do that. Closing this now. |
This reverts commit 4a1824a. This commit potentially introduces a security vulnerabilty, (CVE-2017–0889) as described here: https://medium.com/in-the-weeds/all-about-paperclips-cve-2017-0889-server-side-request-forgery-ssrf-vulnerability-8cb2b1c96fe8 as kindly reported and described by this PR author in solidusio#3593. Also, this PR has been introduced because there wasn't a clear way to upload images via API, but this can be done by setting the right Content-Type header in the request, as follow: curl -v -H "Content-Type: multipart/form-data" -H "Authorization: Bearer YOUR_TOKEN" http://your.host/api/products/1
This reverts commit 4a1824a. This commit potentially introduces a security vulnerabilty, (CVE-2017–0889) as described here: https://medium.com/in-the-weeds/all-about-paperclips-cve-2017-0889-server-side-request-forgery-ssrf-vulnerability-8cb2b1c96fe8 as kindly reported and described by this PR author in solidusio#3593. Also, this PR has been introduced because there wasn't a clear way to upload images via API, but this can be done by setting the right Content-Type header in the request, as follow: curl -v -H "Content-Type: multipart/form-data" -H "Authorization: Bearer YOUR_TOKEN" http://your.host/api/products/1
This reverts commit 4a1824a. This commit potentially introduces a security vulnerabilty, (CVE-2017–0889) as described here: https://medium.com/in-the-weeds/all-about-paperclips-cve-2017-0889-server-side-request-forgery-ssrf-vulnerability-8cb2b1c96fe8 as kindly reported and described by this PR author in solidusio#3593. Also, this PR has been introduced because there wasn't a clear way to upload images via API, but this can be done by setting the right Content-Type header in the request, as follow: curl -v -H "Content-Type: multipart/form-data" -H "Authorization: Bearer YOUR_TOKEN" http://your.host/api/products/1
Description
Paperclip’s CVE-2017–0889 Server Side Request Forgery (SSRF)
vulnerability (https://medium.com/in-the-weeds/all-about-paperclips-cve-2017-0889-server-side-request-forgery-ssrf-vulnerability-8cb2b1c96fe8) was likely introduced in our attempts to allow API image uploads via URL. This patch ensures that redirection does not take place in the context of
uploading an image via the api. It also does a check to make sure the IP/host aren't private. Lastly, it uses VCR to stub out the http requests for images.
Ref #3573
Checklist: