Commit d8550474 authored by Antonio Sartori's avatar Antonio Sartori Committed by Chromium LUCI CQ

CSP: Replace blink::MediaListDirective with mojo type

In the Blink Content Security Policy code, for parsing the
'plugin-types' directive, we switch from using the internal blink type
blink::MediaListDirective to using a Vector<String> as in the mojo
type network::mojom::blink::ContentSecurityPolicy.

This is part of a project to harmonize the CSP code in Blink and in
services/network, and will make it easier to synchronize Content
Security Policies between the two.

Bug: 1021462,1149272
Change-Id: I26e2625f825c23f0e8ea557f5acfe3c94313ce9b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2563547
Commit-Queue: Antonio Sartori <antoniosartori@chromium.org>
Reviewed-by: default avatarArthur Sonzogni <arthursonzogni@chromium.org>
Reviewed-by: default avatarMike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#837480}
parent 0504c8b5
......@@ -375,14 +375,12 @@ bool CSPDirectiveList::CheckSource(
url.IsEmpty() ? policy_->FallbackUrlForPlugin() : url, redirect_status);
}
bool CSPDirectiveList::CheckMediaType(MediaListDirective* directive,
bool CSPDirectiveList::CheckMediaType(const Vector<String>& plugin_types,
const String& type,
const String& type_attribute) const {
if (!directive)
return true;
if (type_attribute.IsEmpty() || type_attribute.StripWhiteSpace() != type)
return false;
return directive->Allows(type);
return plugin_types.Contains(type);
}
bool CSPDirectiveList::CheckEvalAndReportViolation(
......@@ -446,14 +444,16 @@ bool CSPDirectiveList::CheckWasmEvalAndReportViolation(
}
bool CSPDirectiveList::CheckMediaTypeAndReportViolation(
MediaListDirective* directive,
const Vector<String>& plugin_types,
const String& type,
const String& type_attribute,
const String& console_message) const {
if (CheckMediaType(directive, type, type_attribute))
if (CheckMediaType(plugin_types, type, type_attribute))
return true;
String message = console_message + "\'" + directive->GetText() + "\'.";
String raw_directive = GetRawDirectiveForMessage(
raw_directives_, network::mojom::blink::CSPDirectiveName::PluginTypes);
String message = console_message + "\'" + raw_directive + "\'.";
if (type_attribute.IsEmpty())
message = message +
" When enforcing the 'plugin-types' directive, the plugin's "
......@@ -464,9 +464,8 @@ bool CSPDirectiveList::CheckMediaTypeAndReportViolation(
// 'RedirectStatus::NoRedirect' is safe here, as we do the media type check
// before actually loading data; this means that we shouldn't leak redirect
// targets, as we won't have had a chance to redirect yet.
ReportViolation(directive->GetText(), CSPDirectiveName::PluginTypes,
message + "\n", NullURL(),
ResourceRequest::RedirectStatus::kNoRedirect);
ReportViolation(raw_directive, CSPDirectiveName::PluginTypes, message + "\n",
NullURL(), ResourceRequest::RedirectStatus::kNoRedirect);
return DenyIfEnforcingPolicy();
}
......@@ -718,14 +717,17 @@ bool CSPDirectiveList::AllowPluginType(
const String& type_attribute,
const KURL& url,
ReportingDisposition reporting_disposition) const {
if (!plugin_types_.has_value())
return true;
return reporting_disposition == ReportingDisposition::kReport
? CheckMediaTypeAndReportViolation(
plugin_types_.Get(), type, type_attribute,
plugin_types_.value(), type, type_attribute,
"Refused to load '" + url.ElidedString() + "' (MIME type '" +
type_attribute +
"') because it violates the following Content Security "
"Policy Directive: ")
: CheckMediaType(plugin_types_.Get(), type, type_attribute);
: CheckMediaType(plugin_types_.value(), type, type_attribute);
}
bool CSPDirectiveList::AllowFromSource(
......@@ -850,9 +852,10 @@ bool CSPDirectiveList::AllowDynamicWorker() const {
return CheckDynamic(worker_src, CSPDirectiveName::WorkerSrc);
}
const String& CSPDirectiveList::PluginTypesText() const {
String CSPDirectiveList::PluginTypesText() const {
DCHECK(HasPluginTypes());
return plugin_types_->GetText();
return GetRawDirectiveForMessage(
raw_directives_, network::mojom::blink::CSPDirectiveName::PluginTypes);
}
bool CSPDirectiveList::ShouldSendCSPHeader(ResourceType type) const {
......@@ -1252,8 +1255,7 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) {
object_src_ = CSPSourceListParse(name, value, policy_);
return;
case CSPDirectiveName::PluginTypes:
plugin_types_ =
MakeGarbageCollected<MediaListDirective>(name, value, policy_);
plugin_types_ = CSPPluginTypesParse(value, policy_);
return;
case CSPDirectiveName::PrefetchSrc:
if (!policy_->ExperimentalFeaturesEnabled())
......@@ -1525,7 +1527,6 @@ bool CSPDirectiveList::IsScriptRestrictionReasonable() const {
void CSPDirectiveList::Trace(Visitor* visitor) const {
visitor->Trace(policy_);
visitor->Trace(plugin_types_);
visitor->Trace(trusted_types_);
visitor->Trace(require_trusted_types_for_);
}
......
......@@ -128,8 +128,8 @@ class CORE_EXPORT CSPDirectiveList final
// Used to copy plugin-types into a plugin document in a nested
// browsing context.
bool HasPluginTypes() const { return !!plugin_types_; }
const String& PluginTypesText() const;
bool HasPluginTypes() const { return plugin_types_.has_value(); }
String PluginTypesText() const;
bool ShouldSendCSPHeader(ResourceType) const;
......@@ -240,7 +240,7 @@ class CORE_EXPORT CSPDirectiveList final
bool CheckSource(const network::mojom::blink::CSPSourceList*,
const KURL&,
ResourceRequest::RedirectStatus) const;
bool CheckMediaType(MediaListDirective*,
bool CheckMediaType(const Vector<String>& plugin_types,
const String& type,
const String& type_attribute) const;
......@@ -269,7 +269,7 @@ class CORE_EXPORT CSPDirectiveList final
CSPDirectiveName,
const KURL& url_before_redirects,
ResourceRequest::RedirectStatus) const;
bool CheckMediaTypeAndReportViolation(MediaListDirective*,
bool CheckMediaTypeAndReportViolation(const Vector<String>& plugin_types,
const String& type,
const String& type_attribute,
const String& console_message) const;
......@@ -301,7 +301,7 @@ class CORE_EXPORT CSPDirectiveList final
bool upgrade_insecure_requests_;
Member<MediaListDirective> plugin_types_;
base::Optional<Vector<String>> plugin_types_;
network::mojom::blink::CSPSourceListPtr base_uri_;
network::mojom::blink::CSPSourceListPtr child_src_;
network::mojom::blink::CSPSourceListPtr connect_src_;
......
......@@ -4,36 +4,30 @@
#include "third_party/blink/renderer/core/frame/csp/media_list_directive.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/text/parsing_utilities.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
MediaListDirective::MediaListDirective(const String& name,
const String& value,
ContentSecurityPolicy* policy)
: CSPDirective(name, value, policy) {
Vector<UChar> characters;
value.AppendTo(characters);
Parse(characters.data(), characters.data() + characters.size());
}
bool MediaListDirective::Allows(const String& type) const {
return plugin_types_.Contains(type);
}
void MediaListDirective::Parse(const UChar* begin, const UChar* end) {
Vector<String> CSPPluginTypesParse(const String& value,
ContentSecurityPolicy* policy) {
// TODO(amalika): Revisit parsing algorithm. Right now plugin types are not
// validated when they are added to m_pluginTypes.
Vector<String> plugin_types;
Vector<UChar> characters;
value.AppendTo(characters);
const UChar* begin = characters.data();
const UChar* end = characters.data() + characters.size();
const UChar* position = begin;
// 'plugin-types ____;' OR 'plugin-types;'
if (position == end) {
Policy()->ReportInvalidPluginTypes(String());
return;
policy->ReportInvalidPluginTypes(String());
return plugin_types;
}
while (position < end) {
......@@ -41,14 +35,14 @@ void MediaListDirective::Parse(const UChar* begin, const UChar* end) {
// ^ ^
SkipWhile<UChar, IsASCIISpace>(position, end);
if (position == end)
return;
return plugin_types;
// mime1/mime1 mime2/mime2
// ^
begin = position;
if (!SkipExactly<UChar, IsMediaTypeCharacter>(position, end)) {
SkipWhile<UChar, IsNotASCIISpace>(position, end);
Policy()->ReportInvalidPluginTypes(
policy->ReportInvalidPluginTypes(
String(begin, static_cast<wtf_size_t>(position - begin)));
continue;
}
......@@ -58,7 +52,7 @@ void MediaListDirective::Parse(const UChar* begin, const UChar* end) {
// ^
if (!SkipExactly<UChar>(position, end, '/')) {
SkipWhile<UChar, IsNotASCIISpace>(position, end);
Policy()->ReportInvalidPluginTypes(
policy->ReportInvalidPluginTypes(
String(begin, static_cast<wtf_size_t>(position - begin)));
continue;
}
......@@ -67,7 +61,7 @@ void MediaListDirective::Parse(const UChar* begin, const UChar* end) {
// ^
if (!SkipExactly<UChar, IsMediaTypeCharacter>(position, end)) {
SkipWhile<UChar, IsNotASCIISpace>(position, end);
Policy()->ReportInvalidPluginTypes(
policy->ReportInvalidPluginTypes(
String(begin, static_cast<wtf_size_t>(position - begin)));
continue;
}
......@@ -77,15 +71,16 @@ void MediaListDirective::Parse(const UChar* begin, const UChar* end) {
// ^ ^ ^
if (position < end && IsNotASCIISpace(*position)) {
SkipWhile<UChar, IsNotASCIISpace>(position, end);
Policy()->ReportInvalidPluginTypes(
policy->ReportInvalidPluginTypes(
String(begin, static_cast<wtf_size_t>(position - begin)));
continue;
}
plugin_types_.insert(
String(begin, static_cast<wtf_size_t>(position - begin)));
plugin_types.emplace_back(begin, static_cast<wtf_size_t>(position - begin));
DCHECK(position == end || IsASCIISpace(*position));
}
return plugin_types;
}
} // namespace blink
......@@ -5,33 +5,17 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_MEDIA_LIST_DIRECTIVE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_MEDIA_LIST_DIRECTIVE_H_
#include "base/macros.h"
#include "third_party/blink/renderer/core/frame/csp/csp_directive.h"
#include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
class ContentSecurityPolicy;
class CORE_EXPORT MediaListDirective final : public CSPDirective {
public:
MediaListDirective(const String& name,
const String& value,
ContentSecurityPolicy*);
bool Allows(const String& type) const;
private:
FRIEND_TEST_ALL_PREFIXES(MediaListDirectiveTest, GetIntersect);
FRIEND_TEST_ALL_PREFIXES(MediaListDirectiveTest, Subsumes);
void Parse(const UChar* begin, const UChar* end);
HashSet<String> plugin_types_;
DISALLOW_COPY_AND_ASSIGN(MediaListDirective);
};
CORE_EXPORT
Vector<String> CSPPluginTypesParse(const String& value,
ContentSecurityPolicy* policy);
} // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment