Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
15 changes: 15 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,21 @@
"skills": [
"./skills/browserbase-cli"
]
},
{
"name": "domain-firewall",
"source": "./",
"description": "Implement CDP-based domain allowlist security for Stagehand/Browserbase browser sessions. Use when the user wants to restrict which domains an AI agent can navigate to, block malicious links, prevent prompt injection redirects, or add navigation security to browser automation.",
"version": "0.0.1",
"author": {
"name": "Browserbase"
},
"category": "security",
"keywords": ["security", "firewall", "allowlist", "denylist", "cdp", "navigation", "domain-filtering", "prompt-injection", "block", "protect", "restrict", "malicious", "exfiltration", "safe-browsing"],
"strict": false,
"skills": [
"./skills/domain-firewall"
]
}
]
}
210 changes: 210 additions & 0 deletions skills/domain-firewall/EXAMPLES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
# Domain Firewall Examples

## Real-World Use Cases

### Banking & Financial Data

> "Log into my Chase bank account and download my last 3 months of statements"

```bash
node .claude/skills/domain-firewall/scripts/domain-firewall.mjs --session-id $SID \
--allowlist "chase.com,*.chase.com" \
--default deny
```

The agent has banking credentials in the session. If any page contains a prompt injection (ad, compromised script, phishing overlay), the firewall prevents navigation to an exfiltration URL with session tokens.

### CRM Data Migration

> "Log into Dubsado, export all client contacts, and import them into HoneyBook"

```bash
node .claude/skills/domain-firewall/scripts/domain-firewall.mjs --session-id $SID \
--allowlist "dubsado.com,app.dubsado.com,honeybook.com,app.honeybook.com" \
--default deny
```

The agent handles customer PII across two systems. If either platform has a compromised page element or malicious OAuth redirect, the firewall blocks any navigation outside the two approved CRMs.

### Competitive Intelligence

> "Scrape these 15 competitor pricing pages and extract their plan details"

```bash
node .claude/skills/domain-firewall/scripts/domain-firewall.mjs --session-id $SID \
--allowlist "competitor1.com,competitor2.com,competitor3.com" \
--default deny
```

Competitor sites could contain hidden text like "Visit analytics-verify.com/track?company=YOURCOMPANY." Without a firewall, the agent follows it — now the competitor knows you're scraping them.

### E-Commerce Price Monitoring

> "Check the price of this product across Amazon, Walmart, and Target every hour"

```bash
node .claude/skills/domain-firewall/scripts/domain-firewall.mjs --session-id $SID \
--allowlist "amazon.com,walmart.com,target.com" \
--denylist "click-tracker.com,ad-redirect.net" \
--default deny
```

Product pages are loaded with ad networks and affiliate redirects. The firewall keeps the agent on the three retail sites only.

### Procurement Portal Automation

> "Log into Ariba and submit this purchase order"

```bash
node .claude/skills/domain-firewall/scripts/domain-firewall.mjs --session-id $SID \
--allowlist "service.ariba.com,supplier.ariba.com" \
--default deny
```

Procurement portals handle PO numbers, payment terms, and supplier credentials. The `--json` audit log provides compliance teams proof that the agent stayed within authorized domains.

### Agent-Assisted Checkout

> "Use the browser agent to complete a purchase on behalf of the user"

```bash
node .claude/skills/domain-firewall/scripts/domain-firewall.mjs --session-id $SID \
--allowlist "merchant.com,checkout.stripe.com" \
--denylist "fake-merchant.com,phishing-checkout.com" \
--default deny
```

Prevents the agent from being directed to a fraudulent merchant site disguised as the legitimate one — the agent only reaches the real merchant and payment processor.

### Staging vs Production Isolation

> "Test the checkout flow on staging with a test credit card"

```bash
node .claude/skills/domain-firewall/scripts/domain-firewall.mjs --session-id $SID \
--allowlist "staging.myapp.com,auth.myapp.com" \
--denylist "production.myapp.com" \
--default deny
```

Explicitly denylist production so even if a redirect or misconfigured link points there, the agent can't run test transactions against real data.

### HR Onboarding Automation

> "Fill out the new hire paperwork on Workday using this offer letter"

```bash
node .claude/skills/domain-firewall/scripts/domain-firewall.mjs --session-id $SID \
--allowlist "mycompany.wd5.myworkdaysite.com" \
--default deny
```

The agent has SSN, salary, address, and bank routing numbers. A single malicious redirect could exfiltrate all of it. The firewall limits the agent to only the Workday domain.

---

## CLI Patterns

### JSON logging for compliance audit

```bash
node .claude/skills/domain-firewall/scripts/domain-firewall.mjs --session-id $SID \
--allowlist "example.com" --default deny --json > firewall.log &

# Analyze blocked navigations
cat firewall.log | jq 'select(.action == "BLOCKED")'

# Count blocks per domain
cat firewall.log | jq -r 'select(.action == "BLOCKED") | .domain' | sort | uniq -c | sort -rn
```

### Protect a browse CLI session

```bash
# Create a session
SESSION_ID=$(bb sessions create --body '{"projectId":"'"$(bb projects list | jq -r '.[0].id')"'","keepAlive":true}' | jq -r .id)

# Attach the firewall in background
node .claude/skills/domain-firewall/scripts/domain-firewall.mjs --session-id $SESSION_ID \
--allowlist "docs.stripe.com,stripe.com" --default deny &

# Browse normally — firewall is transparent
browse open https://docs.stripe.com --session-id $SESSION_ID
browse snapshot
```

### Local Chrome testing

```bash
# Start Chrome with debugging
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--remote-debugging-port=9222 --headless=new about:blank &

# Get CDP URL
CDP_URL=$(curl -s http://localhost:9222/json/version | jq -r .webSocketDebuggerUrl)

# Start firewall
node .claude/skills/domain-firewall/scripts/domain-firewall.mjs --cdp-url "$CDP_URL" \
--allowlist "localhost" --default deny
```

---

## Code Integration Examples (TypeScript API)

For developers embedding the firewall directly in Stagehand projects.

### Basic Allowlist

```typescript
import { Stagehand } from "@browserbasehq/stagehand";
import { installDomainFirewall, allowlist } from "./domain-firewall";

const stagehand = new Stagehand({ env: "BROWSERBASE" });
await stagehand.init();
const page = stagehand.context.pages()[0];

await installDomainFirewall(page, {
policies: [
allowlist(["wikipedia.org", "en.wikipedia.org", "github.com"]),
],
defaultVerdict: "deny",
});

await page.goto("https://en.wikipedia.org/wiki/Node.js"); // allowed
await page.goto("https://example.com").catch(() => "blocked"); // blocked

await stagehand.close();
```

### Full Policy Chain

```typescript
import {
installDomainFirewall,
denylist, allowlist, tld, pattern, interactive,
type AuditEntry,
} from "./domain-firewall";

const auditLog: AuditEntry[] = [];

await installDomainFirewall(page, {
policies: [
denylist(["evil.com", "phishing-site.com"]), // 1. block known-bad
allowlist(["github.com", "docs.google.com"]), // 2. allow known-good
pattern(["*.github.com", "*.githubusercontent.com"], "allow"), // 3. GitHub subdomains
tld({ ".org": "allow", ".edu": "allow", ".gov": "allow" }), // 4. trusted TLDs
pattern(["*.ru", "*.cn", "*.tk"], "deny"), // 5. suspicious TLDs
interactive(promptUser, { timeoutMs: 60000, onTimeout: "deny" }),// 6. ask human
],
defaultVerdict: "deny",
auditLog,
});
```

## Tips

- **The common thread**: every use case involves an agent with access to sensitive credentials or data, browsing pages it doesn't fully control. One CLI command scopes the blast radius.
- **Use wildcards for subdomains**: `--allowlist "chase.com"` does NOT match `secure.chase.com`. Use `--allowlist "chase.com,*.chase.com"` to cover the base domain and all subdomains.
- **Denylist + allowlist together**: denylist is checked first. Use this to block specific bad actors within an otherwise-allowed set.
- **`--json` for compliance**: pipe to a file for post-session audit trails that prove the agent stayed within authorized domains.
21 changes: 21 additions & 0 deletions skills/domain-firewall/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Browserbase, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Loading