1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/common/manifest_handlers/sandboxed_page_info.h"
7 #include "base/lazy_instance.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/values.h"
12 #include "extensions/common/csp_validator.h"
13 #include "extensions/common/error_utils.h"
14 #include "extensions/common/manifest_constants.h"
15 #include "extensions/common/url_pattern.h"
17 namespace extensions
{
21 namespace keys
= extensions::manifest_keys
;
22 namespace errors
= manifest_errors
;
24 const char kDefaultSandboxedPageContentSecurityPolicy
[] =
25 "sandbox allow-scripts allow-forms allow-popups";
27 static base::LazyInstance
<SandboxedPageInfo
> g_empty_sandboxed_info
=
28 LAZY_INSTANCE_INITIALIZER
;
30 const SandboxedPageInfo
& GetSandboxedPageInfo(const Extension
* extension
) {
31 SandboxedPageInfo
* info
= static_cast<SandboxedPageInfo
*>(
32 extension
->GetManifestData(keys::kSandboxedPages
));
33 return info
? *info
: g_empty_sandboxed_info
.Get();
38 SandboxedPageInfo::SandboxedPageInfo() {
41 SandboxedPageInfo::~SandboxedPageInfo() {
44 const std::string
& SandboxedPageInfo::GetContentSecurityPolicy(
45 const Extension
* extension
) {
46 return GetSandboxedPageInfo(extension
).content_security_policy
;
49 const URLPatternSet
& SandboxedPageInfo::GetPages(const Extension
* extension
) {
50 return GetSandboxedPageInfo(extension
).pages
;
53 bool SandboxedPageInfo::IsSandboxedPage(const Extension
* extension
,
54 const std::string
& relative_path
) {
55 return extension
->ResourceMatches(GetPages(extension
), relative_path
);
58 SandboxedPageHandler::SandboxedPageHandler() {
61 SandboxedPageHandler::~SandboxedPageHandler() {
64 bool SandboxedPageHandler::Parse(Extension
* extension
, base::string16
* error
) {
65 scoped_ptr
<SandboxedPageInfo
> sandboxed_info(new SandboxedPageInfo
);
67 const base::ListValue
* list_value
= NULL
;
68 if (!extension
->manifest()->GetList(keys::kSandboxedPages
, &list_value
)) {
69 *error
= base::ASCIIToUTF16(errors::kInvalidSandboxedPagesList
);
73 for (size_t i
= 0; i
< list_value
->GetSize(); ++i
) {
74 std::string relative_path
;
75 if (!list_value
->GetString(i
, &relative_path
)) {
76 *error
= ErrorUtils::FormatErrorMessageUTF16(
77 errors::kInvalidSandboxedPage
, base::IntToString(i
));
80 URLPattern
pattern(URLPattern::SCHEME_EXTENSION
);
81 if (pattern
.Parse(extension
->url().spec()) != URLPattern::PARSE_SUCCESS
) {
82 *error
= ErrorUtils::FormatErrorMessageUTF16(
83 errors::kInvalidURLPatternError
, extension
->url().spec());
86 while (relative_path
[0] == '/')
87 relative_path
= relative_path
.substr(1, relative_path
.length() - 1);
88 pattern
.SetPath(pattern
.path() + relative_path
);
89 sandboxed_info
->pages
.AddPattern(pattern
);
92 if (extension
->manifest()->HasPath(keys::kSandboxedPagesCSP
)) {
93 if (!extension
->manifest()->GetString(
94 keys::kSandboxedPagesCSP
,
95 &sandboxed_info
->content_security_policy
)) {
96 *error
= base::ASCIIToUTF16(errors::kInvalidSandboxedPagesCSP
);
100 if (!csp_validator::ContentSecurityPolicyIsLegal(
101 sandboxed_info
->content_security_policy
) ||
102 !csp_validator::ContentSecurityPolicyIsSandboxed(
103 sandboxed_info
->content_security_policy
, extension
->GetType())) {
104 *error
= base::ASCIIToUTF16(errors::kInvalidSandboxedPagesCSP
);
108 sandboxed_info
->content_security_policy
=
109 kDefaultSandboxedPageContentSecurityPolicy
;
110 CHECK(csp_validator::ContentSecurityPolicyIsSandboxed(
111 sandboxed_info
->content_security_policy
, extension
->GetType()));
114 extension
->SetManifestData(keys::kSandboxedPages
, sandboxed_info
.release());
118 const std::vector
<std::string
> SandboxedPageHandler::Keys() const {
119 return SingleKey(keys::kSandboxedPages
);
122 } // namespace extensions