You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It appears logic introduced in #2695 to work-around the itms-services: schema oddity has an overly broad assumption that is results in invalid URIs due to not percent-encoding relative IRIs as intended.
Ultimately, this can trick browsers into behaving badly when faced with invalid relative URL locations. But I think it is ours to fix in werkzeug because the current code is emitting an invalid location header per RFCs (and the presumed intention of the code.)
RFC 3986 for URIs has a section 2 that essentially says URI components should be percent-encoded if they aren't part of the "reserved" or explicitly "unreserved" lists of characters. As an case-study: backslashes should be percent-encoded. Indeed, werkzeug seems to intent to encode them, but this issue describes the case where the typical encoding logic is not being applied.
Replication
As an example consider an app expecting to use redirect(relative_uri) and expecting werkzeug to properly encode the Location: header (as it historically would before the mentioned work-around)
After @davidism 's prompt in the original issue to also file an upstream Python issue (python/cpython#104139 (comment)), Python's urlib.parse was improved with the itms-services: url schema knowledge in Python 3.12.
The cpython comment thread also mentions a potentially more tightly scoped workaround for the "_invalid_iri" issue on older python versions:
Yes, I like that solution, since it allows users to tell Python in general about any special scheme they need. Note that you won't see response.location encoded in your example, that only happens at the last moment when converting the Response to HTTP.
Summary
It appears logic introduced in #2695 to work-around the
itms-services:
schema oddity has an overly broad assumption that is results in invalid URIs due to not percent-encoding relative IRIs as intended.Ultimately, this can trick browsers into behaving badly when faced with invalid relative URL locations. But I think it is ours to fix in werkzeug because the current code is emitting an invalid location header per RFCs (and the presumed intention of the code.)
RFC 3986 for URIs has a section 2 that essentially says URI components should be percent-encoded if they aren't part of the "reserved" or explicitly "unreserved" lists of characters. As an case-study: backslashes should be percent-encoded. Indeed, werkzeug seems to intent to encode them, but this issue describes the case where the typical encoding logic is not being applied.
Replication
As an example consider an app expecting to use
redirect(relative_uri)
and expecting werkzeug to properly encode theLocation:
header (as it historically would before the mentioned work-around)Note the backslashes (
\
) in this URI are /not/ being encoded as%5C
.As a smaller test case:
Expected Behavior
The previous encoding behavior before the wrapper was desirable
Environment:
Relevant Code
werkzeug/src/werkzeug/wrappers/response.py
Lines 482 to 483 in d3dd65a
werkzeug/src/werkzeug/urls.py
Lines 167 to 185 in d3dd65a
The text was updated successfully, but these errors were encountered: