mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 1264117 - Limit length of hostnames to 253 characters r=nhnt11,necko-reviewers,dragana
Differential Revision: https://phabricator.services.mozilla.com/D105609
This commit is contained in:
parent
a570dfc9d1
commit
c33fe1fe47
@ -8555,6 +8555,14 @@
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
# When this pref is true we enforce a 253 character limit on domains we try to
|
||||
# resolve. See bug 1264117. If it doesn't cause any web-compat issues we can
|
||||
# remove it in a few releases
|
||||
- name: network.dns.limit_253_chars
|
||||
type: RelaxedAtomicBool
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# The proxy type. See nsIProtocolProxyService.idl
|
||||
# PROXYCONFIG_DIRECT = 0
|
||||
# PROXYCONFIG_MANUAL = 1
|
||||
|
@ -864,6 +864,12 @@ void net_ParseRequestContentType(const nsACString& aHeaderStr,
|
||||
}
|
||||
|
||||
bool net_IsValidHostName(const nsACString& host) {
|
||||
// A DNS name is limited to 255 bytes on the wire.
|
||||
// In practice this means the host name is limited to 253 ascii characters.
|
||||
if (StaticPrefs::network_dns_limit_253_chars() && host.Length() > 253) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* end = host.EndReading();
|
||||
// Use explicit whitelists to select which characters we are
|
||||
// willing to send to lower-level DNS logic. This is more
|
||||
|
17
netwerk/test/unit/test_channel_long_domain.js
Normal file
17
netwerk/test/unit/test_channel_long_domain.js
Normal file
@ -0,0 +1,17 @@
|
||||
// Tests that domains longer than 253 characters fail to load when pref is true
|
||||
|
||||
add_task(async function test_long_domain_fails() {
|
||||
Services.prefs.setBoolPref("network.dns.limit_253_chars", true);
|
||||
let domain = "http://" + "a".repeat(254);
|
||||
|
||||
let req = await new Promise(resolve => {
|
||||
let chan = NetUtil.newChannel({
|
||||
uri: domain,
|
||||
loadUsingSystemPrincipal: true,
|
||||
});
|
||||
chan.asyncOpen(new ChannelListener(resolve, null, CL_EXPECT_FAILURE));
|
||||
});
|
||||
Assert.equal(req.status, Cr.NS_ERROR_UNKNOWN_HOST, "Request should fail");
|
||||
|
||||
Services.prefs.clearUserPref("network.dns.limit_253_chars");
|
||||
});
|
@ -9,6 +9,10 @@ const threadManager = Cc["@mozilla.org/thread-manager;1"].getService(
|
||||
);
|
||||
const mainThread = threadManager.currentThread;
|
||||
|
||||
const overrideService = Cc[
|
||||
"@mozilla.org/network/native-dns-override;1"
|
||||
].getService(Ci.nsINativeDNSResolverOverride);
|
||||
|
||||
class Listener {
|
||||
constructor() {
|
||||
this.promise = new Promise(resolve => {
|
||||
@ -66,3 +70,82 @@ add_task(async function test_idn_cname() {
|
||||
inRecord.QueryInterface(Ci.nsIDNSAddrRecord);
|
||||
Assert.equal(inRecord.canonicalName, ACE_IDN, "IDN is returned as punycode");
|
||||
});
|
||||
|
||||
add_task(
|
||||
{
|
||||
skip_if: () =>
|
||||
Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
|
||||
.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT,
|
||||
},
|
||||
async function test_long_domain() {
|
||||
let listener = new Listener();
|
||||
let domain = "a".repeat(253);
|
||||
overrideService.addIPOverride(domain, "1.2.3.4");
|
||||
dns.asyncResolve(
|
||||
domain,
|
||||
Ci.nsIDNSService.RESOLVE_TYPE_DEFAULT,
|
||||
Ci.nsIDNSService.RESOLVE_CANONICAL_NAME,
|
||||
null, // resolverInfo
|
||||
listener,
|
||||
mainThread,
|
||||
defaultOriginAttributes
|
||||
);
|
||||
let [, , inStatus] = await listener;
|
||||
Assert.equal(inStatus, Cr.NS_OK);
|
||||
|
||||
listener = new Listener();
|
||||
domain = "a".repeat(254);
|
||||
overrideService.addIPOverride(domain, "1.2.3.4");
|
||||
|
||||
Services.prefs.setBoolPref("network.dns.limit_253_chars", true);
|
||||
|
||||
if (mozinfo.socketprocess_networking) {
|
||||
// When using the socket process, the call fails asynchronously.
|
||||
dns.asyncResolve(
|
||||
domain,
|
||||
Ci.nsIDNSService.RESOLVE_TYPE_DEFAULT,
|
||||
Ci.nsIDNSService.RESOLVE_CANONICAL_NAME,
|
||||
null, // resolverInfo
|
||||
listener,
|
||||
mainThread,
|
||||
defaultOriginAttributes
|
||||
);
|
||||
let [, , inStatus] = await listener;
|
||||
Assert.equal(inStatus, Cr.NS_ERROR_UNKNOWN_HOST);
|
||||
} else {
|
||||
Assert.throws(
|
||||
() => {
|
||||
dns.asyncResolve(
|
||||
domain,
|
||||
Ci.nsIDNSService.RESOLVE_TYPE_DEFAULT,
|
||||
Ci.nsIDNSService.RESOLVE_CANONICAL_NAME,
|
||||
null, // resolverInfo
|
||||
listener,
|
||||
mainThread,
|
||||
defaultOriginAttributes
|
||||
);
|
||||
},
|
||||
/NS_ERROR_UNKNOWN_HOST/,
|
||||
"Should throw for large domains"
|
||||
);
|
||||
}
|
||||
|
||||
listener = new Listener();
|
||||
domain = "a".repeat(254);
|
||||
Services.prefs.setBoolPref("network.dns.limit_253_chars", false);
|
||||
dns.asyncResolve(
|
||||
domain,
|
||||
Ci.nsIDNSService.RESOLVE_TYPE_DEFAULT,
|
||||
Ci.nsIDNSService.RESOLVE_CANONICAL_NAME,
|
||||
null, // resolverInfo
|
||||
listener,
|
||||
mainThread,
|
||||
defaultOriginAttributes
|
||||
);
|
||||
[, , inStatus] = await listener;
|
||||
Assert.equal(inStatus, Cr.NS_OK);
|
||||
|
||||
Services.prefs.clearUserPref("network.dns.limit_253_chars");
|
||||
overrideService.clearOverrides();
|
||||
}
|
||||
);
|
||||
|
@ -181,6 +181,7 @@ skip-if = bits != 32
|
||||
[test_cache_jar.js]
|
||||
[test_cache-entry-id.js]
|
||||
[test_channel_close.js]
|
||||
[test_channel_long_domain.js]
|
||||
[test_compareURIs.js]
|
||||
[test_compressappend.js]
|
||||
[test_content_encoding_gzip.js]
|
||||
|
Loading…
Reference in New Issue
Block a user