OpenClaw 安全更新:Web Fetch Provider 边界强化详解
OpenClaw 安全更新:Web Fetch Provider 边界强化详解
OpenClaw 在最新版本中加强了 Web Fetch Provider 的安全边界,通过强化 URL 解析和请求验证,有效防止 SSRF(服务器端请求伪造)等安全攻击。
本文将详细介绍这项安全更新的技术细节和配置方法。
目录
什么是 Web Fetch Provider
Web Fetch Provider 是 OpenClaw 中用于网页内容获取的核心组件。它负责:
- 发送 HTTP/HTTPS 请求
- 解析响应内容
- 处理重定向和超时
- 管理连接池
典型使用场景
在 Skill 中使用 Web Fetch
web_fetch:
url: "https://api.example.com/data"
method: GET
headers:
Authorization: "Bearer ${API_TOKEN}"
安全风险分析
SSRF(服务器端请求伪造)
攻击原理:
攻击者通过构造特殊 URL,让服务器向内部网络或敏感资源发起请求。
攻击示例:
恶意请求
url: "http://169.254.169.254/latest/meta-data/" # AWS 元数据服务
或
url: "http://localhost:6379/" # 本地 Redis 服务
或
url: "file:///etc/passwd" # 本地文件读取
URL 解析漏洞
问题场景:
- 不规范的 URL 格式被意外解析
- 特殊字符绕过安全检查
- Unicode 编码混淆
有问题的 URL
http://example.com@evil.com/ # @ 符号混淆
http://example.com%2F..%2Fetc/passwd # 编码绕过
边界强化措施
1. URL 解析加固
新的 URL 解析器采用更严格的 RFC 3986 标准:
// 严格的 URL 解析
class HardenedURLParser {
parse(url: string): ParsedURL {
// 1. 规范化编码
const normalized = this.normalizeEncoding(url);
// 2. 验证协议白名单
if (!this.isAllowedProtocol(normalized.protocol)) {
throw new SecurityError(Protocol ${normalized.protocol} not allowed);
}
// 3. 验证主机名格式
if (!this.isValidHostname(normalized.hostname)) {
throw new SecurityError(Invalid hostname: ${normalized.hostname});
}
// 4. 检查 IP 范围
if (this.isPrivateIP(normalized.hostname)) {
throw new SecurityError(Private IP access not allowed: ${normalized.hostname});
}
return normalized;
}
}
2. 请求边界控制
config.yaml
providers:
web_fetch:
security:
# 启用边界强化
hardened_boundaries: true
# 协议白名单
allowed_protocols:
- https
- http
# 禁止的主机模式
blocked_host_patterns:
- "localhost"
- "127...*"
- "10...*"
- "192.168.."
- "*.internal"
- "*.local"
# 禁止的端口
blocked_ports:
- 22 # SSH
- 23 # Telnet
- 25 # SMTP
- 53 # DNS
- 110 # POP3
- 143 # IMAP
- 3389 # RDP
- 6379 # Redis
- 3306 # MySQL
- 5432 # PostgreSQL
# 最大重定向次数
max_redirects: 3
# 验证 SSL 证书
verify_ssl: true
3. 响应边界控制
providers:
web_fetch:
response_limits:
# 最大响应大小 (10MB)
max_size: 10485760
# 允许的内容类型
allowed_content_types:
- "text/html"
- "text/plain"
- "application/json"
- "application/xml"
- "text/markdown"
# 禁止的内容模式
blocked_patterns:
- "" # 脚本标签(可选)
配置与使用
基础配置
config.yaml
providers:
web_fetch:
enabled: true
# 安全强化(推荐启用)
security:
hardened_boundaries: true
# 超时设置
timeout:
connect: 5000 # 连接超时 5秒
read: 30000 # 读取超时 30秒
# 重试策略
retry:
max_attempts: 3
backoff: exponential
在 Skill 中使用
// 安全的 Web Fetch 调用
export class SafeWebFetchSkill {
async fetchData(url: string) {
// OpenClaw 会自动应用安全边界
const response = await this.webFetch({
url,
method: 'GET',
headers: {
'User-Agent': 'OpenClaw/1.0'
}
});
return response.data;
}
}
自定义安全策略
为特定 provider 定制安全策略
providers:
web_fetch:
# 默认严格模式
security:
hardened_boundaries: true
# 特定场景宽松模式(谨慎使用)
profiles:
internal_api:
security:
hardened_boundaries: true
blocked_host_patterns:
# 允许访问内部 API
- "localhost"
- "127.0.0.1"
public_only:
security:
hardened_boundaries: true
blocked_host_patterns:
- "*.internal.company.com"
最佳实践
1. 输入验证
// 始终验证用户输入的 URL
function validateUserURL(input: string): string {
// 1. 基本格式检查
const urlPattern = /^https?:\/\/.+/;
if (!urlPattern.test(input)) {
throw new Error('URL must start with http:// or https://');
}
// 2. 长度限制
if (input.length > 2048) {
throw new Error('URL too long');
}
// 3. 危险字符检查
const dangerousChars = ['<', '>', '{', '}', '|', '^', ''];
for (const char of dangerousChars) {
if (input.includes(char)) {
throw new Error(URL contains dangerous character: ${char}`);
}
}
return input;
}
2. 使用 URL 白名单
对于已知安全的 API
providers:
web_fetch:
whitelist:
enabled: true
urls:
- "https://api.github.com/*"
- "https://api.openai.com/*"
- "https://docs.openclaw.ai/*"
3. 日志审计
providers:
web_fetch:
audit:
enabled: true
log_level: info
log_requests: true
log_responses: false # 避免记录敏感数据
4. 监控和告警
monitoring:
web_fetch:
alerts:
- name: "SSRF Attempt Detected"
condition: "security.blocked_request_count > 0"
action: "notify_admin"
- name: "High Error Rate"
condition: "error_rate > 0.1"
action: "throttle_requests"
测试安全边界
安全测试用例
// tests/security/web-fetch.test.ts
describe('Web Fetch Security Boundaries', () => {
it('should block private IP access', async () => {
await expect(
webFetch('http://192.168.1.1/')
).rejects.toThrow('Private IP access not allowed');
});
it('should block localhost access', async () => {
await expect(
webFetch('http://localhost:8080/')
).rejects.toThrow('Blocked host pattern: localhost');
});
it('should block file protocol', async () => {
await expect(
webFetch('file:///etc/passwd')
).rejects.toThrow('Protocol file not allowed');
});
it('should block suspicious URL encoding', async () => {
await expect(
webFetch('http://example.com%2F..%2Fadmin')
).rejects.toThrow('Invalid URL encoding');
});
});
总结
Web Fetch Provider 边界强化 为 OpenClaw 带来了更强的安全防护:
1. URL 解析加固 — 严格遵循 RFC 标准,防止编码绕过
2. 请求边界控制 — 协议、主机、端口多层次限制
3. 响应边界控制 — 大小、类型双重限制
4. 可观测性 — 完整的审计日志和监控告警
关键配置:
providers:
web_fetch:
security:
hardened_boundaries: true # 启用安全强化
常见问题
Q: 启用边界强化后,原有功能会受影响吗?
A: 正常的外部 API 调用不会受影响。只有尝试访问内部网络或敏感资源的请求会被阻止。
Q: 如何临时禁用某个安全限制?
A: 不建议禁用,但可以添加例外规则:
security:
hardened_boundaries: true
exceptions:
- host: "internal-api.company.com"
reason: "Internal API access required"
Q: 误拦截了合法请求怎么办?
A:
1. 检查审计日志确认拦截原因
2. 如果是白名单中的 API,更新白名单配置
3. 如果是配置错误,调整 blocked_host_patterns
Q: 支持自定义安全策略吗?
A: 支持,可以通过配置文件自定义协议、端口、主机模式等限制。
Q: 对性能有影响吗?
A: 影响极小。URL 解析和验证在微秒级完成。
Q: 如何查看被拦截的请求?
A:
查看安全审计日志
tail -f ~/.openclaw/logs/security-audit.log | grep "BLOCKED"
统计拦截情况
openclaw stats web-fetch --security
参考来源
—
相关阅读: