PlantUML 信息泄漏与合规:源代码↔图双向暴露的风险与缓解

puml.online

PlantUML 图同时含「源码」和「图」——双向暴露 = 双向泄漏。但很多人没意识到这是合规、安全、AI 训练的反向数据源——这一篇整理风险清单、缓解方案、合规策略。

「图」比「文字」更容易泄漏

比文字更危险的地方

写一个博客:「我们使用 192.168.1.10 作为 PostgreSQL 主库」。文字泄漏是「作者写错」才会发生。

但 PlantUML 图里:

1
2
3
4
5
6
7
8
9
10
package "生产环境" {
[Frontend] as fe
[PostgreSQL] as pg
[Redis] as rd
[Auth Service] as auth
}

fe --> pg : "jdbc:postgresql://10.0.5.20:5432/prod"
fe --> rd : "redis://10.0.5.21:6379"
auth --> pg

代码段里直接暴露了IP 10.0.5.20:5432、端口、redis port、auth 服务未脱敏的连接字符串

这种泄漏是「图代码」自身——不是「渲染失败」或「作者疏忽」。审 PR 的时候不会注意:「哦就一张图,能有啥?」

五类常见泄漏风险

1. 内部 hostname / IP

1
[Frontend] --> "internal-payment.svc.cluster.local:8080" as fep

泄漏了:

  • k8s namespace 的内部 DNS(svc.cluster.local
  • 端口
  • 服务拓扑

2. 凭据 / token

1
[CI/CD] --> "kubectl --token=eyJhbGciOiJSUzI1NiIs..."

直接粘贴 token 到图里;有人 git push → token 公开。

3. 真实路径 / URL

1
[Widget] --> "https://internal-admin.company.com/users"

泄漏了内网管理系统路径,攻击者会推断。

4. 服务依赖图 → 业务上下文

1
2
3
[PaymentService] --> [Stripe]
[PaymentService] --> [PayPal]
[OrderService] --> [Stripe]

业务流(支付平台列表)= 商业情报。竞争对手看到就知道你的集成栈。

5. 真实客户名 / 项目代号

1
2
[CustomerA-Backend] as cust_a
[CustomerA-Backend] --> [HuaweiCloud Payment API]

泄漏了客户名「CustomerA」、合作厂商。

自建合规清单

下面是一份给架构图作者的清单。每次画图过一遍:

  • 图中所有 hostname 用别名(db1redis-prodpayment-api)?
  • 图中所有 IP10.x.x.x 占位?
  • 凭据 / token / cookie 都在外部配置文件?不在图里?
  • 端口号只展示公开端口(80/443)?
  • 真实客户名 / 项目代号不出现?
  • 内部域名后缀.svc.cluster.local.internal)不出现?
  • 数据库 / 队列 / 缓存的版本号不出现?
  • 服务负责人 / 联系方式(email、Slack channel)不出现?
  • 任何**「凭据字串」**(password=api_key=secret=)?

不符合的——立即改。

5 套缓解方案

1. 别名替换(最朴素)

在 puml 源里全用别名

1
2
3
4
[FE] --> [BE]
[BE] --> [DB]
[BE] --> [Cache]
[BE] --> [PayAPI]

渲染后的 SVG 看不出 IP / port / hostname。

优点:源头干净,不泄漏任何东西。
缺点:图不直观(FE/BE 是什么?)。需要文档说明别名映射。

2. Render 后正则替换(兜底)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# scripts/sanitize-svg.py
import re, sys

def sanitize(svg):
# IP 替换
svg = re.sub(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', 'x.x.x.x', svg)
# 内部域名
svg = re.sub(r'\b\S+\.internal\b', '[internal]', svg)
svg = re.sub(r'\b\S+\.svc\.cluster\.local\b', '[svc]', svg)
# URL
svg = re.sub(r'https?://[^\s"<>]+', 'https://[redacted]', svg)
# 凭据
svg = re.sub(r'(password|api_key|secret|token)=[^\s"<>]+', r'\1=[redacted]', svg)
return svg

if __name__ == "__main__":
for f in sys.argv[1:]:
with open(f) as fh:
new = sanitize(fh.read())
with open(f, 'w') as fh:
fh.write(new)
1
2
plantuml -tsvg diagram.puml
python sanitize-svg.py rendered/*.svg

优点:事后兜底,puml 源可以保留全名。
缺点:正则难精准(IP 匹配会误伤 SVG 内部 attribute)。

3. SVG 嵌入前 INSPECT

CI pipeline 加一步:

1
2
3
4
5
6
7
8
9
- name: Sanity-check SVG
run: |
plantuml -tsvg -o rendered/ docs/diagrams/*.puml
for svg in rendered/*.svg; do
if grep -E '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' "$svg"; then
echo "❌ $svg 包含 IP!"
exit 1
fi
done

简单粗暴:任何 IP 出现 → build fail

4. 域名 / 路径替换

1
2
3
4
5
6
7
8
9
10
NAME_MAP = {
"10.0.5.20": "db1",
"10.0.5.21": "redis-prod",
"internal-payment.svc.cluster.local:8080": "payment",
}

def replace_names(text):
for k, v in NAME_MAP.items():
text = text.replace(k, v)
return text

可审计——替换映射表存 git + review。

5. 不放完整 puml 在公开仓库

最严格的方案:私有仓库的图 + 公开仓库的 sanitized 版本

1
2
internal-repo/diagrams/  → 完整版(脱敏)
docs.diagrams/ → 公开版(再次脱敏 + 别名)

外部分发版不暴露任何内部 hostname。

「植物uml.com vs 自部署」的安全区别

plantuml.com 的隐忧

https://www.plantuml.com/plantuml/svg/~1<encoded> 的问题是:

  • 服务端有访问日志——渲染过的 puml 源码会进 log
  • 日志保留时间不一定——一个被泄漏的 puml 可能 6 个月后「翻旧账」才用到
  • 跨境的传输——puml 源码经过境外 ISP / CDN

对于有 GDPR / SOC2 / HIPAA 合规要求的企业,plantuml.com 通常禁止使用

自部署 plantuml-server

最稳的方案:自建 plantuml-server。

1
2
3
4
5
docker run -d \
-p 8080:8080 \
--name plantuml-server \
-v plantuml-data:/var/lib/plantuml \
plantuml/plantuml-server:latest

好处

  • 不出内网
  • 完全可控日志(默认不记录)
  • 可加入企业 SSO

坏处

  • 需要维护
  • 性能调优需要工作(thread 数、内存)
  • 字体 / 软件更新要手动

TeaVM(客户端)

puml.online 的 TeaVM 编辑器模式:

  • 源码不离浏览器 → 不会有任何服务端日志
  • 不发到任何服务器 → 不进 CDN / ISP

唯一的安全边界:浏览器自身。如果浏览器是公司管控的设备 → 最安全的方案。

AI 训练数据的反向风险

这是 2026 年的新坑。

公开图 → LLM 训练语料

GitHub 上有 ~1500 万张 PlantUML 公开图(gitee/码云的也有但数据未公开)——这些图跟 README、文档一起被爬虫抓取。

潜在问题

  • 攻击者专门爬 PlantUML 图源(不是渲染后的 SVG,而是源码)——可以挖企业信息
  • LLM 用 PlantUUM 图源训练后,模型可能「学会」内网命名习惯

「攻击场景」示例

1
2
3
4
5
6
攻击者爬取 GitHub:
1. 找到 [CompanyX/product] 仓库
2. 提取所有 plantuml/diagram 源码
3. 训练一个 NER 模型
4. 模型学到 [Login Service] [Pay API] [Order Queue] 是 X 公司的内部命名
5. 推断出该公司技术栈

防御方案

  • 不放公开 PlantUML 源在 GitHub——放 SVG 渲染结果(不带源码)
  • <!-- @private --> 注释 + CI 检查禁止公开 !include
  • 图源只放私有仓库 + sanitized 的 SVG 同步公开
  • 一旦发现公开图就立即 git history 重写(git filter-repo + force push)

LLMs 训练你的图法律上是允许的吗?

需要查每个公司的「公开资料收集」政策。多数公司:

  • 员工在公开仓的提交视为公司资产(除非合同另说)
  • 公开 = 同意被爬取 = 用于训练

重要策略:明确写「*.puml 不允许公开」的公司规约(CLA)。

工具链安全 audit

如果你有 100+ PlantUML 文件,定期审计:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash
# scripts/audit-puml-leaks.sh
# Check for sensitive info in puml sources
echo "→ 扫描 IP"
grep -rE "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" docs/diagrams/ && {
echo "❌ 有 IP"
exit 1
}

echo "→ 扫描内部域名"
grep -rE "\.internal|\.svc\.cluster\.local|\.corp" docs/diagrams/ && {
echo "❌ 有内网域名"
exit 1
}

echo "→ 扫描凭据"
grep -riE "password=|api_key=|secret=|token=" docs/diagrams/ && {
echo "❌ 有凭据"
exit 1
}

echo "✓ 通过"

集成进 CI:每次 PR 自动跑。

公开 vs 私有双轨案例

我们 puml.online 的图发布策略:

内容 仓库 编码 渲染后
教程示例 public 匿名别名 + 简化 SVG
公司生产架构 内部 private 全名 + 真实 SVG (内部访问)
内部审计图 内部 private 全名 SVG (内部访问)

渲染流水线:

1
2
3
4
5
6
7
8
9
10
开发者改 puml

CI 校验语法

渲染 SVG(多个 alias 模式):
- 公开版本:别名替换 + 简化
- 内部版本:全名保留

公开版本 → gitee push
内部版本 → 内部 CDN

AI 时代的额外防御

1. 注入 anti-crawler 标记

1
' 这张图包含商业敏感信息,未经授权禁止爬取

文字注释对爬虫是噪音——训练 LLM 时会被忽略或加重「不利」信号。

2. 别名 hash

1
2
def hash_alias(hostname):
return hashlib.sha256(hostname.encode()).hexdigest()[:8]

db1.company.internal9f3b2c4d。LLM 训练时无法关联这些是真实 hostname。

3. 「错名」引流

故意在图里写错的服务名——攻击者收集到的图源真实但无业务价值。

落地检查表

每个季度自审一次:

  • 公司的 PlantUML 源代码是否在公开仓库?
  • GitHub README 嵌入的图是否包含内部信息?
  • 仓库 README 顶部是否有「企业级规约」声明图源不可公开?
  • PR template 是否要求画图者脱敏后再 PR?
  • CI 是否自动扫描 IP、域名、凭据字串?
  • 是否教过 team 成员「图比文字更易泄漏」?
  • 公开渲染结果(SVG)是否经过再次脱敏?
  • 跨境的 plantuml.com 是否禁用?

puml.online 自身的实践

我们:

  • 教程示例图用别名(AuthServiceOrderService、无 IP/端口)
  • 源代码公开 (教程角度)
  • 客户端渲染(TeaVM:源码不离浏览器)
  • CI 不放服务器——纯静态 + 客户端
  • 没有用植物uml.com 在线服务

小结

  • PlantUML 图比文字更容易泄漏——「双份暴露」是核心问题
  • 5 类风险:IP / 凭据 / URL / 业务上下文 / 真实客户名
  • 5 套方案:别名 / 替换 / 扫描 / 映射 / 不公开
  • 2026 年的新坑:AI 训练数据反向风险
  • 公共域 vs 自部署 vs TeaVM:安全性顺序 TeaVM > 自部署 > plantuml.com

下一步

  • 标题: PlantUML 信息泄漏与合规:源代码↔图双向暴露的风险与缓解
  • 作者: puml.online
  • 创建于 : 2026-07-30 12:45:00
  • 更新于 : 2026-08-14 21:34:29
  • 链接: https://puml.online/blog/plantuml-security-leak/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。