Block 17,410+ AI-tool domains at the browser level with zero client software. Deploy via WPAD, GPO, or MDM using our daily-updated domain feed.
Many organizations need to block AI tools but lack a forward proxy, SWG, or NGFW with URL filtering. PAC files fill that gap with zero infrastructure.
A JavaScript file the browser downloads and executes locally to decide whether each URL request connects directly or routes through a proxy.
Route AI-tool domains to a non-existent proxy or a block-page server. All other traffic connects directly. No appliance, agent, or DNS sinkhole needed.
PAC files run in every major browser on Windows, macOS, Linux, ChromeOS, and managed mobile platforms.
PAC files block browser-based access effectively but do not cover standalone desktop apps or CLI tools that bypass browser proxy settings. For most organizations, the primary risk is employees pasting data into web-based AI chatbots — and PAC files cover that immediately.
We publish 17,410+ AI-tool domains updated daily. Embed them directly into a PAC file or consume via API to generate PAC files dynamically.
Zero infrastructure required, under 1 KB compressed, supported by all major browsers, and centrally deployable via GPO — the fastest path from policy to enforcement.
Every PAC file contains a single JavaScript function: FindProxyForURL(url, host). The browser calls it for every request and routes traffic based on the return value.
| Return String | Behavior |
|---|---|
"DIRECT" | Connect without a proxy |
"PROXY host:port" | Route through an HTTP proxy |
"SOCKS host:port" | Route through a SOCKS proxy |
dnsDomainIs(host, domain)Returns true if the hostname ends with the specified domain suffix. Best for AI-tool blocking.
shExpMatch(host, pattern)Shell-expression matching with wildcard support for flexible pattern matching.
localHostOrDomainIs(host, hostdom)Matches exact hostnames or subdomains without substring false positives.
PROXY 127.0.0.1:9Routes to discard protocol. Functional but shows a confusing connection-refused error to users. With no server to record the request, there is also no logging.
PROXY block.internal:8080Lightweight HTTP server (nginx/IIS) returning a branded block page with policy explanation and an exception-request link.
// PAC file: Block AI tools, allow everything else // Save as proxy.pac or wpad.dat and host on an internal web server function FindProxyForURL(url, host) { // Normalize hostname to lowercase host = host.toLowerCase(); // --- AI Tool Domains to Block --- // Text & Language AI if (dnsDomainIs(host, "openai.com") || dnsDomainIs(host, "chat.openai.com") || dnsDomainIs(host, "chatgpt.com") || dnsDomainIs(host, "anthropic.com") || dnsDomainIs(host, "claude.ai") || dnsDomainIs(host, "gemini.google.com") || dnsDomainIs(host, "bard.google.com") || dnsDomainIs(host, "perplexity.ai") || dnsDomainIs(host, "you.com") || dnsDomainIs(host, "poe.com") || dnsDomainIs(host, "writesonic.com") || dnsDomainIs(host, "jasper.ai") || dnsDomainIs(host, "copy.ai")) { return "PROXY block.internal.corp:8080"; } // Code & Development AI if (dnsDomainIs(host, "github.com") && shExpMatch(url, "*copilot*")) { return "PROXY block.internal.corp:8080"; } if (dnsDomainIs(host, "copilot.github.com") || dnsDomainIs(host, "codeium.com") || dnsDomainIs(host, "cursor.sh") || dnsDomainIs(host, "tabnine.com") || dnsDomainIs(host, "replit.com")) { return "PROXY block.internal.corp:8080"; } // Image & Visual AI if (dnsDomainIs(host, "midjourney.com") || dnsDomainIs(host, "stability.ai") || dnsDomainIs(host, "leonardo.ai") || dnsDomainIs(host, "dall-e.com") || dnsDomainIs(host, "deepai.org")) { return "PROXY block.internal.corp:8080"; } // All other traffic: connect directly return "DIRECT"; }
PAC files execute in a sandboxed JavaScript environment inside the browser. The function is called for every URL request, including embedded resources. For large domain lists, use a sorted array with binary search or a hash-set lookup to keep resolution time O(log n) or O(1) instead of O(n).
PROXY 127.0.0.1:9 — functional but shows a confusing connection-refused error.Static PAC files with hardcoded domains become stale as new AI tools launch daily. Dynamic generation solves this with a server-side script that fetches current domains from our API — the browser re-fetches the PAC file on startup and at configurable intervals, ensuring a current blocklist without manual intervention.
Host this script on an internal web server and point your WPAD or GPO configuration to its URL. It caches the API response for one hour to avoid rate limits.
# Dynamic PAC file generator (PHP) # Host at: http://wpad.corp.example.com/wpad.dat # Fetches AI domains from the blocklist API, caches for 1 hour <?php header('Content-Type: application/x-ns-proxy-autoconfig'); header('Cache-Control: max-age=3600'); $cacheFile = '/tmp/ai-blocklist-cache.csv'; $cacheTTL = 3600; if (!file_exists($cacheFile) || time() - filemtime($cacheFile) > $cacheTTL) { $ctx = stream_context_create(['http' => [ 'header' => 'X-API-Key: YOUR_API_KEY' ]]); $response = file_get_contents( 'https://www.aitoolsblocklist.com/api/database/?action=download_database', false, $ctx ); file_put_contents($cacheFile, $response); } else { $response = file_get_contents($cacheFile); } // Extract the domain column from the CSV (domain,category,subcategory) $lines = array_slice(array_filter(explode("\n", trim($response))), 1); $domains = array_map(fn($l) => explode(',', $l)[0], $lines); // Build the dnsDomainIs() conditions $conditions = []; foreach ($domains as $d) { $d = trim(strtolower($d)); if ($d) $conditions[] = 'dnsDomainIs(h,"'.$d.'")'; } echo "function FindProxyForURL(url, host) {\n"; echo " var h = host.toLowerCase();\n"; echo " if (" . implode(" ||\n ", $conditions) . ") {\n"; echo " return \"PROXY block.internal.corp:8080\";\n"; echo " }\n"; echo " return \"DIRECT\";\n"; echo "}\n"; ?>
in operator for O(1) lookups.
application/x-ns-proxy-autoconfig. IE and legacy Edge silently ignore files served with incorrect types.
Add AddType application/x-ns-proxy-autoconfig .pac .dat to your configuration.
Add the type to the mime.types file or use default_type in the location block.
Add the MIME mapping in the site's properties for .pac and .dat extensions.
The lightest enforcement layer you can ship — measured against appliances, agents, and full proxy stacks.
WPAD lets browsers discover and download PAC files automatically with zero client-side configuration. It is enabled by default on Windows.
The browser queries DHCP for a PAC file URL. Works even when the client is not in a domain.
If DHCP fails, the browser performs a DNS lookup for wpad.<domain> and downloads /wpad.dat from that host.
Open DHCP Management Console → Scope Options → add option 252 with value http://wpad.corp.example.com/wpad.dat.
Define option wpad-url code 252 = text; then set option wpad-url "http://wpad.corp.example.com/wpad.dat"; in the subnet declaration.
Create an A record for wpad in your internal DNS zone pointing to the web server hosting your PAC file. The browser constructs http://wpad.<domain>/wpad.dat automatically — if the client's DNS suffix is corp.example.com, it tries http://wpad.corp.example.com/wpad.dat. Ensure the server responds with the correct MIME type.
# DNS configuration for WPAD (BIND zone file) # Add this A record to your internal DNS zone wpad IN A 10.0.1.50 # If using CNAME (less common but works in some environments): wpad IN CNAME internal-webserver.corp.example.com. # --- Web server configuration --- # Apache: Add MIME type for PAC files # /etc/apache2/sites-enabled/wpad.conf <VirtualHost *:80> ServerName wpad.corp.example.com DocumentRoot /var/www/wpad AddType application/x-ns-proxy-autoconfig .dat .pac <Directory /var/www/wpad> Options -Indexes AllowOverride None Require all granted </Directory> </VirtualHost> # Nginx: Add MIME type and serve wpad.dat # /etc/nginx/conf.d/wpad.conf server { listen 80; server_name wpad.corp.example.com; root /var/www/wpad; location = /wpad.dat { types { } default_type application/x-ns-proxy-autoconfig; } } # IIS: Add MIME mapping via PowerShell Add-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' ` -Filter "system.webServer/staticContent" ` -Name "." ` -Value @{ fileExtension = '.dat' mimeType = 'application/x-ns-proxy-autoconfig' }
The WPAD server is a critical dependency. Chrome and Edge cache the last-known PAC file and fall back to DIRECT if it's unavailable. Firefox retries periodically. Deploy behind a load balancer or use DNS round-robin for redundancy.
If an attacker registers the wpad DNS name or responds to DHCP option 252, they can serve a malicious PAC file. Mitigate by explicitly registering the hostname in DNS, blocking external WPAD queries at the firewall, and using DHCP snooping.
Chrome re-fetches the PAC file on network changes and periodically. Firefox respects the HTTP Cache-Control header. Set max-age=3600 on PAC file responses to ensure hourly updates without excessive polling.
Explicit PAC file assignment via GPO or MDM is more deterministic than WPAD. It guarantees application regardless of DHCP/DNS configuration and is easier to audit.
GPO sets the proxy auto-configuration URL in Windows Internet Settings. This applies to IE, legacy Edge, Chromium Edge, and Chrome (which reads system proxy settings by default).
Create or edit a GPO linked to the target organizational units.
Go to User Configuration > Preferences > Windows Settings > Registry.
Create a registry item with the PAC file URL. Optionally add Chrome-specific and Edge-specific policy keys.
# GPO Registry Settings for PAC File # Path: User Configuration > Preferences > Windows Settings > Registry # Enable automatic proxy configuration Key: HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings Value: AutoConfigURL Type: REG_SZ Data: http://wpad.corp.example.com/wpad.dat # Disable "Automatically detect settings" to prevent WPAD override Key: HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections Value: DefaultConnectionSettings # Byte 8 bit 4: 0 = disable auto-detect, 1 = enable # --- Chrome-specific policy (if not using system settings) --- # ADMX: Google Chrome > Proxy Settings Key: HKLM\Software\Policies\Google\Chrome Value: ProxyPacUrl Type: REG_SZ Data: http://wpad.corp.example.com/wpad.dat Key: HKLM\Software\Policies\Google\Chrome Value: ProxyMode Type: REG_SZ Data: pac_script # --- Edge Chromium-specific policy --- Key: HKLM\Software\Policies\Microsoft\Edge Value: ProxyPacUrl Type: REG_SZ Data: http://wpad.corp.example.com/wpad.dat Key: HKLM\Software\Policies\Microsoft\Edge Value: ProxyMode Type: REG_SZ Data: pac_script # --- PowerShell: Apply PAC URL to all users immediately --- $pac = "http://wpad.corp.example.com/wpad.dat" Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" ` -Name "AutoConfigURL" -Value $pac # Verify the setting was applied Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" ` -Name "AutoConfigURL"
Create a device configuration profile, search for "Proxy" in the Settings Catalog, and set the Auto Config URL with your PAC file URL. Applies to both Edge and system-level proxy settings.
Create a custom profile using an XML payload that sets ProxyAutoConfigURLString in the com.apple.SystemConfiguration domain. Alternatively, use a Jamf-managed network profile per Wi-Fi SSID.
On macOS, proxy auto-configuration is set per network interface. An MDM profile can enforce the PAC URL for specific Wi-Fi networks or all Ethernet connections.
Create a Configuration Profile → Network payload → set Proxy Type to Automatic with the Proxy Setup URL. Applies to Safari, Chrome, and all apps that respect macOS proxy settings.
Firefox on macOS uses its own proxy settings. Deploy a policies.json file to /Applications/Firefox.app/Contents/Resources/distribution/ or configure via autoconfig.js.
GPO is the most robust method for domain-joined machines. Set PAC URL via registry preferences (not deprecated IE Maintenance). For non-domain machines, use Intune or a PowerShell login script. Chrome and Edge both respect system proxy settings unless browser-specific policies override.
MDM configuration profiles enforce PAC URLs at the system level. Safari and Chrome respect the system setting. Firefox uses its own proxy stack and requires a separate policy — deploy a policies.json file to /Applications/Firefox.app/Contents/Resources/distribution/ with the WebProxy > AutoConfigURL key pointing to your PAC file.
Browsers handle PAC files differently in caching, failover, DNS resolution, and error handling. Understanding these differences is essential for reliable cross-browser deployment.
dnsResolve() may differ from other browsers.--proxy-pac-url flag or ProxyPacUrl enterprise policy.HTTPS proxy types in PAC return values.about:preferences > Network Settings or autoconfig.js.dnsResolve() to prevent timeouts.const, let, arrow functions, or template literals.var declarations and traditional function syntax.ProxyMode and ProxyPacUrl Edge enterprise policies.var instead of let/const, traditional function declarations, no arrow functions or template literalsdnsResolve() — introduces DNS latency on every request and behaves differently across browsersdnsDomainIs() and shExpMatch() — string comparison only, no DNS overheadArray.includes() or Array.indexOf(); use a for-loop insteadFindProxyForURL returns undefined, Chrome falls back to DIRECT but older browsers may block all trafficChaining thousands of dnsDomainIs() calls becomes unwieldy and slow. The PAC sandbox lacks Set and Map, but plain JavaScript objects enable efficient lookups.
[] operator for O(1) average-case lookup time.
// High-performance PAC file with hash-set domain lookup // Handles 40,000+ domains with O(1) lookup time var BLOCKED = { "openai.com": 1, "chatgpt.com": 1, "anthropic.com": 1, "claude.ai": 1, "gemini.google.com": 1, "midjourney.com": 1, "stability.ai": 1, "perplexity.ai": 1, "cursor.sh": 1, "copilot.github.com": 1, "codeium.com": 1, "writesonic.com": 1, "jasper.ai": 1, "copy.ai": 1, "replit.com": 1, "huggingface.co": 1, "leonardo.ai": 1, "poe.com": 1 // ... 40,000+ entries generated by API }; function FindProxyForURL(url, host) { var h = host.toLowerCase(); // Direct lookup if (BLOCKED[h]) { return "PROXY block.internal.corp:8080"; } // Walk up domain hierarchy for subdomain matching // e.g., "api.openai.com" matches "openai.com" var parts = h.split("."); for (var i = 1; i < parts.length - 1; i++) { var parent = parts.slice(i).join("."); if (BLOCKED[parent]) { return "PROXY block.internal.corp:8080"; } } return "DIRECT"; }
api.openai.com, the function walks up the hierarchy and matches openai.com. The loop stops before checking the TLD to avoid false positives.
Assign category codes instead of simple 1 values to enable per-category policies. Our API outputs domains with category tags, and the dynamic PAC generator can produce files that check category membership via bitmask or integer code.
PAC file enforcement happens in the browser, not on a network device. There is no centralized log of blocked requests by default — your monitoring strategy depends on your block response approach.
| Approach | Visibility | User Experience | Cost |
|---|---|---|---|
| Block-page proxy | Full audit trail — timestamp, client IP, hostname | Branded block page with policy explanation | Single nginx instance |
Loopback (127.0.0.1:9) |
No logging — no server to record the request | Confusing connection-refused error | Zero |
chrome://net-internals/#proxy — shows PAC URL, download status, and FindProxyForURL() results.about:networking#dns and browser console show proxy resolution results.text/html instead of application/x-ns-proxy-autoconfig — browser silently ignores the file.pacparser (open-source PAC evaluator) before deploying.ProxySettingsPerUser to 0 — requires admin rights to change.PAC files are a pragmatic, low-cost solution for AI-tool blocking, but they have inherent limitations. Understand these before relying on PAC files as your sole enforcement mechanism.
curl, AI-tool CLIs, and scripts bypass PAC file enforcementDownload the sample domain list to test your PAC file setup, or tell us about your environment and we will generate a ready-to-deploy PAC file customized for your infrastructure.
Tell us your proxy infrastructure, browser mix, and deployment method. We will generate a ready-to-deploy PAC file within 24 hours.
The full classified database behind every feed format we ship.
Read moreCatch non-browser apps at the resolver with the same domain data.
Read moreEndpoints, filters, and formats for dynamic PAC generation.
Read morePlain-text exports for firewalls, proxies, and custom tooling.
Read moreDiscover the unsanctioned AI tools already in use on your network.
Read moreStop sensitive data from leaving through AI chat prompts.
Read moreMap AI blocking to your regulatory and governance obligations.
Read moreSimple plans for the full feed, category subsets, and API access.
Read more