blob: 9cc789671c27fb935f7557cf21c497e5eecf7c9f [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_URL_NULL_ORIGIN_MAP_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_URL_NULL_ORIGIN_MAP_H_
#include "base/thread_annotations.h"
#include "base/unguessable_token.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
namespace blink {
class KURL;
class SecurityOrigin;
// BlobURLNullOriginMap contains pairs of blob URL and security origin that is
// serialized into "null". An instance of this class is per-thread, and created
// when GetInstace() is called for the first time.
//
// When a blob URL is created in an opaque origin or something whose
// SecurityOrigin::SerializesAsNull() returns true, the origin is serialized
// into the URL as "null". Since that makes it impossible to parse the origin
// back out and compare it against a context's origin (to check if a context is
// allowed to dereference the URL), this class stores a map of blob URL to such
// an origin.
class PLATFORM_EXPORT BlobURLNullOriginMap {
public:
// Returns a thread-specific instance. The instance is created when this
// function is called for the first time.
static ThreadSpecific<BlobURLNullOriginMap>& GetInstance();
// Adds a pair of |blob_url| and |origin| to the map. |blob_url| and |origin|
// must have the same "null" origin.
void Add(const KURL& blob_url, SecurityOrigin* origin);
// Removes a "null" origin keyed with |blob_url| from the map. |blob_url| must
// have the "null" origin.
void Remove(const KURL& blob_url);
// Returns a "null" origin keyed with |blob_url| from the map. |blob_url| must
// have the "null" origin.
SecurityOrigin* Get(const KURL& blob_url);
private:
friend class ThreadSpecific<BlobURLNullOriginMap>;
HashMap<String, scoped_refptr<SecurityOrigin>> blob_url_null_origin_map_;
};
// BlobURLOpaqueOriginNonceMap contains pairs of blob URL and opaque security
// origin's nonce. This is used for comparing opaque origins in a thread-safe
// way. An instance of this class is singleton, and can safely be accessed from
// any threads.
//
// BlobURLNullOriginMap above does not work for the case where the blob URL is
// registered in an opaque origin, and then a network request is sent to the URL
// from a different thread because the map contains non-thread-safe
// SecurityOrigin. For example, this happens on dedicated worker construction
// that loads a top-level worker script on a worker thread.
//
// To handle the case, BlobURLOpaqueOriginNonceMap keeps SecurityOrigin::Nonce
// instead of SecurityOrigin. The nonce is uniquely assigned to SecurityOrigin
// when it is constructed as an opaque origin, and SecurityOrigin instances
// (isolated-)copied from the same opaque origin share the same nonce. The nonce
// is thread-safe, so it is feasible to compare opaque origins over threads.
//
// TODO(nhiroki): Unify BlobURLNullOriginMap and BlobURLOpaqueOriginNonceMap.
// Making BlobURLNullOriginMap thread-safe could be possible solution, but
// actually it should be quite hard and not practical. This is because
// SecurityOrigin is not thread-safe, and widely used with an assumption that it
// is not shared among threads. Instead, we could stop using
// BlobURLNullOriginMap, and use BlobURLNullOriginMap in any case.
class PLATFORM_EXPORT BlobURLOpaqueOriginNonceMap {
public:
// Returns the singleton instance of this class. The instance is created when
// this function is called for the first time.
static BlobURLOpaqueOriginNonceMap& GetInstance();
// Returns an opaque origin's nonce keyed with |blob_url| from the map.
// |blob_url| must have the opaque origin.
base::UnguessableToken Get(const KURL& blob_url) LOCKS_EXCLUDED(mutex_);
private:
friend class BlobURLNullOriginMap;
// Adds a pair of |blob_url| and |origin|'s nonce to the map. |blob_url| and
// |origin| must have the same opaque origin. Only called from
// BlobURLNullOriginMap::Add().
void Add(const KURL& blob_url, SecurityOrigin* origin) LOCKS_EXCLUDED(mutex_);
// Removes an opaque origin's nonce keyed with |blob_url| from the map.
// |blob_url| must have the opaque origin. Only called from
// BlobURLNullOriginMap::Remove().
void Remove(const KURL& blob_url) LOCKS_EXCLUDED(mutex_);
HashMap<String, base::UnguessableToken> blob_url_opaque_origin_nonce_map_
GUARDED_BY(mutex_);
Mutex mutex_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_URL_NULL_ORIGIN_MAP_H_