代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/firefox 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
# HG changeset patch
# User pbz <pbz@mozilla.com>
# Date 1600689290 0
# Mon Sep 21 11:54:50 2020 +0000
# Node ID efcefed227f304781326e7c8a52633559a79b6adlist oniguruma.spec
# Parent 32d03662a363850006f648c22e825b3e886b29bc
Bug 1314912 - Rate limit calls to History and Location interfaces. r=smaug9.0-3
This adds a rate limit to methods and setters of the History and Location
for non-system callers.
The rate limit is counted per BrowsingContext and can be controlled by prefs.
This patch is based on the original rate limit patch by :freesamael.
Differential Revision: https://phabricator.services.mozilla.com/D90136
diff -r 32d03662a363 -r efcefed227f3 docshell/base/BrowsingContext.cpp
--- a/docshell/base/BrowsingContext.cpp 2020-07-21 06:49:37.000000000 +0800
+++ b/docshell/base/BrowsingContext.cpp 2021-01-06 10:22:57.966851379 +0800
@@ -2459,6 +2459,56 @@ bool BrowsingContext::CanSet(FieldIndex<
return GetBrowserId() == 0 && IsTop() && Children().IsEmpty();
}
+nsresult BrowsingContext::CheckLocationChangeRateLimit(CallerType aCallerType) {
+ // We only rate limit non system callers
+ if (aCallerType == CallerType::System) {
+ return NS_OK;
+ }
+
+ // Fetch rate limiting preferences
+ uint32_t limitCount =
+ StaticPrefs::dom_navigation_locationChangeRateLimit_count();
+ uint32_t timeSpanSeconds =
+ StaticPrefs::dom_navigation_locationChangeRateLimit_timespan();
+
+ // Disable throttling if either of the preferences is set to 0.
+ if (limitCount == 0 || timeSpanSeconds == 0) {
+ return NS_OK;
+ }
+
+ TimeDuration throttleSpan = TimeDuration::FromSeconds(timeSpanSeconds);
+
+ if (mLocationChangeRateLimitSpanStart.IsNull() ||
+ ((TimeStamp::Now() - mLocationChangeRateLimitSpanStart) > throttleSpan)) {
+ // Initial call or timespan exceeded, reset counter and timespan.
+ mLocationChangeRateLimitSpanStart = TimeStamp::Now();
+ mLocationChangeRateLimitCount = 1;
+ return NS_OK;
+ }
+
+ if (mLocationChangeRateLimitCount >= limitCount) {
+ // Rate limit reached
+
+ Document* doc = GetDocument();
+ if (doc) {
+ nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,NS_LITERAL_CSTRING("DOM"), doc,
+ nsContentUtils::eDOM_PROPERTIES,
+ "LocChangeFloodingPrevented");
+ }
+
+ return NS_ERROR_DOM_SECURITY_ERR;
+ }
+
+ mLocationChangeRateLimitCount++;
+ return NS_OK;
+}
+
+void BrowsingContext::ResetLocationChangeRateLimit() {
+ // Resetting the timestamp object will cause the check function to
+ // init again and reset the rate limit.
+ mLocationChangeRateLimitSpanStart = TimeStamp();
+}
+
} // namespace dom
namespace ipc {
diff -r 32d03662a363 -r efcefed227f3 docshell/base/BrowsingContext.h
--- a/docshell/base/BrowsingContext.h 2020-07-21 06:49:37.000000000 +0800
+++ b/docshell/base/BrowsingContext.h 2021-01-06 10:22:57.954851198 +0800
@@ -652,6 +652,16 @@ class BrowsingContext : public nsILoadCo
bool CrossOriginIsolated();
+ // Checks if we reached the rate limit for calls to Location and History API.
+ // The rate limit is controlled by the
+ // "dom.navigation.locationChangeRateLimit" prefs.
+ // Rate limit applies per BrowsingContext.
+ // Returns NS_OK if we are below the rate limit and increments the counter.
+ // Returns NS_ERROR_DOM_SECURITY_ERR if limit is reached.
+ nsresult CheckLocationChangeRateLimit(CallerType aCallerType);
+
+ void ResetLocationChangeRateLimit();
+
protected:
virtual ~BrowsingContext();
BrowsingContext(WindowContext* aParentWindow, BrowsingContextGroup* aGroup,
@@ -932,6 +942,11 @@ class BrowsingContext : public nsILoadCo
RefPtr<SessionStorageManager> mSessionStorageManager;
RefPtr<ChildSHistory> mChildSessionHistory;
+
+ // Counter and time span for rate limiting Location and History API calls.
+ // Used by CheckLocationChangeRateLimit. Do not apply cross-process.
+ uint32_t mLocationChangeRateLimitCount;
+ mozilla::TimeStamp mLocationChangeRateLimitSpanStart;
};
/**
diff -r 32d03662a363 -r efcefed227f3 docshell/shistory/ChildSHistory.cpp
--- a/docshell/shistory/ChildSHistory.cpp 2020-07-21 06:49:37.000000000 +0800
+++ b/docshell/shistory/ChildSHistory.cpp 2021-01-06 10:22:58.058852764 +0800
@@ -105,7 +105,14 @@ void ChildSHistory::Go(int32_t aOffset,
}
}
-void ChildSHistory::AsyncGo(int32_t aOffset, bool aRequireUserInteraction) {
+void ChildSHistory::AsyncGo(int32_t aOffset, bool aRequireUserInteraction,
+ CallerType aCallerType, ErrorResult& aRv) {
+ nsresult rv = mBrowsingContext->CheckLocationChangeRateLimit(aCallerType);
+ if (NS_FAILED(rv)) {
+ aRv.Throw(rv);
+ return;
+ }
+
if (!CanGo(aOffset)) {
return;
}
diff -r 32d03662a363 -r efcefed227f3 docshell/shistory/ChildSHistory.h
--- a/docshell/shistory/ChildSHistory.h 2020-07-21 06:49:37.000000000 +0800
+++ b/docshell/shistory/ChildSHistory.h 2021-01-06 10:22:58.058852764 +0800
@@ -64,8 +64,8 @@ class ChildSHistory : public nsISupports
*/
bool CanGo(int32_t aOffset);
void Go(int32_t aOffset, bool aRequireUserInteraction, ErrorResult& aRv);
- void AsyncGo(int32_t aOffset, bool aRequireUserInteraction);
-
+ void AsyncGo(int32_t aOffset, bool aRequireUserInteraction,
+ CallerType aCallerType, ErrorResult& aRv);
void RemovePendingHistoryNavigations();
/**
diff -r 32d03662a363 -r efcefed227f3 dom/base/LocationBase.cpp
--- a/dom/base/LocationBase.cpp 2020-07-21 04:53:13.000000000 +0800
+++ b/dom/base/LocationBase.cpp 2021-01-06 10:22:46.030671698 +0800
@@ -116,6 +116,16 @@ void LocationBase::SetURI(nsIURI* aURI,
return;
}
+ CallerType callerType = aSubjectPrincipal.IsSystemPrincipal()
+ ? CallerType::System
+ : CallerType::NonSystem;
+
+ nsresult rv = bc->CheckLocationChangeRateLimit(callerType);
+ if (NS_FAILED(rv)) {
+ aRv.Throw(rv);
+ return;
+ }
+
RefPtr<nsDocShellLoadState> loadState =
CheckURL(aURI, aSubjectPrincipal, aRv);
if (aRv.Failed()) {
@@ -141,7 +151,7 @@ void LocationBase::SetURI(nsIURI* aURI,
loadState->SetLoadFlags(nsIWebNavigation::LOAD_FLAGS_NONE);
loadState->SetFirstParty(true);
- nsresult rv = bc->LoadURI(loadState);
+ rv = bc->LoadURI(loadState);
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
}
diff -r 32d03662a363 -r efcefed227f3 dom/base/nsHistory.cpp
--- a/dom/base/nsHistory.cpp 2020-07-21 06:49:37.000000000 +0800
+++ b/dom/base/nsHistory.cpp 2021-01-06 10:22:46.030671698 +0800
@@ -135,7 +135,7 @@ void nsHistory::GetState(JSContext* aCx,
aResult.setNull();
}
-void nsHistory::Go(int32_t aDelta, ErrorResult& aRv) {
+void nsHistory::Go(int32_t aDelta, CallerType aCallerType, ErrorResult& aRv) {
nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
if (!win || !win->HasActiveDocument()) {
return aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
@@ -157,15 +157,17 @@ void nsHistory::Go(int32_t aDelta, Error
// Ignore the return value from Go(), since returning errors from Go() can
// lead to exceptions and a possible leak of history length
+ // AsyncGo throws if we hit the location change rate limit.
if (StaticPrefs::dom_window_history_async()) {
- session_history->AsyncGo(aDelta, /* aRequireUserInteraction = */ false);
+ session_history->AsyncGo(aDelta, /* aRequireUserInteraction = */ false,
+ aCallerType, aRv);
} else {
session_history->Go(aDelta, /* aRequireUserInteraction = */ false,
IgnoreErrors());
}
}
-void nsHistory::Back(ErrorResult& aRv) {
+void nsHistory::Back(CallerType aCallerType, ErrorResult& aRv) {
nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
if (!win || !win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
@@ -181,13 +183,14 @@ void nsHistory::Back(ErrorResult& aRv) {
}
if (StaticPrefs::dom_window_history_async()) {
- sHistory->AsyncGo(-1, /* aRequireUserInteraction = */ false);
+ sHistory->AsyncGo(-1, /* aRequireUserInteraction = */ false, aCallerType,
+ aRv);
} else {
sHistory->Go(-1, /* aRequireUserInteraction = */ false, IgnoreErrors());
}
}
-void nsHistory::Forward(ErrorResult& aRv) {
+void nsHistory::Forward(CallerType aCallerType, ErrorResult& aRv) {
nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
if (!win || !win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
@@ -203,7 +206,8 @@ void nsHistory::Forward(ErrorResult& aRv
}
if (StaticPrefs::dom_window_history_async()) {
- sHistory->AsyncGo(1, /* aRequireUserInteraction = */ false);
+ sHistory->AsyncGo(1, /* aRequireUserInteraction = */ false, aCallerType,
+ aRv);
} else {
sHistory->Go(1, /* aRequireUserInteraction = */ false, IgnoreErrors());
}
@@ -211,19 +215,20 @@ void nsHistory::Forward(ErrorResult& aRv
void nsHistory::PushState(JSContext* aCx, JS::Handle<JS::Value> aData,
const nsAString& aTitle, const nsAString& aUrl,
- ErrorResult& aRv) {
- PushOrReplaceState(aCx, aData, aTitle, aUrl, aRv, false);
+ CallerType aCallerType, ErrorResult& aRv) {
+ PushOrReplaceState(aCx, aData, aTitle, aUrl, aCallerType, aRv, false);
}
void nsHistory::ReplaceState(JSContext* aCx, JS::Handle<JS::Value> aData,
const nsAString& aTitle, const nsAString& aUrl,
- ErrorResult& aRv) {
- PushOrReplaceState(aCx, aData, aTitle, aUrl, aRv, true);
+ CallerType aCallerType, ErrorResult& aRv) {
+ PushOrReplaceState(aCx, aData, aTitle, aUrl, aCallerType, aRv, true);
}
void nsHistory::PushOrReplaceState(JSContext* aCx, JS::Handle<JS::Value> aData,
const nsAString& aTitle,
- const nsAString& aUrl, ErrorResult& aRv,
+ const nsAString& aUrl,
+ CallerType aCallerType, ErrorResult& aRv,
bool aReplace) {
nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
if (!win) {
@@ -238,6 +243,15 @@ void nsHistory::PushOrReplaceState(JSCon
return;
}
+ BrowsingContext* bc = win->GetBrowsingContext();
+ if (bc) {
+ nsresult rv = bc->CheckLocationChangeRateLimit(aCallerType);
+ if (NS_FAILED(rv)) {
+ aRv.Throw(rv);
+ return;
+ }
+ }
+
// AddState might run scripts, so we need to hold a strong reference to the
// docShell here to keep it from going away.
nsCOMPtr<nsIDocShell> docShell = win->GetDocShell();
diff -r 32d03662a363 -r efcefed227f3 dom/base/nsHistory.h
--- a/dom/base/nsHistory.h 2020-07-21 04:53:13.000000000 +0800
+++ b/dom/base/nsHistory.h 2021-01-06 10:22:46.030671698 +0800
@@ -42,14 +42,17 @@ class nsHistory final : public nsISuppor
mozilla::ErrorResult& aRv);
void GetState(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
mozilla::ErrorResult& aRv) const;
- void Go(int32_t aDelta, mozilla::ErrorResult& aRv);
- void Back(mozilla::ErrorResult& aRv);
- void Forward(mozilla::ErrorResult& aRv);
+ void Go(int32_t aDelta, mozilla::dom::CallerType aCallerType,
+ mozilla::ErrorResult& aRv);
+ void Back(mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aRv);
+ void Forward(mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aRv);
void PushState(JSContext* aCx, JS::Handle<JS::Value> aData,
const nsAString& aTitle, const nsAString& aUrl,
+ mozilla::dom::CallerType aCallerType,
mozilla::ErrorResult& aRv);
void ReplaceState(JSContext* aCx, JS::Handle<JS::Value> aData,
const nsAString& aTitle, const nsAString& aUrl,
+ mozilla::dom::CallerType aCallerType,
mozilla::ErrorResult& aRv);
protected:
@@ -59,6 +62,7 @@ class nsHistory final : public nsISuppor
void PushOrReplaceState(JSContext* aCx, JS::Handle<JS::Value> aData,
const nsAString& aTitle, const nsAString& aUrl,
+ mozilla::dom::CallerType aCallerType,
mozilla::ErrorResult& aRv, bool aReplace);
already_AddRefed<mozilla::dom::ChildSHistory> GetSessionHistory() const;
diff -r 32d03662a363 -r efcefed227f3 dom/chrome-webidl/BrowsingContext.webidl
--- a/dom/chrome-webidl/BrowsingContext.webidl 2020-07-21 06:49:37.000000000 +0800
+++ b/dom/chrome-webidl/BrowsingContext.webidl 2021-01-06 10:22:42.362616481 +0800
@@ -120,6 +120,9 @@ interface BrowsingContext {
* under the new browser element.
*/
attribute unsigned long long browserId;
+
+ // Resets the location change rate limit. Used for testing.
+ void resetLocationChangeRateLimit();
};
BrowsingContext includes LoadContextMixin;
diff -r 32d03662a363 -r efcefed227f3 dom/locales/en-US/chrome/dom/dom.properties
--- a/dom/locales/en-US/chrome/dom/dom.properties 2020-07-21 06:49:37.000000000 +0800
+++ b/dom/locales/en-US/chrome/dom/dom.properties 2021-01-06 10:22:42.418617324 +0800
@@ -393,3 +393,5 @@ UnknownProtocolNavigationPrevented=Preve
PostMessageSharedMemoryObjectToCrossOriginWarning=Cannot post message containing a shared memory object to a cross-origin window.
# LOCALIZATION NOTE: %S is the URL of the resource in question
UnusedLinkPreloadPending=The resource at “%S” preloaded with link preload was not used within a few seconds. Make sure all attributes of the preload tag are set correctly.
+# LOCALIZATION NOTE: Do not translate "Location" and "History".
+LocChangeFloodingPrevented=Too many calls to Location or History APIs within a short timeframe.
diff -r 32d03662a363 -r efcefed227f3 dom/webidl/History.webidl
--- a/dom/webidl/History.webidl 2020-07-21 04:53:19.000000000 +0800
+++ b/dom/webidl/History.webidl 2021-01-06 10:22:42.298615518 +0800
@@ -21,14 +21,14 @@ interface History {
attribute ScrollRestoration scrollRestoration;
[Throws]
readonly attribute any state;
- [Throws]
+ [Throws, NeedsCallerType]
void go(optional long delta = 0);
- [Throws]
+ [Throws, NeedsCallerType]
void back();
- [Throws]
+ [Throws, NeedsCallerType]
void forward();
- [Throws]
+ [Throws, NeedsCallerType]
void pushState(any data, DOMString title, optional DOMString? url = null);
- [Throws]
+ [Throws, NeedsCallerType]
void replaceState(any data, DOMString title, optional DOMString? url = null);
};
diff -r 32d03662a363 -r efcefed227f3 modules/libpref/init/StaticPrefList.yaml
--- a/modules/libpref/init/StaticPrefList.yaml 2021-01-06 10:25:09.272827991 +0800
+++ b/modules/libpref/init/StaticPrefList.yaml 2021-01-06 10:22:36.458527604 +0800
@@ -2181,6 +2181,19 @@
value: true
mirror: always
+# Limit of location change caused by content scripts in a time span per
+# BrowsingContext. This includes calls to History and Location APIs.
+- name: dom.navigation.locationChangeRateLimit.count
+ type: uint32_t
+ value: 200
+ mirror: always
+
+# Time span in seconds for location change rate limit.
+- name: dom.navigation.locationChangeRateLimit.timespan
+ type: uint32_t
+ value: 10
+ mirror: always
+
# Network Information API
- name: dom.netinfo.enabled
type: RelaxedAtomicBool
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。