blob: 5eb80657a776999ef25f6075d7be20d80f91d0a1 [file] [log] [blame]
// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "cobalt/web/csp_delegate_factory.h"
#include <memory>
#include <utility>
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/threading/thread_local.h"
#include "cobalt/web/csp_delegate.h"
#include "cobalt/web/csp_violation_reporter.h"
#include "cobalt/web/window_or_worker_global_scope.h"
namespace cobalt {
namespace web {
namespace {
#if !defined(COBALT_FORCE_CSP)
// 32-bit random number.
// Not exactly cryptographically secure, but hopefully enough to stop us
// mistakenly allowing insecure access.
const int kInsecureAllowedToken = 0x5b38b65b;
// static
bool InsecureAllowed(int token) {
if (token == kInsecureAllowedToken) {
return true;
} else {
LOG(FATAL) << "Not permitted to create insecure CSP delegates. "
"To allow this, get a token from a call to "
"GetInsecureAllowedToken and pass as the last argument to "
"the CspDelegateFactory::Create function.";
return false;
}
}
CspDelegate* CreateInsecureDelegate(
std::unique_ptr<CspViolationReporter> violation_reporter, const GURL& url,
csp::CSPHeaderPolicy header_policy,
const base::Closure& policy_changed_callback, int insecure_allowed_token) {
if (InsecureAllowed(insecure_allowed_token)) {
return new CspDelegateInsecure();
} else {
return NULL;
}
}
#endif // !defined(COBALT_FORCE_CSP)
CspDelegate* CreateSecureDelegate(
std::unique_ptr<CspViolationReporter> violation_reporter, const GURL& url,
csp::CSPHeaderPolicy header_policy,
const base::Closure& policy_changed_callback, int insecure_allowed_token) {
return new CspDelegateSecure(std::move(violation_reporter), url,
header_policy, policy_changed_callback);
}
} // namespace
#if !defined(COBALT_FORCE_CSP)
int CspDelegateFactory::GetInsecureAllowedToken() {
return kInsecureAllowedToken;
}
#endif // !defined(COBALT_FORCE_CSP)
CspDelegateFactory* CspDelegateFactory::GetInstance() {
return base::Singleton<CspDelegateFactory>::get();
}
CspDelegateFactory::CspDelegateFactory() {
method_[kCspEnforcementEnable] = CreateSecureDelegate;
#if !defined(COBALT_FORCE_CSP)
method_[kCspEnforcementDisable] = CreateInsecureDelegate;
#endif // !defined(COBALT_FORCE_CSP)
}
std::unique_ptr<CspDelegate> CspDelegateFactory::CreateDelegate(
WindowOrWorkerGlobalScope* global, const CspDelegate::Options& options,
const base::Closure& policy_changed_callback) {
std::unique_ptr<CspViolationReporter> violation_reporter(
new CspViolationReporter(global, options.post_sender));
std::unique_ptr<CspDelegate> delegate(method_[options.enforcement_type](
std::move(violation_reporter),
(global ? global->environment_settings()->creation_url() : GURL()),
options.header_policy, policy_changed_callback,
options.insecure_allowed_token));
return delegate;
}
#if !defined(COBALT_FORCE_CSP)
// For use by tests.
void CspDelegateFactory::OverrideCreator(CspEnforcementType type,
CspDelegateCreator creator) {
DCHECK_LT(type, kCspEnforcementCount);
method_[type] = creator;
}
#endif // !defined(COBALT_FORCE_CSP)
} // namespace web
} // namespace cobalt