Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore: remove proxy config polling
Signed-off-by: kryptocodes <srivatsantb@gmail.com>
  • Loading branch information
kryptocodes committed Jan 28, 2026
commit 3e0954f87e854503f25e7d9808b4681d08d5c3ee
61 changes: 40 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,21 +150,41 @@ The headful image supports configuring an HTTP/SOCKS proxy for the browser using
- Geo-targeting specific locations
- Rotating IP addresses

### Usage

Configure the proxy when starting the container:
### Quick Start

1. **Start the container:**
```bash
cd images/chromium-headful
IMAGE=kernel-docker ENABLE_WEBRTC=true ./run-docker.sh
```

2. **Upload the proxy extension:**
```bash
# Create zip from the extension folder (files must be at root level, not in a subdirectory)
cd brightdata-proxy-extension && zip -r ../proxy-extension.zip . && cd ..

PROXY_ENABLED=true \
PROXY_HOST=brd.superproxy.io \
PROXY_PORT=22225 \
PROXY_USERNAME="brd-customer-XXXXX-zone-XXXXX" \
PROXY_PASSWORD="your-password" \
IMAGE=kernel-docker \
ENABLE_WEBRTC=true \
./run-docker.sh
# Upload via API
curl -X POST "http://localhost:444/chromium/upload-extensions-and-restart" \
-F "extensions.zip_file=@proxy-extension.zip;filename=ext.zip" \
-F "extensions.name=proxy-extension"
```

3. **Configure the proxy:**
```bash
curl -X PUT http://localhost:444/proxy/config \
-H "Content-Type: application/json" \
-d '{
"host": "brd.superproxy.io",
"port": 33335,
"username": "brd-customer-XXXXX-zone-XXXXX",
"password": "your-password",
"scheme": "http"
}'
```

4. **Restart Chromium to apply:**
```bash
docker exec <container-name> supervisorctl restart chromium
```

### Geo-targeting
Expand All @@ -179,23 +199,22 @@ Append the country code to the username for geo-targeting:
| Germany | `-country-de` |

Example:
```bash
PROXY_USERNAME="brd-customer-XXXXX-zone-XXXXX-country-in"
```json
"username": "brd-customer-XXXXX-zone-XXXXX-country-in"
```

### Runtime Configuration (API)

Update the proxy configuration without restarting the container:
### API Reference

```bash
# Set proxy configuration
curl -X PUT http://localhost:444/proxy/config \
-H "Content-Type: application/json" \
-d '{
"host": "brd.superproxy.io",
"port": 22225,
"port": 33335,
"username": "brd-customer-XXXXX-zone-XXXXX",
"password": "your-password"
"password": "your-password",
"scheme": "http"
}'

# Get current proxy configuration
Expand All @@ -206,10 +225,10 @@ curl -X DELETE http://localhost:444/proxy/config
```

### Notes
- The proxy extension automatically picks up configuration changes within 30 seconds
- Port `444` maps to the kernel-images API (internal port `10001`)
- After updating proxy config, restart Chromium for the extension to apply changes
- Supported schemes: `http`, `https`, `socks4`, `socks5`
- Whitelist the container's public IP in your proxy provider's dashboard (find it with `docker exec <container> curl -s https://api.ipify.org`)
- Run without `PROXY_ENABLED=true` to disable the proxy extension
- Default bypass list: `["localhost", "127.0.0.1"]`

## Replay Capture

Expand Down
11 changes: 1 addition & 10 deletions brightdata-proxy-extension/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,13 @@ chrome.webRequest.onAuthRequired.addListener(
["asyncBlocking"]
);
Comment on lines 93 to 121
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Chrome extension webRequest onAuthRequired details.isProxy challenger property API documentation

💡 Result:

In chrome.webRequest.onAuthRequired, the event details object includes:

  • details.challenger: an object describing the server (or proxy) that is requesting authentication:

  • details.isProxy (boolean): indicates whether the auth challenge is coming from a proxy:

    • true = proxy auth (Proxy-Authenticate, typically HTTP 407)
    • false = origin/server auth (WWW-Authenticate, typically HTTP 401) (developer.mozilla.org)

Notes:

  • onAuthRequired is only fired for HTTP and HTTPS/TLS proxies that require authentication (not SOCKS proxies). (developer.mozilla.org)
  • In Manifest V3, Chrome requires the webRequestAuthProvider permission to use onAuthRequired. (developer.chrome.com)

Citations:


🏁 Script executed:

# Check if there are any existing security checks in the codebase
rg -i "isProxy|challenger" brightdata-proxy-extension/

Repository: reclaimprotocol/popcorn-images

Length of output: 56


🏁 Script executed:

# Look for any comments or documentation about auth handling
rg -i "auth|credential" brightdata-proxy-extension/background.js -A 2 -B 2

Repository: reclaimprotocol/popcorn-images

Length of output: 575


🏁 Script executed:

rg "proxyConfig\s*=" brightdata-proxy-extension/background.js -B 3 -A 3

Repository: reclaimprotocol/popcorn-images

Length of output: 367


🏁 Script executed:

rg "proxyConfig" brightdata-proxy-extension/background.js -B 2 -A 2 | head -40

Repository: reclaimprotocol/popcorn-images

Length of output: 615


🏁 Script executed:

rg "proxyConfig\." brightdata-proxy-extension/background.js | sort | uniq

Repository: reclaimprotocol/popcorn-images

Length of output: 227


🏁 Script executed:

# Look for the config object structure or where it's used
rg "config\." brightdata-proxy-extension/background.js -B 2 -A 2 | head -50

Repository: reclaimprotocol/popcorn-images

Length of output: 646


Restrict auth handling to proxy challenges to prevent credential leakage.

onAuthRequired fires for both HTTP proxy auth challenges (HTTP 407, isProxy=true) and origin/server auth challenges (HTTP 401, isProxy=false). Without a guard on details.isProxy, proxy credentials are leaked to any website that requests authentication. Add a check for details.isProxy === true before responding with credentials, and optionally validate the challenger host matches the proxy host.

🔒 Suggested hardening
 chrome.webRequest.onAuthRequired.addListener(
   (details, callbackFn) => {
+    if (!details.isProxy) {
+      callbackFn({ cancel: false });
+      return;
+    }
+    if (proxyConfig?.host && details.challenger?.host && details.challenger.host !== proxyConfig.host) {
+      callbackFn({ cancel: false });
+      return;
+    }
     if (proxyConfig && proxyConfig.username && proxyConfig.password) {
       console.log("Auth required, providing credentials");
       callbackFn({
         authCredentials: {
           username: proxyConfig.username,
           password: proxyConfig.password
         }
       });
     } else {
       console.log("Auth required but no credentials available");
       callbackFn({ cancel: false });
     }
   },
   { urls: ["<all_urls>"] },
   ["asyncBlocking"]
 );
🤖 Prompt for AI Agents
In `@brightdata-proxy-extension/background.js` around lines 49 - 67, The
onAuthRequired handler (chrome.webRequest.onAuthRequired) currently returns
proxyConfig credentials for any auth challenge; restrict it so you only supply
credentials when details.isProxy === true and proxyConfig exists, e.g., check
details.isProxy before calling callbackFn with authCredentials, otherwise call
callbackFn({cancel:false}); optionally also validate the challenger host in
details.challenger or details.host against your configured proxy host to avoid
sending proxy credentials to origin/server challenges.


// Initialize and poll for config changes
// Initialize proxy configuration
async function init() {
const config = await fetchProxyConfig();
if (config) {
applyProxySettings(config);
}
}

// Poll for config changes every 30 seconds
setInterval(async () => {
const config = await fetchProxyConfig();
if (config && JSON.stringify(config) !== JSON.stringify(proxyConfig)) {
console.log("Proxy config changed, updating...");
applyProxySettings(config);
}
}, 30000);

init();
console.log("Bright Data Proxy Extension loaded (API-configured)");
4 changes: 2 additions & 2 deletions server/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1083,8 +1083,8 @@ paths:
put:
summary: Set the proxy configuration
description: |
Set the proxy configuration for the browser. The browser extension will poll this
endpoint to get the current configuration and apply it automatically.
Set the proxy configuration for the browser. The browser extension fetches this
configuration at startup and applies it automatically.
operationId: setProxyConfig
requestBody:
required: true
Expand Down