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( ...@@ -375,14 +375,12 @@ bool CSPDirectiveList::CheckSource(
url.IsEmpty() ? policy_->FallbackUrlForPlugin() : url, redirect_status); 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,
const String& type_attribute) const { const String& type_attribute) const {
if (!directive)
return true;
if (type_attribute.IsEmpty() || type_attribute.StripWhiteSpace() != type) if (type_attribute.IsEmpty() || type_attribute.StripWhiteSpace() != type)
return false; return false;
return directive->Allows(type); return plugin_types.Contains(type);
} }
bool CSPDirectiveList::CheckEvalAndReportViolation( bool CSPDirectiveList::CheckEvalAndReportViolation(
...@@ -446,14 +444,16 @@ bool CSPDirectiveList::CheckWasmEvalAndReportViolation( ...@@ -446,14 +444,16 @@ bool CSPDirectiveList::CheckWasmEvalAndReportViolation(
} }
bool CSPDirectiveList::CheckMediaTypeAndReportViolation( bool CSPDirectiveList::CheckMediaTypeAndReportViolation(
MediaListDirective* directive, const Vector<String>& plugin_types,
const String& type, const String& type,
const String& type_attribute, const String& type_attribute,
const String& console_message) const { const String& console_message) const {
if (CheckMediaType(directive, type, type_attribute)) if (CheckMediaType(plugin_types, type, type_attribute))
return true; 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()) if (type_attribute.IsEmpty())
message = message + message = message +
" When enforcing the 'plugin-types' directive, the plugin's " " When enforcing the 'plugin-types' directive, the plugin's "
...@@ -464,9 +464,8 @@ bool CSPDirectiveList::CheckMediaTypeAndReportViolation( ...@@ -464,9 +464,8 @@ bool CSPDirectiveList::CheckMediaTypeAndReportViolation(
// 'RedirectStatus::NoRedirect' is safe here, as we do the media type check // 'RedirectStatus::NoRedirect' is safe here, as we do the media type check
// before actually loading data; this means that we shouldn't leak redirect // before actually loading data; this means that we shouldn't leak redirect
// targets, as we won't have had a chance to redirect yet. // targets, as we won't have had a chance to redirect yet.
ReportViolation(directive->GetText(), CSPDirectiveName::PluginTypes, ReportViolation(raw_directive, CSPDirectiveName::PluginTypes, message + "\n",
message + "\n", NullURL(), NullURL(), ResourceRequest::RedirectStatus::kNoRedirect);
ResourceRequest::RedirectStatus::kNoRedirect);
return DenyIfEnforcingPolicy(); return DenyIfEnforcingPolicy();
} }
...@@ -718,14 +717,17 @@ bool CSPDirectiveList::AllowPluginType( ...@@ -718,14 +717,17 @@ bool CSPDirectiveList::AllowPluginType(
const String& type_attribute, const String& type_attribute,
const KURL& url, const KURL& url,
ReportingDisposition reporting_disposition) const { ReportingDisposition reporting_disposition) const {
if (!plugin_types_.has_value())
return true;
return reporting_disposition == ReportingDisposition::kReport return reporting_disposition == ReportingDisposition::kReport
? CheckMediaTypeAndReportViolation( ? CheckMediaTypeAndReportViolation(
plugin_types_.Get(), type, type_attribute, plugin_types_.value(), type, type_attribute,
"Refused to load '" + url.ElidedString() + "' (MIME type '" + "Refused to load '" + url.ElidedString() + "' (MIME type '" +
type_attribute + type_attribute +
"') because it violates the following Content Security " "') because it violates the following Content Security "
"Policy Directive: ") "Policy Directive: ")
: CheckMediaType(plugin_types_.Get(), type, type_attribute); : CheckMediaType(plugin_types_.value(), type, type_attribute);
} }
bool CSPDirectiveList::AllowFromSource( bool CSPDirectiveList::AllowFromSource(
...@@ -850,9 +852,10 @@ bool CSPDirectiveList::AllowDynamicWorker() const { ...@@ -850,9 +852,10 @@ bool CSPDirectiveList::AllowDynamicWorker() const {
return CheckDynamic(worker_src, CSPDirectiveName::WorkerSrc); return CheckDynamic(worker_src, CSPDirectiveName::WorkerSrc);
} }
const String& CSPDirectiveList::PluginTypesText() const { String CSPDirectiveList::PluginTypesText() const {
DCHECK(HasPluginTypes()); DCHECK(HasPluginTypes());
return plugin_types_->GetText(); return GetRawDirectiveForMessage(
raw_directives_, network::mojom::blink::CSPDirectiveName::PluginTypes);
} }
bool CSPDirectiveList::ShouldSendCSPHeader(ResourceType type) const { bool CSPDirectiveList::ShouldSendCSPHeader(ResourceType type) const {
...@@ -1252,8 +1255,7 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) { ...@@ -1252,8 +1255,7 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) {
object_src_ = CSPSourceListParse(name, value, policy_); object_src_ = CSPSourceListParse(name, value, policy_);
return; return;
case CSPDirectiveName::PluginTypes: case CSPDirectiveName::PluginTypes:
plugin_types_ = plugin_types_ = CSPPluginTypesParse(value, policy_);
MakeGarbageCollected<MediaListDirective>(name, value, policy_);
return; return;
case CSPDirectiveName::PrefetchSrc: case CSPDirectiveName::PrefetchSrc:
if (!policy_->ExperimentalFeaturesEnabled()) if (!policy_->ExperimentalFeaturesEnabled())
...@@ -1525,7 +1527,6 @@ bool CSPDirectiveList::IsScriptRestrictionReasonable() const { ...@@ -1525,7 +1527,6 @@ bool CSPDirectiveList::IsScriptRestrictionReasonable() const {
void CSPDirectiveList::Trace(Visitor* visitor) const { void CSPDirectiveList::Trace(Visitor* visitor) const {
visitor->Trace(policy_); visitor->Trace(policy_);
visitor->Trace(plugin_types_);
visitor->Trace(trusted_types_); visitor->Trace(trusted_types_);
visitor->Trace(require_trusted_types_for_); visitor->Trace(require_trusted_types_for_);
} }
......
...@@ -128,8 +128,8 @@ class CORE_EXPORT CSPDirectiveList final ...@@ -128,8 +128,8 @@ class CORE_EXPORT CSPDirectiveList final
// Used to copy plugin-types into a plugin document in a nested // Used to copy plugin-types into a plugin document in a nested
// browsing context. // browsing context.
bool HasPluginTypes() const { return !!plugin_types_; } bool HasPluginTypes() const { return plugin_types_.has_value(); }
const String& PluginTypesText() const; String PluginTypesText() const;
bool ShouldSendCSPHeader(ResourceType) const; bool ShouldSendCSPHeader(ResourceType) const;
...@@ -240,7 +240,7 @@ class CORE_EXPORT CSPDirectiveList final ...@@ -240,7 +240,7 @@ class CORE_EXPORT CSPDirectiveList final
bool CheckSource(const network::mojom::blink::CSPSourceList*, bool CheckSource(const network::mojom::blink::CSPSourceList*,
const KURL&, const KURL&,
ResourceRequest::RedirectStatus) const; ResourceRequest::RedirectStatus) const;
bool CheckMediaType(MediaListDirective*, bool CheckMediaType(const Vector<String>& plugin_types,
const String& type, const String& type,
const String& type_attribute) const; const String& type_attribute) const;
...@@ -269,7 +269,7 @@ class CORE_EXPORT CSPDirectiveList final ...@@ -269,7 +269,7 @@ class CORE_EXPORT CSPDirectiveList final
CSPDirectiveName, CSPDirectiveName,
const KURL& url_before_redirects, const KURL& url_before_redirects,
ResourceRequest::RedirectStatus) const; ResourceRequest::RedirectStatus) const;
bool CheckMediaTypeAndReportViolation(MediaListDirective*, bool CheckMediaTypeAndReportViolation(const Vector<String>& plugin_types,
const String& type, const String& type,
const String& type_attribute, const String& type_attribute,
const String& console_message) const; const String& console_message) const;
...@@ -301,7 +301,7 @@ class CORE_EXPORT CSPDirectiveList final ...@@ -301,7 +301,7 @@ class CORE_EXPORT CSPDirectiveList final
bool upgrade_insecure_requests_; bool upgrade_insecure_requests_;
Member<MediaListDirective> plugin_types_; base::Optional<Vector<String>> plugin_types_;
network::mojom::blink::CSPSourceListPtr base_uri_; network::mojom::blink::CSPSourceListPtr base_uri_;
network::mojom::blink::CSPSourceListPtr child_src_; network::mojom::blink::CSPSourceListPtr child_src_;
network::mojom::blink::CSPSourceListPtr connect_src_; network::mojom::blink::CSPSourceListPtr connect_src_;
......
...@@ -4,36 +4,30 @@ ...@@ -4,36 +4,30 @@
#include "third_party/blink/renderer/core/frame/csp/media_list_directive.h" #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/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/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/parsing_utilities.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink { namespace blink {
MediaListDirective::MediaListDirective(const String& name, Vector<String> CSPPluginTypesParse(const String& value,
const String& value, ContentSecurityPolicy* policy) {
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) {
// TODO(amalika): Revisit parsing algorithm. Right now plugin types are not // TODO(amalika): Revisit parsing algorithm. Right now plugin types are not
// validated when they are added to m_pluginTypes. // 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; const UChar* position = begin;
// 'plugin-types ____;' OR 'plugin-types;' // 'plugin-types ____;' OR 'plugin-types;'
if (position == end) { if (position == end) {
Policy()->ReportInvalidPluginTypes(String()); policy->ReportInvalidPluginTypes(String());
return; return plugin_types;
} }
while (position < end) { while (position < end) {
...@@ -41,14 +35,14 @@ void MediaListDirective::Parse(const UChar* begin, const UChar* end) { ...@@ -41,14 +35,14 @@ void MediaListDirective::Parse(const UChar* begin, const UChar* end) {
// ^ ^ // ^ ^
SkipWhile<UChar, IsASCIISpace>(position, end); SkipWhile<UChar, IsASCIISpace>(position, end);
if (position == end) if (position == end)
return; return plugin_types;
// mime1/mime1 mime2/mime2 // mime1/mime1 mime2/mime2
// ^ // ^
begin = position; begin = position;
if (!SkipExactly<UChar, IsMediaTypeCharacter>(position, end)) { if (!SkipExactly<UChar, IsMediaTypeCharacter>(position, end)) {
SkipWhile<UChar, IsNotASCIISpace>(position, end); SkipWhile<UChar, IsNotASCIISpace>(position, end);
Policy()->ReportInvalidPluginTypes( policy->ReportInvalidPluginTypes(
String(begin, static_cast<wtf_size_t>(position - begin))); String(begin, static_cast<wtf_size_t>(position - begin)));
continue; continue;
} }
...@@ -58,7 +52,7 @@ void MediaListDirective::Parse(const UChar* begin, const UChar* end) { ...@@ -58,7 +52,7 @@ void MediaListDirective::Parse(const UChar* begin, const UChar* end) {
// ^ // ^
if (!SkipExactly<UChar>(position, end, '/')) { if (!SkipExactly<UChar>(position, end, '/')) {
SkipWhile<UChar, IsNotASCIISpace>(position, end); SkipWhile<UChar, IsNotASCIISpace>(position, end);
Policy()->ReportInvalidPluginTypes( policy->ReportInvalidPluginTypes(
String(begin, static_cast<wtf_size_t>(position - begin))); String(begin, static_cast<wtf_size_t>(position - begin)));
continue; continue;
} }
...@@ -67,7 +61,7 @@ void MediaListDirective::Parse(const UChar* begin, const UChar* end) { ...@@ -67,7 +61,7 @@ void MediaListDirective::Parse(const UChar* begin, const UChar* end) {
// ^ // ^
if (!SkipExactly<UChar, IsMediaTypeCharacter>(position, end)) { if (!SkipExactly<UChar, IsMediaTypeCharacter>(position, end)) {
SkipWhile<UChar, IsNotASCIISpace>(position, end); SkipWhile<UChar, IsNotASCIISpace>(position, end);
Policy()->ReportInvalidPluginTypes( policy->ReportInvalidPluginTypes(
String(begin, static_cast<wtf_size_t>(position - begin))); String(begin, static_cast<wtf_size_t>(position - begin)));
continue; continue;
} }
...@@ -77,15 +71,16 @@ void MediaListDirective::Parse(const UChar* begin, const UChar* end) { ...@@ -77,15 +71,16 @@ void MediaListDirective::Parse(const UChar* begin, const UChar* end) {
// ^ ^ ^ // ^ ^ ^
if (position < end && IsNotASCIISpace(*position)) { if (position < end && IsNotASCIISpace(*position)) {
SkipWhile<UChar, IsNotASCIISpace>(position, end); SkipWhile<UChar, IsNotASCIISpace>(position, end);
Policy()->ReportInvalidPluginTypes( policy->ReportInvalidPluginTypes(
String(begin, static_cast<wtf_size_t>(position - begin))); String(begin, static_cast<wtf_size_t>(position - begin)));
continue; continue;
} }
plugin_types_.insert( plugin_types.emplace_back(begin, static_cast<wtf_size_t>(position - begin));
String(begin, static_cast<wtf_size_t>(position - begin)));
DCHECK(position == end || IsASCIISpace(*position)); DCHECK(position == end || IsASCIISpace(*position));
} }
return plugin_types;
} }
} // namespace blink } // namespace blink
...@@ -5,33 +5,17 @@ ...@@ -5,33 +5,17 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_MEDIA_LIST_DIRECTIVE_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_MEDIA_LIST_DIRECTIVE_H_
#define 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/core_export.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/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink { namespace blink {
class ContentSecurityPolicy; class ContentSecurityPolicy;
class CORE_EXPORT MediaListDirective final : public CSPDirective { CORE_EXPORT
public: Vector<String> CSPPluginTypesParse(const String& value,
MediaListDirective(const String& name, ContentSecurityPolicy* policy);
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);
};
} // namespace blink } // 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