react-native-windows 0.72.31 → 0.72.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
-->
|
|
11
11
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
12
12
|
<PropertyGroup>
|
|
13
|
-
<ReactNativeWindowsVersion>0.72.
|
|
13
|
+
<ReactNativeWindowsVersion>0.72.32</ReactNativeWindowsVersion>
|
|
14
14
|
<ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
|
|
15
15
|
<ReactNativeWindowsMinor>72</ReactNativeWindowsMinor>
|
|
16
|
-
<ReactNativeWindowsPatch>
|
|
16
|
+
<ReactNativeWindowsPatch>32</ReactNativeWindowsPatch>
|
|
17
17
|
<ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
|
|
18
|
-
<ReactNativeWindowsCommitId>
|
|
18
|
+
<ReactNativeWindowsCommitId>5e396ba8c0e2b687eeb194d52c595cf217c7f280</ReactNativeWindowsCommitId>
|
|
19
19
|
</PropertyGroup>
|
|
20
20
|
</Project>
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
#include <regex>
|
|
17
17
|
|
|
18
18
|
using std::set;
|
|
19
|
+
using std::string;
|
|
19
20
|
using std::wstring;
|
|
20
21
|
|
|
21
22
|
using winrt::hresult_error;
|
|
@@ -37,22 +38,26 @@ namespace Microsoft::React::Networking {
|
|
|
37
38
|
|
|
38
39
|
#pragma region OriginPolicyHttpFilter
|
|
39
40
|
|
|
40
|
-
#pragma region
|
|
41
|
+
#pragma region CaseInsensitiveComparer
|
|
41
42
|
|
|
42
|
-
bool OriginPolicyHttpFilter::
|
|
43
|
+
bool OriginPolicyHttpFilter::CaseInsensitiveComparer::operator()(const wchar_t *a, const wchar_t *b) const {
|
|
43
44
|
return _wcsicmp(a, b) < 0;
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
bool OriginPolicyHttpFilter::CaseInsensitiveComparer::operator()(const wstring &a, const wstring &b) const {
|
|
48
|
+
return _wcsicmp(a.c_str(), b.c_str()) < 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
#pragma endregion CaseInsensitiveComparer
|
|
47
52
|
|
|
48
53
|
// https://fetch.spec.whatwg.org/#forbidden-method
|
|
49
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
50
|
-
{L"CONNECT", L"TRACE", L"TRACK"};
|
|
54
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
55
|
+
OriginPolicyHttpFilter::s_forbiddenMethods = {L"CONNECT", L"TRACE", L"TRACK"};
|
|
51
56
|
|
|
52
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
57
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
53
58
|
OriginPolicyHttpFilter::s_simpleCorsMethods = {L"GET", L"HEAD", L"POST"};
|
|
54
59
|
|
|
55
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
60
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
56
61
|
OriginPolicyHttpFilter::s_simpleCorsRequestHeaderNames = {
|
|
57
62
|
L"Accept",
|
|
58
63
|
L"Accept-Language",
|
|
@@ -64,11 +69,11 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
|
|
|
64
69
|
L"Viewport-Width",
|
|
65
70
|
L"Width"};
|
|
66
71
|
|
|
67
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
72
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
68
73
|
OriginPolicyHttpFilter::s_simpleCorsResponseHeaderNames =
|
|
69
74
|
{L"Cache-Control", L"Content-Language", L"Content-Type", L"Expires", L"Last-Modified", L"Pragma"};
|
|
70
75
|
|
|
71
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
76
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
72
77
|
OriginPolicyHttpFilter::s_simpleCorsContentTypeValues = {
|
|
73
78
|
L"application/x-www-form-urlencoded",
|
|
74
79
|
L"multipart/form-data",
|
|
@@ -76,7 +81,7 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
|
|
|
76
81
|
|
|
77
82
|
// https://fetch.spec.whatwg.org/#forbidden-header-name
|
|
78
83
|
// Chromium still bans "User-Agent" due to https://crbug.com/571722
|
|
79
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
84
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
80
85
|
OriginPolicyHttpFilter::s_corsForbiddenRequestHeaderNames = {
|
|
81
86
|
L"Accept-Charset",
|
|
82
87
|
L"Accept-Encoding",
|
|
@@ -99,24 +104,15 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
|
|
|
99
104
|
L"Upgrade",
|
|
100
105
|
L"Via"};
|
|
101
106
|
|
|
102
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
107
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
103
108
|
OriginPolicyHttpFilter::s_cookieSettingResponseHeaders = {
|
|
104
109
|
L"Set-Cookie",
|
|
105
110
|
L"Set-Cookie2", // Deprecated by the spec, but probably still used
|
|
106
111
|
};
|
|
107
112
|
|
|
108
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
113
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
109
114
|
OriginPolicyHttpFilter::s_corsForbiddenRequestHeaderNamePrefixes = {L"Proxy-", L"Sec-"};
|
|
110
115
|
|
|
111
|
-
/*static*/ Uri OriginPolicyHttpFilter::s_origin{nullptr};
|
|
112
|
-
|
|
113
|
-
/*static*/ void OriginPolicyHttpFilter::SetStaticOrigin(std::string &&url) {
|
|
114
|
-
if (!url.empty())
|
|
115
|
-
s_origin = Uri{to_hstring(url)};
|
|
116
|
-
else
|
|
117
|
-
s_origin = nullptr;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
116
|
/*static*/ bool OriginPolicyHttpFilter::IsSameOrigin(Uri const &u1, Uri const &u2) noexcept {
|
|
121
117
|
return (u1 && u2) && u1.SchemeName() == u2.SchemeName() && u1.Host() == u2.Host() && u1.Port() == u2.Port();
|
|
122
118
|
}
|
|
@@ -301,7 +297,7 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
|
|
|
301
297
|
}
|
|
302
298
|
|
|
303
299
|
/*static*/ OriginPolicyHttpFilter::AccessControlValues OriginPolicyHttpFilter::ExtractAccessControlValues(
|
|
304
|
-
|
|
300
|
+
IMap<hstring, hstring> const &headers) {
|
|
305
301
|
using std::wregex;
|
|
306
302
|
using std::wsregex_token_iterator;
|
|
307
303
|
|
|
@@ -381,10 +377,14 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
|
|
|
381
377
|
}
|
|
382
378
|
}
|
|
383
379
|
|
|
384
|
-
OriginPolicyHttpFilter::OriginPolicyHttpFilter(IHttpFilter const &innerFilter)
|
|
380
|
+
OriginPolicyHttpFilter::OriginPolicyHttpFilter(string &&origin, IHttpFilter const &innerFilter)
|
|
381
|
+
: m_origin{nullptr}, m_innerFilter{innerFilter} {
|
|
382
|
+
if (!origin.empty())
|
|
383
|
+
m_origin = Uri{to_hstring(origin)};
|
|
384
|
+
}
|
|
385
385
|
|
|
386
|
-
OriginPolicyHttpFilter::OriginPolicyHttpFilter()
|
|
387
|
-
: OriginPolicyHttpFilter(winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter{}) {}
|
|
386
|
+
OriginPolicyHttpFilter::OriginPolicyHttpFilter(string &&origin)
|
|
387
|
+
: OriginPolicyHttpFilter(std::move(origin), winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter{}) {}
|
|
388
388
|
|
|
389
389
|
OriginPolicy OriginPolicyHttpFilter::ValidateRequest(HttpRequestMessage const &request) {
|
|
390
390
|
auto effectiveOriginPolicy =
|
|
@@ -394,17 +394,17 @@ OriginPolicy OriginPolicyHttpFilter::ValidateRequest(HttpRequestMessage const &r
|
|
|
394
394
|
return effectiveOriginPolicy;
|
|
395
395
|
|
|
396
396
|
case OriginPolicy::SameOrigin:
|
|
397
|
-
if (!IsSameOrigin(
|
|
397
|
+
if (!IsSameOrigin(m_origin, request.RequestUri()))
|
|
398
398
|
throw hresult_error{E_INVALIDARG, L"SOP (same-origin policy) is enforced"};
|
|
399
399
|
break;
|
|
400
400
|
|
|
401
401
|
case OriginPolicy::SimpleCrossOriginResourceSharing:
|
|
402
402
|
// Check for disallowed mixed content
|
|
403
403
|
if (GetRuntimeOptionBool("Http.BlockMixedContentSimpleCors") &&
|
|
404
|
-
|
|
404
|
+
m_origin.SchemeName() != request.RequestUri().SchemeName())
|
|
405
405
|
throw hresult_error{E_INVALIDARG, L"The origin and request URLs must have the same scheme"};
|
|
406
406
|
|
|
407
|
-
if (IsSameOrigin(
|
|
407
|
+
if (IsSameOrigin(m_origin, request.RequestUri()))
|
|
408
408
|
// Same origin. Therefore, skip Cross-Origin handling.
|
|
409
409
|
effectiveOriginPolicy = OriginPolicy::SameOrigin;
|
|
410
410
|
else if (!IsSimpleCorsRequest(request))
|
|
@@ -420,7 +420,7 @@ OriginPolicy OriginPolicyHttpFilter::ValidateRequest(HttpRequestMessage const &r
|
|
|
420
420
|
// Example: On the Edge browser, an XHR request with the "Host" header set gets rejected as unsafe.
|
|
421
421
|
// https://fetch.spec.whatwg.org/#forbidden-header-name
|
|
422
422
|
|
|
423
|
-
if (
|
|
423
|
+
if (m_origin.SchemeName() != request.RequestUri().SchemeName())
|
|
424
424
|
throw hresult_error{E_INVALIDARG, L"The origin and request URLs must have the same scheme"};
|
|
425
425
|
|
|
426
426
|
if (!AreSafeRequestHeaders(request.Headers()))
|
|
@@ -429,7 +429,7 @@ OriginPolicy OriginPolicyHttpFilter::ValidateRequest(HttpRequestMessage const &r
|
|
|
429
429
|
if (s_forbiddenMethods.find(request.Method().ToString().c_str()) != s_forbiddenMethods.cend())
|
|
430
430
|
throw hresult_error{E_INVALIDARG, L"Request method not allowed in cross-origin resource sharing"};
|
|
431
431
|
|
|
432
|
-
if (IsSameOrigin(
|
|
432
|
+
if (IsSameOrigin(m_origin, request.RequestUri()))
|
|
433
433
|
effectiveOriginPolicy = OriginPolicy::SameOrigin;
|
|
434
434
|
else if (IsSimpleCorsRequest(request))
|
|
435
435
|
effectiveOriginPolicy = OriginPolicy::SimpleCrossOriginResourceSharing;
|
|
@@ -466,7 +466,7 @@ void OriginPolicyHttpFilter::ValidateAllowOrigin(
|
|
|
466
466
|
// 4.10.4 - Mismatched allow origin
|
|
467
467
|
auto taintedOriginProp = props.TryLookup(L"TaintedOrigin");
|
|
468
468
|
auto taintedOrigin = taintedOriginProp && winrt::unbox_value<bool>(taintedOriginProp);
|
|
469
|
-
auto origin = taintedOrigin ? nullptr :
|
|
469
|
+
auto origin = taintedOrigin ? nullptr : m_origin;
|
|
470
470
|
if (allowedOrigin.empty() || !IsSameOrigin(origin, Uri{allowedOrigin})) {
|
|
471
471
|
hstring errorMessage;
|
|
472
472
|
if (allowedOrigin.empty())
|
|
@@ -597,7 +597,7 @@ void OriginPolicyHttpFilter::ValidateResponse(HttpResponseMessage const &respons
|
|
|
597
597
|
bool originAllowed = false;
|
|
598
598
|
for (const auto &header : response.Headers()) {
|
|
599
599
|
if (boost::iequals(header.Key(), L"Access-Control-Allow-Origin")) {
|
|
600
|
-
originAllowed |= L"*" == header.Value() ||
|
|
600
|
+
originAllowed |= L"*" == header.Value() || m_origin == Uri{header.Value()};
|
|
601
601
|
}
|
|
602
602
|
}
|
|
603
603
|
|
|
@@ -685,7 +685,7 @@ ResponseOperation OriginPolicyHttpFilter::SendPreflightAsync(HttpRequestMessage
|
|
|
685
685
|
}
|
|
686
686
|
|
|
687
687
|
preflightRequest.Headers().Insert(L"Access-Control-Request-Headers", headerNames);
|
|
688
|
-
preflightRequest.Headers().Insert(L"Origin", GetOrigin(
|
|
688
|
+
preflightRequest.Headers().Insert(L"Origin", GetOrigin(m_origin));
|
|
689
689
|
preflightRequest.Headers().Insert(L"Sec-Fetch-Mode", L"CORS");
|
|
690
690
|
|
|
691
691
|
co_return {co_await m_innerFilter.SendRequestAsync(preflightRequest)};
|
|
@@ -702,7 +702,7 @@ bool OriginPolicyHttpFilter::OnRedirecting(
|
|
|
702
702
|
// origin=http://a.com. Since the origin matches the URL, the request is authorized at http://a.com, but it actually
|
|
703
703
|
// allows http://b.com to bypass the CORS check at http://a.com since the redirected URL is from http://b.com.
|
|
704
704
|
if (!IsSameOrigin(response.Headers().Location(), request.RequestUri()) &&
|
|
705
|
-
!IsSameOrigin(
|
|
705
|
+
!IsSameOrigin(m_origin, request.RequestUri())) {
|
|
706
706
|
// By masking the origin field in the request header, we make it impossible for the server to set a single value for
|
|
707
707
|
// the access-control-allow-origin header. It means, the only way to support redirect is that server allows access
|
|
708
708
|
// from all sites through wildcard.
|
|
@@ -734,7 +734,7 @@ ResponseOperation OriginPolicyHttpFilter::SendRequestAsync(HttpRequestMessage co
|
|
|
734
734
|
// Allow only HTTP or HTTPS schemes
|
|
735
735
|
if (GetRuntimeOptionBool("Http.StrictScheme") && coRequest.RequestUri().SchemeName() != L"https" &&
|
|
736
736
|
coRequest.RequestUri().SchemeName() != L"http")
|
|
737
|
-
throw hresult_error{E_INVALIDARG, L"Invalid URL scheme: [" +
|
|
737
|
+
throw hresult_error{E_INVALIDARG, L"Invalid URL scheme: [" + m_origin.SchemeName() + L"]"};
|
|
738
738
|
|
|
739
739
|
if (!GetRuntimeOptionBool("Http.OmitCredentials")) {
|
|
740
740
|
coRequest.Properties().Lookup(L"RequestArgs").as<RequestArgs>()->WithCredentials = false;
|
|
@@ -771,7 +771,7 @@ ResponseOperation OriginPolicyHttpFilter::SendRequestAsync(HttpRequestMessage co
|
|
|
771
771
|
|
|
772
772
|
if (originPolicy == OriginPolicy::SimpleCrossOriginResourceSharing ||
|
|
773
773
|
originPolicy == OriginPolicy::CrossOriginResourceSharing) {
|
|
774
|
-
coRequest.Headers().Insert(L"Origin", GetOrigin(
|
|
774
|
+
coRequest.Headers().Insert(L"Origin", GetOrigin(m_origin));
|
|
775
775
|
}
|
|
776
776
|
|
|
777
777
|
auto response = co_await m_innerFilter.SendRequestAsync(coRequest);
|
|
@@ -22,37 +22,35 @@ class OriginPolicyHttpFilter
|
|
|
22
22
|
: public winrt::
|
|
23
23
|
implements<OriginPolicyHttpFilter, winrt::Windows::Web::Http::Filters::IHttpFilter, IRedirectEventSource> {
|
|
24
24
|
public:
|
|
25
|
-
struct
|
|
25
|
+
struct CaseInsensitiveComparer {
|
|
26
26
|
bool operator()(const wchar_t *, const wchar_t *) const;
|
|
27
|
+
bool operator()(const std::wstring &, const std::wstring &) const;
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
private:
|
|
30
|
-
static std::set<const wchar_t *,
|
|
31
|
-
static std::set<const wchar_t *,
|
|
32
|
-
static std::set<const wchar_t *,
|
|
33
|
-
static std::set<const wchar_t *,
|
|
34
|
-
static std::set<const wchar_t *,
|
|
35
|
-
static std::set<const wchar_t *,
|
|
36
|
-
static std::set<const wchar_t *,
|
|
37
|
-
static std::set<const wchar_t *,
|
|
38
|
-
|
|
39
|
-
// NOTE: Assumes static origin through owning client/resource/module/(React) instance's lifetime.
|
|
40
|
-
static winrt::Windows::Foundation::Uri s_origin;
|
|
31
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_forbiddenMethods;
|
|
32
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_simpleCorsMethods;
|
|
33
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_simpleCorsRequestHeaderNames;
|
|
34
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_simpleCorsResponseHeaderNames;
|
|
35
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_simpleCorsContentTypeValues;
|
|
36
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_corsForbiddenRequestHeaderNames;
|
|
37
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_corsForbiddenRequestHeaderNamePrefixes;
|
|
38
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_cookieSettingResponseHeaders;
|
|
41
39
|
|
|
42
40
|
struct AccessControlValues {
|
|
43
41
|
winrt::hstring AllowedOrigin;
|
|
44
42
|
winrt::hstring AllowedCredentials;
|
|
45
|
-
std::set<std::wstring> AllowedHeaders;
|
|
43
|
+
std::set<std::wstring, CaseInsensitiveComparer> AllowedHeaders;
|
|
46
44
|
std::set<std::wstring> AllowedMethods;
|
|
47
|
-
std::set<std::wstring> ExposedHeaders;
|
|
45
|
+
std::set<std::wstring, CaseInsensitiveComparer> ExposedHeaders;
|
|
48
46
|
size_t MaxAge;
|
|
49
47
|
};
|
|
50
48
|
|
|
49
|
+
winrt::Windows::Foundation::Uri m_origin;
|
|
50
|
+
|
|
51
51
|
winrt::Windows::Web::Http::Filters::IHttpFilter m_innerFilter;
|
|
52
52
|
|
|
53
53
|
public:
|
|
54
|
-
static void SetStaticOrigin(std::string &&url);
|
|
55
|
-
|
|
56
54
|
static bool IsSameOrigin(
|
|
57
55
|
winrt::Windows::Foundation::Uri const &u1,
|
|
58
56
|
winrt::Windows::Foundation::Uri const &u2) noexcept;
|
|
@@ -79,9 +77,9 @@ class OriginPolicyHttpFilter
|
|
|
79
77
|
winrt::Windows::Web::Http::HttpResponseMessage const &response,
|
|
80
78
|
bool removeAll);
|
|
81
79
|
|
|
82
|
-
OriginPolicyHttpFilter(winrt::Windows::Web::Http::Filters::IHttpFilter const &innerFilter);
|
|
80
|
+
OriginPolicyHttpFilter(std::string &&origin, winrt::Windows::Web::Http::Filters::IHttpFilter const &innerFilter);
|
|
83
81
|
|
|
84
|
-
OriginPolicyHttpFilter();
|
|
82
|
+
OriginPolicyHttpFilter(std::string &&origin);
|
|
85
83
|
|
|
86
84
|
OriginPolicy ValidateRequest(winrt::Windows::Web::Http::HttpRequestMessage const &request);
|
|
87
85
|
|
|
@@ -641,8 +641,7 @@ void WinRTHttpResource::AddResponseHandler(shared_ptr<IResponseHandler> response
|
|
|
641
641
|
|
|
642
642
|
#pragma region IHttpResource
|
|
643
643
|
|
|
644
|
-
/*static*/ shared_ptr<IHttpResource> IHttpResource::Make(
|
|
645
|
-
winrt::Windows::Foundation::IInspectable const &inspectableProperties) noexcept {
|
|
644
|
+
/*static*/ shared_ptr<IHttpResource> IHttpResource::Make(IInspectable const &inspectableProperties) noexcept {
|
|
646
645
|
using namespace winrt::Microsoft::ReactNative;
|
|
647
646
|
using winrt::Windows::Web::Http::HttpClient;
|
|
648
647
|
|
|
@@ -653,8 +652,7 @@ void WinRTHttpResource::AddResponseHandler(shared_ptr<IResponseHandler> response
|
|
|
653
652
|
client = HttpClient{redirFilter};
|
|
654
653
|
} else {
|
|
655
654
|
auto globalOrigin = GetRuntimeOptionString("Http.GlobalOrigin");
|
|
656
|
-
OriginPolicyHttpFilter
|
|
657
|
-
auto opFilter = winrt::make<OriginPolicyHttpFilter>(redirFilter);
|
|
655
|
+
auto opFilter = winrt::make<OriginPolicyHttpFilter>(std::move(globalOrigin), redirFilter);
|
|
658
656
|
redirFilter.as<RedirectHttpFilter>()->SetRedirectSource(opFilter.as<IRedirectEventSource>());
|
|
659
657
|
|
|
660
658
|
client = HttpClient{opFilter};
|