⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 242786 in webkit


Ignore:
Timestamp:
Mar 12, 2019, 1:13:26 AM (7 years ago)
Author:
commit-queue@webkit.org
Message:

Implement further CORS restrictions
https://bugs.webkit.org/show_bug.cgi?id=188644

Patch by Rob Buis <rbuis@igalia.com> on 2019-03-12
Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Update improved test results.

  • web-platform-tests/fetch/api/cors/cors-preflight-not-cors-safelisted.any-expected.txt:
  • web-platform-tests/fetch/api/cors/cors-preflight-not-cors-safelisted.any.worker-expected.txt:
  • web-platform-tests/fetch/api/headers/headers-no-cors.window-expected.txt:

Source/WebCore:

Verify that header value length is not greater than 128 [1]. Also implement
Step 5 of [2] to append values to existing header value when calling
Headers.append.

Tests: fetch/api/cors/cors-preflight-not-cors-safelisted.any.html

fetch/api/cors/cors-preflight-not-cors-safelisted.any.worker.html
fetch/api/headers/headers-no-cors.window.html

[1] https://fetch.spec.whatwg.org/#cors-safelisted-request-header
[2] https://fetch.spec.whatwg.org/#concept-headers-append

  • Modules/fetch/FetchHeaders.cpp:

(WebCore::canWriteHeader):
(WebCore::appendToHeaderMap):
(WebCore::FetchHeaders::remove):
(WebCore::FetchHeaders::set):
(WebCore::FetchHeaders::filterAndFill):

  • platform/network/HTTPParsers.cpp:

(WebCore::isCrossOriginSafeRequestHeader): verify that header length is not greater than 128

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r242595 r242786  
     12019-03-12  Rob Buis  <rbuis@igalia.com>
     2
     3        Implement further CORS restrictions
     4        https://bugs.webkit.org/show_bug.cgi?id=188644
     5
     6        Reviewed by Darin Adler.
     7
     8        Update improved test results.
     9
     10        * web-platform-tests/fetch/api/cors/cors-preflight-not-cors-safelisted.any-expected.txt:
     11        * web-platform-tests/fetch/api/cors/cors-preflight-not-cors-safelisted.any.worker-expected.txt:
     12        * web-platform-tests/fetch/api/headers/headers-no-cors.window-expected.txt:
     13
    1142019-03-07  Frederic Wang  <fwang@igalia.com>
    215
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-not-cors-safelisted.any-expected.txt

    r238664 r242786  
    22PASS Loading data…
    33PASS Need CORS-preflight for accept/" header
    4 FAIL Need CORS-preflight for accept/012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 header assert_equals: Preflight request has been made expected "1" but got "0"
     4PASS Need CORS-preflight for accept/012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 header
    55PASS Need CORS-preflight for accept-language/ header
    66PASS Need CORS-preflight for accept-language/@ header
     
    88PASS Need CORS-preflight for content-language/@ header
    99PASS Need CORS-preflight for content-type/text/html header
    10 FAIL Need CORS-preflight for content-type/text/plain; long=0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901 header assert_equals: Preflight request has been made expected "1" but got "0"
     10PASS Need CORS-preflight for content-type/text/plain; long=0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901 header
    1111PASS Need CORS-preflight for test/hi header
    1212
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-not-cors-safelisted.any.worker-expected.txt

    r238664 r242786  
    22PASS Loading data…
    33PASS Need CORS-preflight for accept/" header
    4 FAIL Need CORS-preflight for accept/012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 header assert_equals: Preflight request has been made expected "1" but got "0"
     4PASS Need CORS-preflight for accept/012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 header
    55PASS Need CORS-preflight for accept-language/ header
    66PASS Need CORS-preflight for accept-language/@ header
     
    88PASS Need CORS-preflight for content-language/@ header
    99PASS Need CORS-preflight for content-type/text/html header
    10 FAIL Need CORS-preflight for content-type/text/plain; long=0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901 header assert_equals: Preflight request has been made expected "1" but got "0"
     10PASS Need CORS-preflight for content-type/text/plain; long=0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901 header
    1111PASS Need CORS-preflight for test/hi header
    1212
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/headers-no-cors.window-expected.txt

    r239693 r242786  
    11
    22PASS Loading data…
    3 FAIL "no-cors" Headers object cannot have accept set to sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss assert_equals: 1 expected "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss" but got "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, "
    4 FAIL "no-cors" Headers object cannot have accept-language set to sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss assert_equals: 1 expected "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss" but got "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, "
    5 FAIL "no-cors" Headers object cannot have content-language set to sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss assert_equals: 1 expected "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss" but got "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, "
    6 FAIL "no-cors" Headers object cannot have accept set to , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss assert_equals: 1 expected "" but got ", sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
    7 FAIL "no-cors" Headers object cannot have accept-language set to , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss assert_equals: 1 expected "" but got ", sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
    8 FAIL "no-cors" Headers object cannot have content-language set to , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss assert_equals: 1 expected "" but got ", sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
    9 FAIL "no-cors" Headers object cannot have content-type set to text/plain;ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, text/plain assert_equals: 1 expected "text/plain;ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss" but got "text/plain;ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, text/plain"
     3PASS "no-cors" Headers object cannot have accept set to sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
     4PASS "no-cors" Headers object cannot have accept-language set to sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
     5PASS "no-cors" Headers object cannot have content-language set to sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
     6PASS "no-cors" Headers object cannot have accept set to , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
     7PASS "no-cors" Headers object cannot have accept-language set to , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
     8PASS "no-cors" Headers object cannot have content-language set to , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
     9PASS "no-cors" Headers object cannot have content-type set to text/plain;ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, text/plain
    1010PASS "no-cors" Headers object cannot have accept/" as header
    11 FAIL "no-cors" Headers object cannot have accept/012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 as header assert_false: expected false got true
     11PASS "no-cors" Headers object cannot have accept/012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 as header
    1212PASS "no-cors" Headers object cannot have accept-language/ as header
    1313PASS "no-cors" Headers object cannot have accept-language/@ as header
     
    1515PASS "no-cors" Headers object cannot have content-language/@ as header
    1616PASS "no-cors" Headers object cannot have content-type/text/html as header
    17 FAIL "no-cors" Headers object cannot have content-type/text/plain; long=0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901 as header assert_false: expected false got true
     17PASS "no-cors" Headers object cannot have content-type/text/plain; long=0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901 as header
    1818PASS "no-cors" Headers object cannot have test/hi as header
    1919PASS "no-cors" Headers object cannot have dpr/2 as header
  • trunk/Source/WebCore/ChangeLog

    r242784 r242786  
     12019-03-12  Rob Buis  <rbuis@igalia.com>
     2
     3        Implement further CORS restrictions
     4        https://bugs.webkit.org/show_bug.cgi?id=188644
     5
     6        Reviewed by Darin Adler.
     7
     8        Verify that header value length is not greater than 128 [1]. Also implement
     9        Step 5 of [2] to append values to existing header value when calling
     10        Headers.append.
     11
     12        Tests: fetch/api/cors/cors-preflight-not-cors-safelisted.any.html
     13               fetch/api/cors/cors-preflight-not-cors-safelisted.any.worker.html
     14               fetch/api/headers/headers-no-cors.window.html
     15
     16        [1] https://fetch.spec.whatwg.org/#cors-safelisted-request-header
     17        [2] https://fetch.spec.whatwg.org/#concept-headers-append
     18
     19        * Modules/fetch/FetchHeaders.cpp:
     20        (WebCore::canWriteHeader):
     21        (WebCore::appendToHeaderMap):
     22        (WebCore::FetchHeaders::remove):
     23        (WebCore::FetchHeaders::set):
     24        (WebCore::FetchHeaders::filterAndFill):
     25        * platform/network/HTTPParsers.cpp:
     26        (WebCore::isCrossOriginSafeRequestHeader): verify that header length is not greater than 128
     27
    1282019-03-11  Ryosuke Niwa  <rniwa@webkit.org>
    229
  • trunk/Source/WebCore/Modules/fetch/FetchHeaders.cpp

    r239427 r242786  
    3434namespace WebCore {
    3535
    36 static ExceptionOr<bool> canWriteHeader(const String& name, const String& value, FetchHeaders::Guard guard)
     36static ExceptionOr<bool> canWriteHeader(const String& name, const String& value, const String& combinedValue, FetchHeaders::Guard guard)
    3737{
    3838    if (!isValidHTTPToken(name))
     
    4444    if (guard == FetchHeaders::Guard::Request && isForbiddenHeaderName(name))
    4545        return false;
    46     if (guard == FetchHeaders::Guard::RequestNoCors && !isSimpleHeader(name, value))
     46    if (guard == FetchHeaders::Guard::RequestNoCors && !combinedValue.isEmpty() && !isSimpleHeader(name, combinedValue))
    4747        return false;
    4848    if (guard == FetchHeaders::Guard::Response && isForbiddenResponseHeaderName(name))
     
    5454{
    5555    String normalizedValue = stripLeadingAndTrailingHTTPSpaces(value);
    56     auto canWriteResult = canWriteHeader(name, normalizedValue, guard);
    57     if (canWriteResult.hasException())
    58         return canWriteResult.releaseException();
    59     if (!canWriteResult.releaseReturnValue())
    60         return { };
    61     headers.add(name, normalizedValue);
     56    String combinedValue = normalizedValue;
     57    if (headers.contains(name))
     58        combinedValue = makeString(headers.get(name), ", ", normalizedValue);
     59    auto canWriteResult = canWriteHeader(name, normalizedValue, combinedValue, guard);
     60    if (canWriteResult.hasException())
     61        return canWriteResult.releaseException();
     62    if (!canWriteResult.releaseReturnValue())
     63        return { };
     64    headers.set(name, combinedValue);
    6265    return { };
    6366}
     
    6568static ExceptionOr<void> appendToHeaderMap(const HTTPHeaderMap::HTTPHeaderMapConstIterator::KeyValue& header, HTTPHeaderMap& headers, FetchHeaders::Guard guard)
    6669{
    67     auto canWriteResult = canWriteHeader(header.key, header.value, guard);
     70    auto canWriteResult = canWriteHeader(header.key, header.value, header.value, guard);
    6871    if (canWriteResult.hasException())
    6972        return canWriteResult.releaseException();
     
    137140ExceptionOr<void> FetchHeaders::remove(const String& name)
    138141{
    139     auto canWriteResult = canWriteHeader(name, { }, m_guard);
     142    auto canWriteResult = canWriteHeader(name, { }, { }, m_guard);
    140143    if (canWriteResult.hasException())
    141144        return canWriteResult.releaseException();
     
    163166{
    164167    String normalizedValue = stripLeadingAndTrailingHTTPSpaces(value);
    165     auto canWriteResult = canWriteHeader(name, normalizedValue, m_guard);
     168    auto canWriteResult = canWriteHeader(name, normalizedValue, normalizedValue, m_guard);
    166169    if (canWriteResult.hasException())
    167170        return canWriteResult.releaseException();
     
    175178{
    176179    for (auto& header : headers) {
    177         auto canWriteResult = canWriteHeader(header.key, header.value, guard);
     180        auto canWriteResult = canWriteHeader(header.key, header.value, header.value, guard);
    178181        if (canWriteResult.hasException())
    179182            continue;
  • trunk/Source/WebCore/platform/network/HTTPParsers.cpp

    r242776 r242786  
    860860    switch (name) {
    861861    case HTTPHeaderName::Accept:
    862         return isValidAcceptHeaderValue(value);
     862        if (!isValidAcceptHeaderValue(value))
     863            return false;
     864        break;
    863865    case HTTPHeaderName::AcceptLanguage:
    864866    case HTTPHeaderName::ContentLanguage:
    865         return isValidLanguageHeaderValue(value);
     867        if (!isValidLanguageHeaderValue(value))
     868            return false;
     869        break;
    866870    case HTTPHeaderName::ContentType: {
    867871        // Preflight is required for MIME types that can not be sent via form submission.
    868872        String mimeType = extractMIMETypeFromMediaType(value);
    869         return equalLettersIgnoringASCIICase(mimeType, "application/x-www-form-urlencoded") || equalLettersIgnoringASCIICase(mimeType, "multipart/form-data") || equalLettersIgnoringASCIICase(mimeType, "text/plain");
     873        if (!(equalLettersIgnoringASCIICase(mimeType, "application/x-www-form-urlencoded") || equalLettersIgnoringASCIICase(mimeType, "multipart/form-data") || equalLettersIgnoringASCIICase(mimeType, "text/plain")))
     874            return false;
     875        break;
    870876    }
    871877    default:
     
    873879        return false;
    874880    }
     881    return value.length() <= 128;
    875882}
    876883
Note: See TracChangeset for help on using the changeset viewer.