10000 Ajax: More checks before replacing %20 to + in data by ermouth · Pull Request #4123 · jquery/jquery · GitHub
[go: up one dir, main page]

Skip to content

Ajax: More checks before replacing %20 to + in data #4123

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

Closed
wants to merge 1 commit into from

Conversation

ermouth
Copy link
@ermouth ermouth commented Jul 10, 2018

Summary

Before $.ajax replaces %20 to + in POST-ed data, opts.headers['content-type'] is now checked as well as opts.contentType, and explicit header wins if present. Replacement only takes place if resulting content type starts with application/x-www-form-urlencoded.

Fixes #4119.

Checklist

@jsf-clabot
Copy link
jsf-clabot commented Jul 10, 2018

CLA assistant check
All committers have signed the CLA.

@timmywil
Copy link
Member

Is there a reason we can't set s.contentType based on the header if present?

@ermouth
Copy link
Author
ermouth commented Jul 10, 2018

@timmywil I preferred to keep existing sequence of sending headers: if s.contentType and content-type in headers are different, they are sent as different. I just do not know exactly why we have this strange option, so kept as is.

@gibson042
Copy link
Member

This seems like a bit of a worm tin... what about the JSONP prefilter that has its own logic branch for application/x-www-form-urlencoded, not to mention other user-installed prefilters?

Having promoted contentType up outside of headers, I think we should embrace it as the definitive means of controlling behavior dependent upon request Content-Type. I don't think we should specifically check headers for anything. In other words, I'm recommending that #4119 be either closed with no code changes, or migrated to a documentation issue.

However, if the above is not persuasive, then the best way to implement this fix would be as an early built-in prefilter that overrides contentType. And it'll need tests.

@ermouth
Copy link
Author
ermouth commented Jul 12, 2018

@gibson042 I discovered this issue in the wild, it broke in-prod system. The issue is very hidden and uncovered itself several months after migrating from jQuery 2 to 3.

It’s not good that there exist a hidden default value of a not-required option, that might corrupt data unexpectedly. It’s twice not good that jQuery 3 behaves differently than jQuery 2.

So it’s not a documentation issue, it’s a dangerous bug corrupting data silently, and it was not easy to root because no one in the world expects hidden values covertly override explicits somewhere in deep internals.

However, if you think the patch should be an early override of contentType, I gonna do it. But I’m pretty sure I will need some assistance with making tests for it.

@timmywil
Copy link
Member
timmywil commented Jul 12, 2018

If there are different code paths for the same header based on the contentType option and not the header, then contentType can't be set by the header. Isn't the easy fix here to use the option? If so, then I agree with @gibson042 and this is a docs issue.

@ermouth
Copy link
Author
ermouth commented Jul 12, 2018

@timmywil It might be easy fix for the software not yet written. For the software already deployed and dependent on the behavior demonstrated by 2.x the easiest fix is to roll back to 2.x branch, which was the first thing we did after the issue discovery.

In many places we generate headers required for a request by a separate function returning headers object. I suppose it‘s more or less common practice. Moreover, we never use .contentType, and I was not aware of it until this issue.

So to delete one specific prop from .headers and move it to opts before each and every request will not be an easy fix, at least for me. Moreover, I have to enforce deletion of .headers['content-type'] everywhere, because it‘s sheer existence in request options is a risk, since gives internal behavior inconsistent with actually sent data.

So from practical POV I‘m sure it’s a bug and not documentation issue.

Hope I did all my best to fix it.

@gibson042
Copy link
Member

Thanks, @ermouth. I reviewed jQuery 2.2.4 and agree that this is indeed a regression. So as I described above, I think we should have a built-in ajaxPrefilter (similar to the one preventing inadvertent XSS) that overwrites contentType with the value of a supplied Content-Type header. And I think testing should be similar to that used for binary response types or abort).

@gibson042 gibson042 added the Ajax label Jul 13, 2018
@timmywil timmywil added this to the 3.4.0 milestone Sep 3, 2018
@jquery jquery deleted a comment from svlima777 Oct 17, 2018
@mgol mgol modified the milestones: 3.4.0, 4.0.0 Apr 8, 2019
@mgol mgol modified the milestones: 4.0.0, 3.5.0 Mar 31, 2020
@mgol
Copy link
Member
mgol commented Apr 6, 2020

This approach was rejected & we have a newer PR: #4650 so I'm closing this one.

@mgol mgol closed this Apr 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

Invalid encoding of %20 char sequence in $.ajax post, put body
5 participants
0