summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc151
1 files changed, 124 insertions, 27 deletions
diff --git a/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc b/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc
index 3a3e37569db..462286b0ac0 100644
--- a/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc
+++ b/chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
+#include <ostream>
+
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "services/network/public/cpp/features.h"
@@ -93,6 +95,40 @@ bool IsCrossNavigationFeature(OriginTrialFeature feature) {
return origin_trials::GetNavigationOriginTrialFeatures().Contains(feature);
}
+std::ostream& operator<<(std::ostream& stream, OriginTrialTokenStatus status) {
+// Included for debug builds only for reduced binary size.
+#ifndef NDEBUG
+ switch (status) {
+ case OriginTrialTokenStatus::kSuccess:
+ return stream << "kSuccess";
+ case OriginTrialTokenStatus::kNotSupported:
+ return stream << "kNotSupported";
+ case OriginTrialTokenStatus::kInsecure:
+ return stream << "kInsecure";
+ case OriginTrialTokenStatus::kExpired:
+ return stream << "kExpired";
+ case OriginTrialTokenStatus::kWrongOrigin:
+ return stream << "kWrongOrigin";
+ case OriginTrialTokenStatus::kInvalidSignature:
+ return stream << "kInvalidSignature";
+ case OriginTrialTokenStatus::kMalformed:
+ return stream << "kMalformed";
+ case OriginTrialTokenStatus::kWrongVersion:
+ return stream << "kWrongVersion";
+ case OriginTrialTokenStatus::kFeatureDisabled:
+ return stream << "kFeatureDisabled";
+ case OriginTrialTokenStatus::kTokenDisabled:
+ return stream << "kTokenDisabled";
+ case OriginTrialTokenStatus::kFeatureDisabledForUser:
+ return stream << "kFeatureDisabledForUser";
+ }
+ NOTREACHED();
+ return stream;
+#else
+ return stream << (static_cast<int>(status));
+#endif // ifndef NDEBUG
+}
+
} // namespace
OriginTrialContext::OriginTrialContext()
@@ -192,23 +228,51 @@ OriginTrialContext::GetEnabledNavigationFeatures() const {
}
void OriginTrialContext::AddToken(const String& token) {
+ AddTokenInternal(token, GetSecurityOrigin(), IsSecureContext(), nullptr,
+ false);
+}
+
+void OriginTrialContext::AddTokenFromExternalScript(
+ const String& token,
+ const SecurityOrigin* origin) {
+ bool is_script_origin_secure = false;
+ if (origin &&
+ RuntimeEnabledFeatures::ThirdPartyOriginTrialsEnabled(context_)) {
+ DVLOG(1) << "AddTokenFromExternalScript: "
+ << (origin ? origin->ToString() : "null");
+ is_script_origin_secure = origin->IsPotentiallyTrustworthy();
+ } else {
+ origin = nullptr;
+ }
+ AddTokenInternal(token, GetSecurityOrigin(), IsSecureContext(), origin,
+ is_script_origin_secure);
+}
+
+void OriginTrialContext::AddTokenInternal(const String& token,
+ const SecurityOrigin* origin,
+ bool is_origin_secure,
+ const SecurityOrigin* script_origin,
+ bool is_script_origin_secure) {
if (token.IsEmpty())
return;
tokens_.push_back(token);
- if (EnableTrialFromToken(GetSecurityOrigin(), IsSecureContext(), token)) {
- // Only install pending features if the provided token is valid. Otherwise,
- // there was no change to the list of enabled features.
+
+ bool enabled = EnableTrialFromToken(origin, is_origin_secure, script_origin,
+ is_script_origin_secure, token);
+ if (enabled) {
+ // Only install pending features if the provided token is valid.
+ // Otherwise, there was no change to the list of enabled features.
InitializePendingFeatures();
}
}
void OriginTrialContext::AddTokens(const Vector<String>& tokens) {
- AddTokens(GetSecurityOrigin(), IsSecureContext(), tokens);
+ AddTokens(tokens, GetSecurityOrigin(), IsSecureContext());
}
-void OriginTrialContext::AddTokens(const SecurityOrigin* origin,
- bool is_secure,
- const Vector<String>& tokens) {
+void OriginTrialContext::AddTokens(const Vector<String>& tokens,
+ const SecurityOrigin* origin,
+ bool is_secure) {
if (tokens.IsEmpty())
return;
bool found_valid = false;
@@ -282,15 +346,15 @@ bool OriginTrialContext::IsFeatureEnabled(OriginTrialFeature feature) const {
// - Spec: https://w3c.github.io/webcomponents/spec/imports/#terminology
// - Spec issue: https://github.com/w3c/webcomponents/issues/197
// For the purposes of origin trials, we consider imported documents to be
- // part of the master document. Thus, check if the trial is enabled in the
- // master document and use that result.
+ // part of the tree_root document. Thus, check if the trial is enabled in the
+ // tree_root document and use that result.
auto* window = DynamicTo<LocalDOMWindow>(context_.Get());
auto* document = window ? window->document() : nullptr;
if (!document || !document->IsHTMLImport())
return false;
const OriginTrialContext* context =
- document->MasterDocument().GetOriginTrialContext();
+ document->TreeRootDocument().GetOriginTrialContext();
if (!context)
return false;
return context->IsFeatureEnabled(feature);
@@ -381,9 +445,44 @@ bool OriginTrialContext::EnableTrialFromName(const String& trial_name,
return did_enable_feature;
}
+OriginTrialTokenStatus OriginTrialContext::ValidateTokenResult(
+ const String& trial_name,
+ bool is_origin_secure,
+ bool is_script_origin_secure,
+ bool is_third_party) {
+ bool is_secure = is_origin_secure;
+ if (is_third_party) {
+ if (!origin_trials::IsTrialEnabledForThirdPartyOrigins(trial_name)) {
+ DVLOG(1) << "ValidateTokenResult: feature disabled for third party trial";
+ return OriginTrialTokenStatus::kFeatureDisabled;
+ }
+ // For third-party tokens, both the current origin and the the script origin
+ // must be secure.
+ is_secure &= is_script_origin_secure;
+ }
+
+ // Origin trials are only enabled for secure origins. The only exception
+ // is for deprecation trials.
+ if (!is_secure &&
+ !origin_trials::IsTrialEnabledForInsecureContext(trial_name)) {
+ DVLOG(1) << "ValidateTokenResult: not secure";
+ return OriginTrialTokenStatus::kInsecure;
+ }
+ return OriginTrialTokenStatus::kSuccess;
+}
+
bool OriginTrialContext::EnableTrialFromToken(const SecurityOrigin* origin,
bool is_secure,
const String& token) {
+ return EnableTrialFromToken(origin, is_secure, nullptr, false, token);
+}
+
+bool OriginTrialContext::EnableTrialFromToken(
+ const SecurityOrigin* origin,
+ bool is_origin_secure,
+ const SecurityOrigin* script_origin,
+ bool is_script_origin_secure,
+ const String& token) {
DCHECK(!token.IsEmpty());
if (!trial_token_validator_) {
@@ -393,33 +492,31 @@ bool OriginTrialContext::EnableTrialFromToken(const SecurityOrigin* origin,
bool valid = false;
StringUTF8Adaptor token_string(token);
+ url::Origin script_url_origin;
+ if (script_origin)
+ script_url_origin = script_origin->ToUrlOrigin();
TrialTokenResult token_result = trial_token_validator_->ValidateToken(
- token_string.AsStringPiece(), origin->ToUrlOrigin(), base::Time::Now());
- DVLOG(1) << "EnableTrialFromToken: token_result = "
- << static_cast<int>(token_result.status) << ", token = " << token;
-
- if (token_result.status == OriginTrialTokenStatus::kSuccess) {
+ token_string.AsStringPiece(), origin->ToUrlOrigin(),
+ script_origin ? &script_url_origin : nullptr, base::Time::Now());
+ DVLOG(1) << "EnableTrialFromToken: token_result = " << token_result.status
+ << ", token = " << token;
+ OriginTrialTokenStatus status = token_result.status;
+ if (status == OriginTrialTokenStatus::kSuccess) {
String trial_name = String::FromUTF8(token_result.feature_name.data(),
token_result.feature_name.size());
if (origin_trials::IsTrialValid(trial_name)) {
- // Origin trials are only enabled for secure origins. The only exception
- // is for deprecation trials.
- if (is_secure ||
- origin_trials::IsTrialEnabledForInsecureContext(trial_name)) {
+ status = ValidateTokenResult(trial_name, is_origin_secure,
+ is_script_origin_secure,
+ token_result.is_third_party);
+ if (status == OriginTrialTokenStatus::kSuccess)
valid = EnableTrialFromName(trial_name, token_result.expiry_time);
- } else {
- // Insecure origin and trial is restricted to secure origins.
- DVLOG(1) << "EnableTrialFromToken: not secure";
- token_result.status = OriginTrialTokenStatus::kInsecure;
- }
}
}
-
- RecordTokenValidationResultHistogram(token_result.status);
+ RecordTokenValidationResultHistogram(status);
return valid;
}
-void OriginTrialContext::Trace(Visitor* visitor) {
+void OriginTrialContext::Trace(Visitor* visitor) const {
visitor->Trace(context_);
}