blob: 978a86d20c69f21e3d17644d404543b88a730b1f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/extensions/csp_handler.h"
#include "base/memory/scoped_ptr.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/common/extensions/csp_validator.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
#include "chrome/common/extensions/manifest_handlers/sandboxed_page_info.h"
namespace keys = extension_manifest_keys;
namespace errors = extension_manifest_errors;
using extensions::csp_validator::ContentSecurityPolicyIsLegal;
using extensions::csp_validator::ContentSecurityPolicyIsSecure;
namespace extensions {
namespace {
const char kDefaultContentSecurityPolicy[] =
"script-src 'self' chrome-extension-resource:; object-src 'self'";
#define PLATFORM_APP_LOCAL_CSP_SOURCES \
"'self' data: chrome-extension-resource:"
const char kDefaultPlatformAppContentSecurityPolicy[] =
// Platform apps can only use local resources by default.
"default-src 'self' chrome-extension-resource:;"
// For remote resources, they can fetch them via XMLHttpRequest.
"connect-src *;"
// And serve them via data: or same-origin (blob:, filesystem:) URLs
"style-src " PLATFORM_APP_LOCAL_CSP_SOURCES " 'unsafe-inline';"
"img-src " PLATFORM_APP_LOCAL_CSP_SOURCES ";"
"frame-src " PLATFORM_APP_LOCAL_CSP_SOURCES ";"
"font-src " PLATFORM_APP_LOCAL_CSP_SOURCES ";"
// Media can be loaded from remote resources since:
// 1. <video> and <audio> have good fallback behavior when offline or under
// spotty connectivity.
// 2. Fetching via XHR and serving via blob: URLs currently does not allow
// streaming or partial buffering.
"media-src *;";
} // namespace
CSPInfo::CSPInfo(const std::string& security_policy)
: content_security_policy(security_policy) {
}
CSPInfo::~CSPInfo() {
}
// static
const std::string& CSPInfo::GetContentSecurityPolicy(
const Extension* extension) {
CSPInfo* csp_info = static_cast<CSPInfo*>(
extension->GetManifestData(keys::kContentSecurityPolicy));
return csp_info ? csp_info->content_security_policy : EmptyString();
}
// static
const std::string& CSPInfo::GetResourceContentSecurityPolicy(
const Extension* extension,
const std::string& relative_path) {
return SandboxedPageInfo::IsSandboxedPage(extension, relative_path) ?
SandboxedPageInfo::GetContentSecurityPolicy(extension) :
GetContentSecurityPolicy(extension);
}
CSPHandler::CSPHandler(bool is_platform_app)
: is_platform_app_(is_platform_app) {
}
CSPHandler::~CSPHandler() {
}
bool CSPHandler::Parse(Extension* extension, string16* error) {
const std::string key = Keys()[0];
if (!extension->manifest()->HasPath(key)) {
if (extension->manifest_version() >= 2) {
// TODO(abarth): Should we continue to let extensions override the
// default Content-Security-Policy?
std::string content_security_policy = is_platform_app_ ?
kDefaultPlatformAppContentSecurityPolicy :
kDefaultContentSecurityPolicy;
CHECK(ContentSecurityPolicyIsSecure(content_security_policy,
extension->GetType()));
extension->SetManifestData(keys::kContentSecurityPolicy,
new CSPInfo(content_security_policy));
}
return true;
}
std::string content_security_policy;
if (!extension->manifest()->GetString(key, &content_security_policy)) {
*error = ASCIIToUTF16(errors::kInvalidContentSecurityPolicy);
return false;
}
if (!ContentSecurityPolicyIsLegal(content_security_policy)) {
*error = ASCIIToUTF16(errors::kInvalidContentSecurityPolicy);
return false;
}
if (extension->manifest_version() >= 2 &&
!ContentSecurityPolicyIsSecure(content_security_policy,
extension->GetType())) {
*error = ASCIIToUTF16(errors::kInsecureContentSecurityPolicy);
return false;
}
extension->SetManifestData(keys::kContentSecurityPolicy,
new CSPInfo(content_security_policy));
return true;
}
bool CSPHandler::AlwaysParseForType(Manifest::Type type) const {
if (is_platform_app_)
return type == Manifest::TYPE_PLATFORM_APP;
else
return type == Manifest::TYPE_EXTENSION ||
type == Manifest::TYPE_LEGACY_PACKAGED_APP;
}
const std::vector<std::string> CSPHandler::Keys() const {
const std::string& key = is_platform_app_ ?
keys::kPlatformAppContentSecurityPolicy : keys::kContentSecurityPolicy;
return SingleKey(key);
}
} // namespace extensions
|