问题的本质:prompt 约束不等于技术约束
前段时间在调一个用 AgentCore Browser 做数据采集的 Agent,跑着跑着发现它自己跳到了 Stack Overflow,还顺着链接访问了好几个外部站点。
这让我重新思考了一个问题:AI Agent 浏览网页的安全风险,远比我们想象的大。
- Agent 可能导航到未授权的域名
- 浏览器密码管理器可能存下敏感凭证
- 自动填充功能可能泄露之前的表单数据
- 不受控的文件下载可能引入恶意内容
很多人第一反应是"在 prompt 里写清楚限制"。但 prompt 约束根本不等于技术约束。Agent 的推理是概率性的,你在 prompt 里写"不要访问社交媒体",它可能因为搜索结果里一个链接跳转就过去了。
更关键的是,密码管理器、自动填充、文件下载这些浏览器内置功能——prompt 根本管不到这一层。
Chrome 企业策略:一个已经验证过的方案
亚马逊云科技的 Amazon Bedrock AgentCore Browser 现在支持 Chrome enterprise policies。本质上是把企业 IT 管理员工浏览器的那套成熟机制,用来管 AI Agent 的浏览行为。
Chrome 企业策略不是什么新东西,全球无数企业用它管理员工浏览器,已经跑了很多年。现在用来管 Agent,天然契合。
支持 450+ 项浏览器设置,覆盖面很广:
- URL 过滤:白名单/黑名单,精确控制 Agent 能去哪
- 下载限制:直接禁止文件下载
- 密码管理器:关掉,不让浏览器存任何密码
- 自动填充:地址信息、信用卡信息统统禁止
- 书签栏:隐藏,减少干扰
- 开发者工具:按需开关(这个有坑,后面细说)
两层策略机制
AgentCore Browser 的策略分两层,这个设计值得展开说说。
Managed 策略(浏览器级别,不可覆盖)
- 创建 Browser 实例时通过控制面 API 配置
- 策略 JSON 文件存在 Amazon S3 里
- 对该 Browser 实例创建的所有 Session 强制生效
- Session 级别无法覆盖——这是硬约束
- 映射到 Chrome 的
/etc/chromium/policies/managed/目录
Recommended 策略(Session 级别,可灵活调整)
- 启动 Browser Session 时通过数据面 API 配置
- 相当于 Chrome 的"用户偏好"级别
- 映射到
/etc/chromium/policies/recommended/目录 - 如果和 Managed 策略冲突,Managed 优先
这个分层的意义在于职责分离:安全团队管 Managed 策略(锁死安全底线),开发团队管 Recommended 策略(灵活调整业务需求)。两边互不干扰。
举个例子:安全团队通过 Managed 策略设定"只能访问公司内网 + AWS 文档",开发团队可以通过 Recommended 策略设置默认首页、书签等不影响安全的偏好。
实战:限制 Agent 只能访问 AWS 文档
Step 1:定义策略 JSON
{"URLBlocklist": ["*"],"URLAllowlist": ["docs.aws.amazon.com",".aws.amazon.com",".amazonaws.com"],"PasswordManagerEnabled": false,"DownloadRestrictions": 3,"DeveloperToolsAvailability": 0,"BookmarkBarEnabled": false,"AutofillAddressEnabled": false,"AutofillCreditCardEnabled": false
}
策略逻辑:先用 URLBlocklist: ["*"] 一刀切拦住所有 URL,再通过 URLAllowlist 打开白名单。这是"默认拒绝"的安全策略思路。
各字段说明:
| 策略项 | 值 | 作用 |
|---|---|---|
| URLBlocklist | ["*"] |
默认屏蔽所有 URL |
| URLAllowlist | AWS 域名列表 | 只放行 AWS 相关域名 |
| PasswordManagerEnabled | false | 禁止存密码 |
| DownloadRestrictions | 3 | 禁止所有下载 |
| DeveloperToolsAvailability | 0 | 允许 DevTools(必须设 0,后面解释) |
| AutofillAddressEnabled | false | 禁止地址自动填充 |
| AutofillCreditCardEnabled | false | 禁止信用卡自动填充 |
Step 2:上传策略到 S3
aws s3 cp chrome-policy.json s3://your-bucket/policies/chrome-policy.json
Step 3:创建带策略的 Browser 实例
from bedrock_agentcore.tools import BrowserClientclient = BrowserClient(REGION)response = client.create_browser(name="docs_research_browser",execution_role_arn=EXECUTION_ROLE_ARN,network_configuration={"networkMode": "PUBLIC"},enterprise_policies=[{"location": {"s3": {"bucket": BUCKET_NAME,"prefix": POLICY_KEY,}},"type": "MANAGED",}],recording={"enabled": True,"s3Location": {"bucket": BUCKET_NAME,"prefix": "policy-demo",},},
)
enterprise_policies 指向 S3 里的策略 JSON 文件,type 设为 MANAGED 表示浏览器级强制策略。recording 开启 Session 录制——可以在控制台回放查看策略执行效果,排障时很有用。
创建完后轮询 get_browser() 接口,等状态从 CREATING 变成 READY。
Step 4:启动 Session 并验证
session = client.start_browser_session(browser_id=browser_id)browser = await playwright.chromium.connect_over_cdp(session["cdp_url"])
context = browser.contexts[0]
page = await context.new_page()# 测试白名单内的 AWS 文档
await page.goto("https://docs.aws.amazon.com", wait_until="domcontentloaded")
title = await page.title()
print(f"✅ 白名单内页面: {title}")# 测试白名单外的站点
await page.goto("https://www.example.com", wait_until="domcontentloaded")
print("❌ 白名单外页面被 Chrome 策略拦截")
白名单内正常加载,白名单外直接拦截。这个限制发生在浏览器层面,跟 Agent 的推理逻辑完全无关——不管 Agent 怎么想去某个网站,浏览器就是不让它去。
注意用 wait_until="domcontentloaded" 而不是默认的 load。AWS 文档页面有大量后台分析脚本持续发网络请求,用 load 事件可能永远等不到。
自定义根 CA 证书
很多企业内网服务用自签证书。Agent 浏览器默认连这些 HTTPS 服务会报证书错误。
千万别想着"关掉证书验证"——那等于让浏览器接受任何证书,包括中间人攻击的伪造证书。
正确做法:
- 把组织的根 CA 证书存到 AWS Secrets Manager
- 创建 Browser 时引用 Secret 的 ARN
- 服务自动将证书导入浏览器信任存储
这样 Agent 访问内网服务、走 SSL 代理都能正常工作,安全性不打折。
踩坑记录
坑一:DevTools 策略设错导致静默失败
这个坑我踩了半小时才找到原因。
一开始把 DeveloperToolsAvailability 设成了 2(禁用)。Playwright 连接成功了,日志没报错。但所有页面操作命令全部超时。
根因:AgentCore Browser 底层用 Chrome DevTools Protocol(CDP)做自动化。WebSocket 握手是在代理层完成的,跟 Chrome 内部的 DevTools 开关无关。所以连接"成功"了,但 Chrome 在 CDP 层面拒绝了后续的所有命令。
DeveloperToolsAvailability 必须设为 0。 这是 AgentCore Browser 正常工作的前提。
坑二:URL 过滤格式的细微差异
Chrome 的 URL 过滤有自己的语法规则,跟常见的 glob 模式不一样:
docs.aws.amazon.com→ 精确匹配这个域名.aws.amazon.com(前面带点)→ 匹配所有子域名
我一开始写的是 aws.amazon.com(没加前导点),结果只有 aws.amazon.com 本身通过,docs.aws.amazon.com、console.aws.amazon.com 这些子域名全被拦了。一个小点的差距,效果完全不同。
坑三:page.load 事件超时
AWS 文档页面有大量后台分析脚本持续发网络请求。Playwright 默认等 load 事件(所有资源加载完),这些后台请求让它永远等不到加载完成。换成 domcontentloaded 就好了。
这个问题不只是 AWS 文档会遇到。现代网页普遍有各种追踪脚本和懒加载资源,Agent 做网页自动化时,建议统一用 domcontentloaded 作为等待条件。
完整数据流
- 本地写策略 JSON → 上传 S3
- 根 CA 证书(如果需要)→ 存 Secrets Manager
CreateBrowserAPI → 控制面从 S3 拉策略、从 Secrets Manager 拉证书StartBrowserSessionAPI → 控制面把配置传给数据面- 数据面部署策略和证书到隔离的浏览器环境
- Chrome 启动时读取策略,全 Session 生命周期内强制执行
策略跟 Browser 实例绑定,不跟代码绑定。换了 Agent 框架、换了开发团队,安全策略不变。这个设计很重要——安全策略不应该依赖于应用代码。
适用场景
- 数据采集 Agent:限制只能访问指定数据源站点
- 文档研究 Agent:锁定在官方文档域名范围内
- 内部系统操作 Agent:只能访问企业内网 + 自定义根 CA
- 合规审计 Agent:确保不接触敏感外部网站、不下载文件
我的判断
做 Agent 浏览器安全,核心思路就两条:
- 安全约束下沉到基础设施层。不依赖 prompt,不依赖 Agent 的推理能力。浏览器层面锁死,Agent 想绕也绕不过去。
- 默认拒绝,按需放行。先
URLBlocklist: ["*"]全部拦住,再逐个开白名单。比列黑名单安全得多——你不可能列完所有危险域名,但可以列完所有需要访问的域名。
Chrome 企业策略是个成熟的方案,不是为 Agent 现造的轮子。文档齐全、社区经验丰富、边界情况已经被大量企业踩过了。拿来管 Agent,可靠性有保障。
如果你也在做 Agent 浏览器安全相关的工作,建议从 URL 白名单 + 禁用密码管理器 + 禁用下载这三条开始,覆盖面已经很广了。
相关资源
- Amazon Bedrock AgentCore Browser 文档:https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/browser-tool.html
- Chrome 企业策略配置指南:https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/browser-enterprise-policies.html
- 自定义根 CA 证书文档:https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/browser-root-ca-certificates.html
