1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/csp_info.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h" 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/csp_validator.h" 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "extensions/common/manifest_constants.h" 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/sandboxed_page_info.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace extensions { 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace keys = manifest_keys; 18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace errors = manifest_errors; 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using csp_validator::ContentSecurityPolicyIsLegal; 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using csp_validator::ContentSecurityPolicyIsSecure; 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDefaultContentSecurityPolicy[] = 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "script-src 'self' chrome-extension-resource:; object-src 'self'"; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define PLATFORM_APP_LOCAL_CSP_SOURCES \ 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "'self' data: chrome-extension-resource:" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDefaultPlatformAppContentSecurityPolicy[] = 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Platform apps can only use local resources by default. 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "default-src 'self' chrome-extension-resource:;" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For remote resources, they can fetch them via XMLHttpRequest. 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "connect-src *;" 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // And serve them via data: or same-origin (blob:, filesystem:) URLs 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "style-src " PLATFORM_APP_LOCAL_CSP_SOURCES " 'unsafe-inline';" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "img-src " PLATFORM_APP_LOCAL_CSP_SOURCES ";" 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "frame-src " PLATFORM_APP_LOCAL_CSP_SOURCES ";" 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "font-src " PLATFORM_APP_LOCAL_CSP_SOURCES ";" 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Media can be loaded from remote resources since: 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 1. <video> and <audio> have good fallback behavior when offline or under 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // spotty connectivity. 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2. Fetching via XHR and serving via blob: URLs currently does not allow 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // streaming or partial buffering. 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "media-src *;"; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CSPInfo::CSPInfo(const std::string& security_policy) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : content_security_policy(security_policy) { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CSPInfo::~CSPInfo() { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const std::string& CSPInfo::GetContentSecurityPolicy( 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension) { 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CSPInfo* csp_info = static_cast<CSPInfo*>( 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->GetManifestData(keys::kContentSecurityPolicy)); 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return csp_info ? csp_info->content_security_policy : base::EmptyString(); 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::string& CSPInfo::GetResourceContentSecurityPolicy( 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Extension* extension, 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& relative_path) { 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SandboxedPageInfo::IsSandboxedPage(extension, relative_path) ? 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SandboxedPageInfo::GetContentSecurityPolicy(extension) : 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetContentSecurityPolicy(extension); 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CSPHandler::CSPHandler(bool is_platform_app) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : is_platform_app_(is_platform_app) { 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CSPHandler::~CSPHandler() { 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool CSPHandler::Parse(Extension* extension, base::string16* error) { 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string key = Keys()[0]; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!extension->manifest()->HasPath(key)) { 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension->manifest_version() >= 2) { 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(abarth): Should we continue to let extensions override the 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // default Content-Security-Policy? 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string content_security_policy = is_platform_app_ ? 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kDefaultPlatformAppContentSecurityPolicy : 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kDefaultContentSecurityPolicy; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(ContentSecurityPolicyIsSecure(content_security_policy, 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->GetType())); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->SetManifestData(keys::kContentSecurityPolicy, 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new CSPInfo(content_security_policy)); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string content_security_policy; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!extension->manifest()->GetString(key, &content_security_policy)) { 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *error = base::ASCIIToUTF16(errors::kInvalidContentSecurityPolicy); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ContentSecurityPolicyIsLegal(content_security_policy)) { 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *error = base::ASCIIToUTF16(errors::kInvalidContentSecurityPolicy); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension->manifest_version() >= 2 && 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !ContentSecurityPolicyIsSecure(content_security_policy, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->GetType())) { 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *error = base::ASCIIToUTF16(errors::kInsecureContentSecurityPolicy); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->SetManifestData(keys::kContentSecurityPolicy, 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new CSPInfo(content_security_policy)); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool CSPHandler::AlwaysParseForType(Manifest::Type type) const { 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_platform_app_) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return type == Manifest::TYPE_PLATFORM_APP; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return type == Manifest::TYPE_EXTENSION || 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type == Manifest::TYPE_LEGACY_PACKAGED_APP; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const std::vector<std::string> CSPHandler::Keys() const { 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& key = is_platform_app_ ? 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) keys::kPlatformAppContentSecurityPolicy : keys::kContentSecurityPolicy; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SingleKey(key); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace extensions 134