[DNR] Improve request method rule conditions for non-HTTP(s) requests
We previously added HTTP request method based matching for declarativeNetRequest rules, but non-HTTP(s) requests were treated as having the GET request method. With this change, we instead consider non-HTTP(s) requests to have a special NON_HTTP request method. The result is that rules with a requestMethods condition will no longer match non-HTTP(s) requests. Rules with an excludedRequestMethods condition will continue to match non-HTTP(s) requests, even if every HTTP request method is excluded. Bug: 1013583 Change-Id: Ib140894cba86e7fd59861fe2594c2b449ae4fdeb Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2940865 Commit-Queue: Charlie Harrison <csharrison@chromium.org> Reviewed-by: Charlie Harrison <csharrison@chromium.org> Reviewed-by: Karan Bhatia <karandeepb@chromium.org> Reviewed-by: Kelvin Jiang <kelvinjiang@chromium.org> Cr-Commit-Position: refs/heads/master@{#893014}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
28cf8364ac
commit
2d9121fa22
chrome/browser/extensions/api/declarative_net_request
components
subresource_filter
core
common
url_pattern_index
extensions
browser
api
declarative_net_request
common
@@ -5924,6 +5924,92 @@ IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests that the "requestMethods" and "excludedRequestMethods" properties of a
|
||||||
|
// rule condition are considered properly for non-HTTP(s) requests.
|
||||||
|
IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest,
|
||||||
|
BlockRequests_NonHTTPMethods) {
|
||||||
|
// Load an extension with some DNR rules that have different request method
|
||||||
|
// conditions.
|
||||||
|
std::vector<TestRule> rules;
|
||||||
|
|
||||||
|
TestRule rule1 = CreateGenericRule(1);
|
||||||
|
rule1.condition->url_filter = "default";
|
||||||
|
rules.push_back(rule1);
|
||||||
|
|
||||||
|
TestRule rule2 = CreateGenericRule(2);
|
||||||
|
rule2.condition->url_filter = "all_methods";
|
||||||
|
rule2.condition->request_methods = {"delete", "get", "head", "options",
|
||||||
|
"patch", "post", "put"};
|
||||||
|
rules.push_back(rule2);
|
||||||
|
|
||||||
|
TestRule rule3 = CreateGenericRule(3);
|
||||||
|
rule3.condition->url_filter = "some_methods";
|
||||||
|
rule3.condition->request_methods = {"get", "put"};
|
||||||
|
rules.push_back(rule3);
|
||||||
|
|
||||||
|
TestRule rule4 = CreateGenericRule(4);
|
||||||
|
rule4.condition->url_filter = "all_methods_excluded";
|
||||||
|
rule4.condition->excluded_request_methods = {
|
||||||
|
"delete", "get", "head", "options", "patch", "post", "put"};
|
||||||
|
rules.push_back(rule4);
|
||||||
|
|
||||||
|
TestRule rule5 = CreateGenericRule(5);
|
||||||
|
rule5.condition->url_filter = "some_methods_excluded";
|
||||||
|
rule5.condition->excluded_request_methods = {"get", "put"};
|
||||||
|
rules.push_back(rule5);
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules(rules));
|
||||||
|
|
||||||
|
// Start a web socket test server.
|
||||||
|
net::SpawnedTestServer websocket_test_server(
|
||||||
|
net::SpawnedTestServer::TYPE_WS, net::GetWebSocketTestDataDirectory());
|
||||||
|
ASSERT_TRUE(websocket_test_server.Start());
|
||||||
|
std::string websocket_url =
|
||||||
|
websocket_test_server.GetURL("echo-with-no-extension").spec();
|
||||||
|
|
||||||
|
const char kOpenWebSocketsScript[] = R"(
|
||||||
|
{
|
||||||
|
const websocketUrl = "%s";
|
||||||
|
const testCases = ["default", "all_methods", "some_methods",
|
||||||
|
"all_methods_excluded", "some_methods_excluded"];
|
||||||
|
|
||||||
|
let blockedTestCases = [];
|
||||||
|
|
||||||
|
Promise.allSettled(
|
||||||
|
testCases.map(testCase =>
|
||||||
|
new Promise(resolve =>
|
||||||
|
{
|
||||||
|
let websocket = new WebSocket(websocketUrl + "?" + testCase);
|
||||||
|
websocket.addEventListener("open", event =>
|
||||||
|
{
|
||||||
|
websocket.close();
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
websocket.addEventListener("error", event =>
|
||||||
|
{
|
||||||
|
blockedTestCases.push(testCase);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
)
|
||||||
|
).then(() =>
|
||||||
|
{
|
||||||
|
window.domAutomationController.send(blockedTestCases.sort().join());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
content::RenderFrameHost* main_frame = GetMainFrame();
|
||||||
|
|
||||||
|
std::string actual_blocked;
|
||||||
|
EXPECT_TRUE(content::ExecuteScriptAndExtractString(
|
||||||
|
main_frame,
|
||||||
|
base::StringPrintf(kOpenWebSocketsScript, websocket_url.c_str()),
|
||||||
|
&actual_blocked));
|
||||||
|
EXPECT_EQ("all_methods_excluded,default,some_methods_excluded",
|
||||||
|
actual_blocked);
|
||||||
|
}
|
||||||
|
|
||||||
// Tests that FLEDGE requests can be blocked by the declarativeNetRequest API,
|
// Tests that FLEDGE requests can be blocked by the declarativeNetRequest API,
|
||||||
// and that if they try to redirect requests, the request is blocked, instead of
|
// and that if they try to redirect requests, the request is blocked, instead of
|
||||||
// being redirected.
|
// being redirected.
|
||||||
|
@@ -54,12 +54,12 @@ VerifyStatus GetVerifyStatus(const uint8_t* buffer,
|
|||||||
|
|
||||||
// RulesetIndexer --------------------------------------------------------------
|
// RulesetIndexer --------------------------------------------------------------
|
||||||
|
|
||||||
const int RulesetIndexer::kIndexedFormatVersion = 30;
|
const int RulesetIndexer::kIndexedFormatVersion = 31;
|
||||||
|
|
||||||
// This static assert is meant to catch cases where
|
// This static assert is meant to catch cases where
|
||||||
// url_pattern_index::kUrlPatternIndexFormatVersion is incremented without
|
// url_pattern_index::kUrlPatternIndexFormatVersion is incremented without
|
||||||
// updating RulesetIndexer::kIndexedFormatVersion.
|
// updating RulesetIndexer::kIndexedFormatVersion.
|
||||||
static_assert(url_pattern_index::kUrlPatternIndexFormatVersion == 9,
|
static_assert(url_pattern_index::kUrlPatternIndexFormatVersion == 10,
|
||||||
"kUrlPatternIndexFormatVersion has changed, make sure you've "
|
"kUrlPatternIndexFormatVersion has changed, make sure you've "
|
||||||
"also updated RulesetIndexer::kIndexedFormatVersion above.");
|
"also updated RulesetIndexer::kIndexedFormatVersion above.");
|
||||||
|
|
||||||
|
@@ -70,6 +70,7 @@ enum RequestMethod : ubyte (bit_flags) {
|
|||||||
PATCH,
|
PATCH,
|
||||||
POST,
|
POST,
|
||||||
PUT,
|
PUT,
|
||||||
|
NON_HTTP
|
||||||
// Note: Update the default value for `request_methods` field in UrlRule, on
|
// Note: Update the default value for `request_methods` field in UrlRule, on
|
||||||
// adding/removing values from this enum.
|
// adding/removing values from this enum.
|
||||||
}
|
}
|
||||||
@@ -87,7 +88,7 @@ table UrlRule {
|
|||||||
element_types : ushort = 8191;
|
element_types : ushort = 8191;
|
||||||
|
|
||||||
// A bitmask of RequestMethod. Equals RequestMethod_ANY by default.
|
// A bitmask of RequestMethod. Equals RequestMethod_ANY by default.
|
||||||
request_methods : ushort = 127;
|
request_methods : ushort = 255;
|
||||||
|
|
||||||
// A bitmask of ActivationType. Disables all activation types by default.
|
// A bitmask of ActivationType. Disables all activation types by default.
|
||||||
activation_types : ubyte = 0;
|
activation_types : ubyte = 0;
|
||||||
|
@@ -85,7 +85,7 @@ int CompareDomains(base::StringPiece lhs_domain, base::StringPiece rhs_domain);
|
|||||||
// Increase this value when introducing an incompatible change to the
|
// Increase this value when introducing an incompatible change to the
|
||||||
// UrlPatternIndex schema (flat/url_pattern_index.fbs). url_pattern_index
|
// UrlPatternIndex schema (flat/url_pattern_index.fbs). url_pattern_index
|
||||||
// clients can use this as a signal to rebuild rulesets.
|
// clients can use this as a signal to rebuild rulesets.
|
||||||
constexpr int kUrlPatternIndexFormatVersion = 9;
|
constexpr int kUrlPatternIndexFormatVersion = 10;
|
||||||
|
|
||||||
// The class used to construct an index over the URL patterns of a set of URL
|
// The class used to construct an index over the URL patterns of a set of URL
|
||||||
// rules. The rules themselves need to be converted to FlatBuffers format by the
|
// rules. The rules themselves need to be converted to FlatBuffers format by the
|
||||||
|
@@ -153,7 +153,7 @@ TEST_F(IndexedRulesetFormatVersionTest, CheckVersionUpdated) {
|
|||||||
EXPECT_EQ(StripCommentsAndWhitespace(kFlatbufferSchemaExpected),
|
EXPECT_EQ(StripCommentsAndWhitespace(kFlatbufferSchemaExpected),
|
||||||
StripCommentsAndWhitespace(flatbuffer_schema))
|
StripCommentsAndWhitespace(flatbuffer_schema))
|
||||||
<< "Schema change detected; update this test and the schema version.";
|
<< "Schema change detected; update this test and the schema version.";
|
||||||
EXPECT_EQ(21, GetIndexedRulesetFormatVersionForTesting())
|
EXPECT_EQ(22, GetIndexedRulesetFormatVersionForTesting())
|
||||||
<< "Update this test if you update the schema version.";
|
<< "Update this test if you update the schema version.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -65,8 +65,12 @@ flat_rule::ElementType GetElementType(WebRequestResourceType web_request_type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Maps an HTTP request method string to flat_rule::RequestMethod.
|
// Maps an HTTP request method string to flat_rule::RequestMethod.
|
||||||
// TODO(kzar): Return `flat_rule::RequestMethod_NONE` for non-HTTP requests.
|
// Returns `flat::RequestMethod_NON_HTTP` for non-HTTP(s) requests.
|
||||||
flat_rule::RequestMethod GetRequestMethod(const std::string& method) {
|
flat_rule::RequestMethod GetRequestMethod(bool http_or_https,
|
||||||
|
const std::string& method) {
|
||||||
|
if (!http_or_https)
|
||||||
|
return flat_rule::RequestMethod_NON_HTTP;
|
||||||
|
|
||||||
using net::HttpRequestHeaders;
|
using net::HttpRequestHeaders;
|
||||||
static const base::NoDestructor<
|
static const base::NoDestructor<
|
||||||
base::flat_map<base::StringPiece, flat_rule::RequestMethod>>
|
base::flat_map<base::StringPiece, flat_rule::RequestMethod>>
|
||||||
@@ -173,7 +177,7 @@ RequestParams::RequestParams(const WebRequestInfo& info)
|
|||||||
: url(&info.url),
|
: url(&info.url),
|
||||||
first_party_origin(info.initiator.value_or(url::Origin())),
|
first_party_origin(info.initiator.value_or(url::Origin())),
|
||||||
element_type(GetElementType(info.web_request_type)),
|
element_type(GetElementType(info.web_request_type)),
|
||||||
method(GetRequestMethod(info.method)),
|
method(GetRequestMethod(info.url.SchemeIsHTTPOrHTTPS(), info.method)),
|
||||||
parent_routing_id(info.parent_routing_id),
|
parent_routing_id(info.parent_routing_id),
|
||||||
embedder_conditions_matcher(base::BindRepeating(DoEmbedderConditionsMatch,
|
embedder_conditions_matcher(base::BindRepeating(DoEmbedderConditionsMatch,
|
||||||
info.frame_data.tab_id)) {
|
info.frame_data.tab_id)) {
|
||||||
|
@@ -43,12 +43,12 @@ namespace dnr_api = api::declarative_net_request;
|
|||||||
// url_pattern_index.fbs. Whenever an extension with an indexed ruleset format
|
// url_pattern_index.fbs. Whenever an extension with an indexed ruleset format
|
||||||
// version different from the one currently used by Chrome is loaded, the
|
// version different from the one currently used by Chrome is loaded, the
|
||||||
// extension ruleset will be reindexed.
|
// extension ruleset will be reindexed.
|
||||||
constexpr int kIndexedRulesetFormatVersion = 21;
|
constexpr int kIndexedRulesetFormatVersion = 22;
|
||||||
|
|
||||||
// This static assert is meant to catch cases where
|
// This static assert is meant to catch cases where
|
||||||
// url_pattern_index::kUrlPatternIndexFormatVersion is incremented without
|
// url_pattern_index::kUrlPatternIndexFormatVersion is incremented without
|
||||||
// updating kIndexedRulesetFormatVersion.
|
// updating kIndexedRulesetFormatVersion.
|
||||||
static_assert(url_pattern_index::kUrlPatternIndexFormatVersion == 9,
|
static_assert(url_pattern_index::kUrlPatternIndexFormatVersion == 10,
|
||||||
"kUrlPatternIndexFormatVersion has changed, make sure you've "
|
"kUrlPatternIndexFormatVersion has changed, make sure you've "
|
||||||
"also updated kIndexedRulesetFormatVersion above.");
|
"also updated kIndexedRulesetFormatVersion above.");
|
||||||
|
|
||||||
|
@@ -261,7 +261,10 @@ namespace declarativeNetRequest {
|
|||||||
|
|
||||||
// List of HTTP request methods which the rule can match. An empty list is
|
// List of HTTP request methods which the rule can match. An empty list is
|
||||||
// not allowed.
|
// not allowed.
|
||||||
// Note: Non HTTP requests are considered to have the "get" request method.
|
//
|
||||||
|
// Note: Specifying a <code>requestMethods</code> rule condition will also
|
||||||
|
// exclude non-HTTP(s) requests, whereas specifying
|
||||||
|
// <code>excludedRequestMethods</code> will not.
|
||||||
RequestMethod[]? requestMethods;
|
RequestMethod[]? requestMethods;
|
||||||
|
|
||||||
// List of request methods which the rule won't match. Only one of
|
// List of request methods which the rule won't match. Only one of
|
||||||
|
Reference in New Issue
Block a user