fix: prevent JSON.stringify on non-JSON payloads#37
fix: prevent JSON.stringify on non-JSON payloads#37
Conversation
create-fetchival.js
Outdated
| ...opts.headers, | ||
| } | ||
| // If a consumer has set the non-json content type, we don't stringify the body. | ||
| const shouldStringify = headers['Content-Type'] === 'application/json' |
There was a problem hiding this comment.
- theoretically there could be others like application/vnd.api+json but in practice maybe we don't have them
- should we do a case insensitive check on the header name?
There was a problem hiding this comment.
we do have vendor specific content-types in at least one case I know of. I don't think the WorldpayClient in that case uses @exodus/fetch, but better to assume that it can happen
There was a problem hiding this comment.
I see three theoretical options to solve the problem for the Sentry client:
- Provide a custom fetch implementation for the error-tracking module to prevent the default JSON.stringify behavior. At a quick glance, I didn't find any existing patterns in the code for doing that, so not sure if it's the right direction.
- Attach the sentry content-type on a proxy side and serialize the payload back to remove escape characters. This sounds too fragile and complex IMO.
- Make this fetch implementation handle the sentry specific header separately and avoid
JSON.stringifyfor it. That feels like a solid compromise, added in c78222f
should we do a case insensitive check on the header name?
Given consumers need to be aware of the mechanism that prevents default JSON.stringify behavior, maybe let's force them to pass the header in a specific case? Just to keep this simple.
There was a problem hiding this comment.
can we stringify for application/json and startsWith('application/') && endsWith('+json')? What does that miss?
There was a problem hiding this comment.
What does that miss?
Hard to say, perhaps need to look for every possible content type in all repositories =\
If we don't want the vendor headers to be hardcoded in this library, could we do something simple like
const shouldStringify = headers['Content-Type'].includes('json')There was a problem hiding this comment.
Would it make more sense to inject the prevenJsonStringifyContentTypes set via a config though?
In some scenarios (like this one) we want to use non
application/jsonpayload.JSON.stringifybreaks the payload in that case by adding escape charactersTesting