-
Notifications
You must be signed in to change notification settings - Fork 979
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
Add option for omitting request data from Faraday exceptions #1526
Add option for omitting request data from Faraday exceptions #1526
Conversation
Thank you for the addition @ClaytonPassmore, this makes sense to me. I'd be happy to merge this in and cut a new release, but first I'd like to add some documentation to the middleware page 🙏 I'll need to think a bit more about the "make this a default in the next major version", as I think it's a hard balance to strike. It's true that the request headers/body might contain sensitive data, but this is not logged automatically and if you send data to a 3rd party service (e.g. error tracker) then I'd expect you to trust that as well, or at least the data to have a controlled retention period. Just an observation: rather than removing the whole request from the exception, do you think we could do something smarter and make it so that you can filter just the data you need to? |
Thanks for the reply @iMacTia! I added some documentation to the middleware page as requested 👍
That's totally fair. Having the ability to configure the behaviour is enough to satisfy my needs 👌
I had a very similar thought when I first approached this problem. One of the challenges I encountered is that there are so many different parts of a request that are formatted differently - headers, body params, and query params. I wasn't sure if it made sense to have separate filter options for each type of field - e.g. Faraday.new do |f|
f.raise_error,
header_filters: ["Authorization", "X-Private-Key"],
query_param_filters: ["api_key", /.*_?email/],
body_filters: [
/"api_key":("[^"]+")/, # E.g. JSON
/<email>([^<]+)</email>/ # E.g. XML
]
end The filtering for body parameters felt extremely cumbersome to specify - I think it's a little too easy to specify a pattern that ends up breaking the content type or doesn't entirely replace the sensitive content. As a result, I went with the "big hammer" approach rather than the "finesse" approach 😄 Definitely open to your thoughts on this though! |
Fair enough, I think if we want to add a more "granular" approach later on it won't clash with the one proposed in this PR, so happy to get this in for the time being 👍 |
I'm interested in seeing this as the default. We have many places in our API where we don't want this behavior. So far we've disabled it in 38 places and are looking to add a linter to ensure future references to Faraday::Connection include the |
@ericboehs This is actually very interesting, I'm surprised you added it to so many places to be honest. The recommended usage of Faraday is to create a connection object per API you integrate to, so unless you integrate with 38 different API you shouldn't need to disable it in so many places 🤔 I'd love to learn more because my assumption so far was that you'd eventually need to do this in a few places, so the overall burden was very low and understandable to guarantee backwards compatibility. But this could be revisited if the friction is to high: if not changing the default, maybe with a global config or similar |
At the VA, we do integrate with a lot of APIs. There are discussions of breaking our modules out into their own applications. I'm not certain we're doing things correctly but here's a draft PR where we're working toward implementing this option. |
Right, so there's clearly some element of repetition here where multiple connections actually point to the same API (which is hard to tell just looking at the code, since everything is dynamically loaded through That said, you still do integrate with a whole lot of APIs in that project 😅! I think a possible middle ground solution to preserve backwards compatibility but support extreme use cases like yours would be to have the possibility to specify a default value for options at the middleware level, something like: Faraday::Response::RaiseError.default_options = { include_request: false }
conn = Faraday.new(...) do |f|
...
f.use :raise_error # no need to specify include_request: false here
end Considerations:
cc @olleolleolle interested in your feedback on this little design proposal 😄 |
Re: 2, merge, I think. This has the same default procedure as Faraday itself, does it not? Or are there new thread-safety risks? |
Description
Adds an option to the
:raise_error
middleware that prevents request data from being included in the generated Faraday exception.Request data can include sensitive headers (e.g.
Authorization
) or other request parameters. Uncaught exceptions tend to make their way into bug trackers, which is not a place where you want sensitive information to go!In order to prevent request data from being included in Faraday exceptions, you can now configure the
:raise_error
middleware so that it is omitted:Todos
Additional Notes
Request data started being bundled in Faraday exceptions in #1181.
To prevent this from becoming a breaking change, I preserved the existing behaviour - request data is included by default.
That said, I would love to see request data omitted by default in a future major version. As a user of this gem, I don't expect "response" data to include "request" data.