Chromium Code Reviews| Index: third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp |
| diff --git a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp |
| index 4bdfefc6cc7a7147cdca93bbf6659dc25093bb0f..3e9e50f1a69a61ad8eb623c467da9e262ca3e710 100644 |
| --- a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp |
| +++ b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp |
| @@ -1142,6 +1142,138 @@ void CSPDirectiveList::addDirective(const String& name, const String& value) { |
| } |
| } |
| +SourceListDirectiveVector CSPDirectiveList::getSourceList( |
| + const char* name, |
| + CSPDirectiveListVector policies) { |
| + SourceListDirectiveVector sourceListDirectives; |
| + if (name == ContentSecurityPolicy::ScriptSrc) { |
|
Mike West
2016/11/17 11:25:15
Another way of approaching this would be to refact
|
| + for (const auto& policy : policies) { |
| + if (SourceListDirective* directive = |
| + policy->operativeDirective(policy->m_scriptSrc.get())) { |
| + sourceListDirectives.append(directive); |
| + } |
| + } |
| + } else if (name == ContentSecurityPolicy::ObjectSrc) { |
| + for (const auto& policy : policies) { |
| + if (SourceListDirective* directive = |
| + policy->operativeDirective(policy->m_objectSrc.get())) { |
| + sourceListDirectives.append(directive); |
| + } |
| + } |
| + } else if (name == ContentSecurityPolicy::FrameSrc) { |
| + for (const auto& policy : policies) { |
| + if (SourceListDirective* directive = policy->operativeDirective( |
| + policy->m_frameSrc.get(), |
| + policy->operativeDirective(policy->m_childSrc.get()))) { |
| + sourceListDirectives.append(directive); |
| + } |
| + } |
| + } else if (name == ContentSecurityPolicy::ImgSrc) { |
| + for (const auto& policy : policies) { |
| + if (SourceListDirective* directive = |
| + policy->operativeDirective(policy->m_imgSrc.get())) { |
| + sourceListDirectives.append(directive); |
| + } |
| + } |
| + } else if (name == ContentSecurityPolicy::StyleSrc) { |
| + for (const auto& policy : policies) { |
| + if (SourceListDirective* directive = |
| + policy->operativeDirective(policy->m_styleSrc.get())) { |
| + sourceListDirectives.append(directive); |
| + } |
| + } |
| + } else if (name == ContentSecurityPolicy::FontSrc) { |
| + for (const auto& policy : policies) { |
| + if (SourceListDirective* directive = |
| + policy->operativeDirective(policy->m_fontSrc.get())) { |
| + sourceListDirectives.append(directive); |
| + } |
| + } |
| + } else if (name == ContentSecurityPolicy::MediaSrc) { |
| + for (const auto& policy : policies) { |
| + if (SourceListDirective* directive = |
| + policy->operativeDirective(policy->m_mediaSrc.get())) { |
| + sourceListDirectives.append(directive); |
| + } |
| + } |
| + } else if (name == ContentSecurityPolicy::ConnectSrc) { |
| + for (const auto& policy : policies) { |
| + if (SourceListDirective* directive = |
| + policy->operativeDirective(policy->m_connectSrc.get())) { |
| + sourceListDirectives.append(directive); |
| + } |
| + } |
| + } else if (name == ContentSecurityPolicy::ChildSrc) { |
| + for (const auto& policy : policies) { |
| + if (SourceListDirective* directive = |
| + policy->operativeDirective(policy->m_childSrc.get())) { |
| + sourceListDirectives.append(directive); |
| + } |
| + } |
| + } else if (name == ContentSecurityPolicy::ManifestSrc) { |
| + for (const auto& policy : policies) { |
| + if (SourceListDirective* directive = |
| + policy->operativeDirective(policy->m_manifestSrc.get())) { |
| + sourceListDirectives.append(directive); |
| + } |
| + } |
| + } else if (name == ContentSecurityPolicy::FrameAncestors) { |
| + for (const auto& policy : policies) { |
| + if (SourceListDirective* directive = policy->m_frameAncestors.get()) { |
| + sourceListDirectives.append(directive); |
| + } |
| + } |
| + } else if (name == ContentSecurityPolicy::BaseURI) { |
| + for (const auto& policy : policies) { |
| + if (SourceListDirective* directive = policy->m_baseURI.get()) { |
| + sourceListDirectives.append(directive); |
| + } |
| + } |
| + } else if (name == ContentSecurityPolicy::FormAction) { |
| + for (const auto& policy : policies) { |
| + if (SourceListDirective* directive = policy->m_formAction.get()) { |
| + sourceListDirectives.append(directive); |
| + } |
| + } |
| + } |
| + |
| + return sourceListDirectives; |
| +} |
| + |
| +bool CSPDirectiveList::subsumes(CSPDirectiveListVector other) { |
| + const char* directives[] = { |
| + // Fetch Directives |
| + ContentSecurityPolicy::ChildSrc, ContentSecurityPolicy::ConnectSrc, |
| + ContentSecurityPolicy::FontSrc, ContentSecurityPolicy::FrameSrc, |
| + ContentSecurityPolicy::ImgSrc, ContentSecurityPolicy::ManifestSrc, |
| + ContentSecurityPolicy::MediaSrc, ContentSecurityPolicy::ObjectSrc, |
| + ContentSecurityPolicy::ScriptSrc, ContentSecurityPolicy::StyleSrc, |
|
Mike West
2016/11/17 11:25:15
You'll want to add 'WorkerSrc', as you noted.
|
| + // Document Directives |
| + ContentSecurityPolicy::BaseURI, |
| + // Navigation Directives |
| + ContentSecurityPolicy::FrameAncestors, ContentSecurityPolicy::FormAction}; |
| + |
| + for (const auto& directive : directives) { |
| + // There should only be one SourceListDirective for each dirctive in |
| + // Embedding-CSP. |
| + SourceListDirectiveVector requiredList = |
| + getSourceList(directive, CSPDirectiveListVector(1, this)); |
| + if (requiredList.size() == 0) |
| + continue; |
| + SourceListDirective* required = requiredList[0]; |
| + // Aggregate all serialized source lists of the returned CSP into a vector |
| + // based on a directive type, defaulting accordingly (for example, to |
| + // `default-src`). |
| + SourceListDirectiveVector returned = getSourceList(directive, other); |
| + // TODO(amalika): Add checks for plugin-types, sandbox, disown-opener, |
| + // navigation-to, worker-src. |
| + if (!required->subsumes(returned)) |
| + return false; |
| + } |
| + |
| + return true; |
| +} |
| + |
| DEFINE_TRACE(CSPDirectiveList) { |
| visitor->trace(m_policy); |
| visitor->trace(m_pluginTypes); |