Firefox DNS Lookups with the browser.dns.resolve() API
This article provides an overview of how the
browser.dns.resolve() API functions within the Mozilla
Firefox web browser to empower privacy and security extensions. By
granting extensions the ability to perform direct Domain Name System
(DNS) lookups, this API allows developers to inspect IP addresses,
uncover disguised trackers, and verify encrypted DNS usage. We will
cover the mechanics of the API, the required permissions, and the
specific ways security tools use it to protect users from malicious
network activity before a web connection is fully established.
Understanding the browser.dns.resolve() API
In standard web environments, browser extensions are largely restricted from seeing the underlying network resolution process. They can see the URL a browser requests, but not the actual IP address or DNS records associated with that URL.
Firefox bridges this gap with the browser.dns.resolve()
API. To use it, an extension must first declare the "dns"
permission in its manifest.json file. Once granted, the
extension can pass a hostname into the function, which then queries the
browser's internal DNS service and returns a Promise.
When the Promise resolves, it provides an object containing:
addresses: An array of IPv4 and/or IPv6 addresses associated with the hostname.canonicalName: The canonical name (CNAME) for the queried host, if requested.isTRR: A boolean indicating whether the resolution was performed using a Trusted Recursive Resolver, such as DNS over HTTPS (DoH).
Customizing Lookups with Flags
The API accepts an optional array of flags as a second parameter to modify how the DNS lookup is performed. The most relevant flags for security extensions include:
canonical_name: Requests the canonical name of the host in addition to its IP addresses.bypass_cache: Forces the browser to perform a fresh DNS lookup rather than relying on the local DNS cache.disable_trr: Instructs the browser not to use the Trusted Recursive Resolver (DoH) for this specific query, falling back to the operating system's resolver.offline: Only checks the browser's internal DNS cache without sending any packets over the network.
How Privacy and Security Extensions Use the API
By integrating browser.dns.resolve() with other browser
APIs—most notably the webRequest API—extensions can
intercept network traffic, resolve the destination domain, and decide
whether to allow or block the connection based on the DNS data.
1. Defeating CNAME Cloaking
Trackers frequently bypass traditional ad-blockers using a technique
called CNAME cloaking. A website will create a first-party subdomain
(e.g., metrics.example.com) and use a DNS CNAME record to
point it to a third-party tracking server (e.g.,
tracker.adnetwork.com). Standard extensions only see the
safe-looking first-party URL.
By using browser.dns.resolve() with the
canonical_name flag, Firefox privacy extensions can unmask
the true destination of the subdomain. If the returned
canonicalName matches a known tracker list, the extension
blocks the request.
2. IP-Based Threat Intelligence
Malicious actors often register new domains rapidly to evade
domain-based blocklists, while hosting these domains on the same
underlying server infrastructure. Security extensions can resolve a
newly encountered domain to retrieve its addresses array.
If the resulting IP address belongs to a known malicious subnet, a
botnet command-and-control server, or a restricted geographical region,
the extension can terminate the connection before any data is
exchanged.
3. Preventing DNS Spoofing and Ensuring Encryption
Because the API returns the isTRR boolean, security
extensions can monitor whether a user's DNS queries are safely routed
through Firefox’s encrypted DNS over HTTPS (DoH) feature. If an
extension detects that sensitive domains are being resolved with
isTRR returning false, it can alert the user
that their DNS queries are being handled by the local network and may be
vulnerable to ISP snooping or local DNS spoofing.
4. Detecting Local Network Fingerprinting
Malicious scripts on public websites sometimes attempt to scan a
user's local network by making requests to public domains that resolve
to local, private IP addresses (such as 192.168.1.1 or
127.0.0.1), a technique known as DNS rebinding. Extensions
use browser.dns.resolve() to check if an external domain
resolves to a private IP address space. If it does, the extension blocks
the request, preventing the external website from interacting with the
user's local router or devices.
5. Respecting Browser Proxy Settings
Unlike external applications that use the operating system's network
stack, browser.dns.resolve() operates strictly within the
context of the Firefox browser. This means any lookups performed by the
extension automatically respect the user's configured Firefox proxy
settings and DoH configurations, preventing accidental DNS leaks that
could compromise user anonymity.