• Hiroki Nakagawa's avatar
    Blob: Check blob URL whose origin is opaque using SecurityOrigin::Nonce · f75dfa5b
    Hiroki Nakagawa authored
    > Introduction
    
    When PlzDedicatedWorker (off-the-main-thread dedicated worker script loading) is
    enabled, top-level dedicated worker script is fetched on a worker thread, not on
    the main (or parent) thread. This causes a problem when a dedicated worker is
    created from blob URL registered in a sandboxed iframe.
    
    > Problem
    
    A sandboxed iframe has an opaque origin. Blob URL registered in the frame also
    has the same opaque origin.
    
    When sending a network request to the blob URL, requester's SecurityOrigin takes
    the origin from the blob URL, and then conducts security check (see
    SecurityOrigin::CanRequest()). However, it's not straightforward on the opaque
    origin because the opaque origin is serialized into the blob URL (KURL) as
    "null" string like "blob:null/{UUID}", and there is no direct way to rebuild the
    origin from the KURL. To deal with the case, in the current implementation, the
    pair of the blob URL and the opaque origin is stored in thread-specific
    BlobURLNullOriginMap, and then the security check refers to the map.
    
    This mechanism works well when PlzDedicatedWorker is disabled, but not work when
    PlzDedicatedWorker is enabled. This is because the pair of the blob URL and the
    opaque origin is stored in the thread-specific map on the main (parent) thread,
    but the network request and the security check are conducted on the worker
    thread. As a result, the security check always fails.
    
    > Solution
    
    Making BlobURLNullOriginMap thread-safe could be one of solutions, but actually
    it's quite hard and not practical. This is because SecurityOrigin is not
    thread-safe, and widely used with an assumption that it's not shared among
    threads.
    
    Alternatively, this CL makes SecurityOrigin::CanRequest() check the opaque
    origin of the blob URL using SecurityOrigin::Nonce. Nonce is uniquely assigned
    to SecurityOrigin when it's constructed as an opaque origin, and SecurityOrigin
    instances (isolated-)copied from the same opaque origin share the same nonce.
    The nonce is base::UnguessableToken, and shareable among thread unlike
    SecurityOrigin.
    
    This CL introduces BlobURLNullOriginNonceMap that is the process-global
    singleton object to contain pairs of blob URL and opaque origins's nonce. The
    map is protected by Mutex, so any threads can access it.
    SecurityOrigin::CanRequest() compares the nonce stored in the map to its own
    nonce in addition to the existing checks. This fixes the problem.
    
    > Test
    
    This enables to pass some tests that were skipped because of timeout. Several
    test cases are still failing even after this change, but it should be caused by
    https://crbug.com/1017034.
    
    Bug: 987130
    Change-Id: I6bf2212aa4f4b1a37035c41866b3faeffe68c2b5
    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1873831
    Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
    Reviewed-by: default avatarMarijn Kruisselbrink <mek@chromium.org>
    Reviewed-by: default avatarHiroshige Hayashizaki <hiroshige@chromium.org>
    Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#712503}
    f75dfa5b
TestExpectations 509 KB