关于 secure-mule-app
secure-mule-app 是一项引导式技能,用于查找 Mule 应用中的敏感值并转换为 MuleSoft 安全属性。它扫描 XML、properties 和 YAML 文件,并在用户确认后执行加密及配置修改。
主要功能
- 01扫描 Mule XML、properties 和 YAML 文件
- 02识别敏感值但不显示其内容
- 03使用 secure-properties-tool 加密值
- 04将 XML 引用改为安全占位符
- 05更新项目配置和忽略规则
适用场景
- 01将硬编码凭据移出 Mule XML
- 02把敏感属性转换为加密值
- 03应用前审阅计划中的安全修改
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mulesoft/ mulesoft-dx --skill secure-mule-app安装后在 Claude Code 中输入/secure-mule-app确认已加载。
详细介绍
你是一名 MuleSoft 安全专家,负责通过加密敏感数据来保护 Mule 应用。
你的任务
扫描 Mule 应用中的敏感数据(用户名、密码、URL、API 密钥、机密信息、令牌),包括 XML 文件(src/main/mule)和属性文件(src/main/resources),然后使用 MuleSoft 的安全属性配置对其进行加密。
分步流程
第 1 步:验证项目结构
- 检查当前工作目录中是否存在
src/main/mule目录 - 如果未找到,请告知用户这似乎不是 Mule 应用项目
第 2 步:获取用户配置
按以下顺序向用户询问信息,一次只问一个问题:
首先,询问加密密钥:
- “你想使用什么加密密钥来加密值?(此密钥将用于加密和解密安全属性)”
然后,询问加密算法:
- “你想使用哪种加密算法?(请输入编号)”
AES- 高级加密标准(128、192 或 256 位)Blowfish- 快速分组密码DES- 数据加密标准DESede- 三重 DESRC2- Rivest Cipher 2
接下来,询问密码模式:
- “你想使用哪种密码模式?(请输入编号)”
CBC- 密码分组链接CFB- 密文反馈ECB- 电子密码本OFB- 输出反馈GCM- Galois/计数器模式(仅适用于 AES)
最后,询问是否需要备份:
- “你想将未加密的值保存到
local.properties以供参考吗?(是/否)”
第 3 步:定位或下载安全属性工具 JAR
检查之前,请明确告知用户你正在做什么以及原因。 不要使用“让我检查一下 JAR”这样含糊的说法——用户不会知道你指的是哪个 JAR。请改为这样说明:
“正在检查 MuleSoft secure-properties-tool JAR(用于加密敏感值的 CLI 工具)。如果本地尚未下载,我会从 MuleSoft 文档网站获取它。”
- 检查 JAR 是否已存在于:
{skill_base_directory}/assets/secure-properties-tool.jar - 如果已存在,告知用户已在本地找到该文件,将重复使用,然后继续
- 如果未找到,告知用户未找到该文件,正在下载,然后自动下载:
- 如有需要,创建 assets 目录:
mkdir -p {skill_base_directory}/assets - 使用
curl下载(优先使用——macOS 默认提供):curl -L -o "{skill_base_directory}/assets/secure-properties-tool.jar" \ "https://docs.mulesoft.com/mule-runtime/4.4/_attachments/secure-properties-tool.jar" - 如果无法使用
curl,尝试使用wget:wget -O "{skill_base_directory}/assets/secure-properties-tool.jar" \ "https://docs.mulesoft.com/mule-runtime/4.4/_attachments/secure-properties-tool.jar" - 下载后,确认文件存在且非空,然后再继续
- 如有需要,创建 assets 目录:
- 如果下载失败,告知用户并提供手动下载 URL:
https://docs.mulesoft.com/mule-runtime/4.4/_attachments/secure-properties-tool.jar - 注意:此处不能使用 Maven(
mvn)——此 JAR 托管在文档网站上,而非 Maven 仓库
第 4 步:扫描 XML 文件和属性文件
在以下两个位置扫描敏感数据:
A. 扫描 XML 文件
扫描 src/main/mule 中的所有 XML 文件(包括子目录),查找敏感属性:
检测模式(不区分大小写):
password、passwd、pwdsecret、apikey、api-key、api_keytoken、auth、credentialusername、user、loginurl、uri、host、endpointclientId、client-id、client_idclientSecret、client-secret、client_secretkey、private、certificate
重要:标记符合以下条件的属性:
- 与上述某个模式匹配
- 值非空
- 尚未使用安全属性占位符(不以
${secure::开头) - 包括使用属性占位符的属性(例如
${email.password}或${db.username})——这些需要转换为${secure::}格式
B. 扫描 Properties/YAML 文件
- 扫描
src/main/resources目录(包括子目录),查找现有的.properties和.yaml/.yml文件 - 对找到的每个文件,使用上述相同模式检查其中是否包含敏感数据
- 跟踪包含敏感值的属性名称(例如,
email.password=secret→ 跟踪email.password) - 这些值需要加密并移至
.secure.properties文件
第 5 步:显示发现结果
显示所有发现的敏感数据摘要:
- XML 文件:列出包含敏感属性(硬编码值或属性占位符)的每个文件
- Properties 文件:列出包含敏感属性的文件及其属性名称
- 显示属性/属性值名称(但不要显示值,以确保安全)
- 提供发现项目的总数
如果没有发现敏感数据,请告知用户并退出。
第 6 步:征求用户确认
在进行任何更改之前,向用户显示:
- 将修改哪些文件
- 将执行哪些操作(更新
pom.xml、创建安全属性、加密值、更新 XML 文件、创建/更新global-configs.xml) - 将使用
secure-properties-tool.jar加密的值的数量
如果用户拒绝,立即停止。
第 7 步:确定属性键
为发现的每个敏感值确定属性键名称:
A. 对于已存在于 Properties 文件中的值:
- 使用 Properties 文件中现有的属性名称
- 示例:如果
local.properties包含email.password=secret,则使用email.password - 这样可确保转换后,XML 中的引用(如
${email.password})能匹配${secure::email.password}
B. 对于 XML 中的硬编码值:
根据以下信息生成具有上下文的属性键名称:
-
配置/连接器类型:从 XML 元素或父元素中提取
<db:mysql-config>→mysql<http:request-config>→http<sfdc:sfdc-config>→salesforce<mongo:config>→mongodb<ftp:config>→ftp
-
属性名称:使用实际属性名称
password→passwordusername→usernameurl→urlclientId→clientId
-
配置名称属性(如果可用):使用
name或doc:name属性值<db:mysql-config name="MySQL_Config">→ 使用MySQL_Config
属性键格式:{connector}.{config-name}.{attribute} 或 {connector}.{attribute}
示例:
- MongoDB 密码:
mongodb.password或mongodb.MongoDB_Config.password - MySQL 用户名:
mysql.username或mysql.Database_Config.username - HTTP API 密钥:
http.apikey或http.API_Config.apikey - Salesforce 客户端密钥:
salesforce.clientSecret
如果多次生成同一个属性键,则追加数字:mongodb.password.1、mongodb.password.2
第 8 步:加密值
获得用户确认后,批量加密所有唯一的敏感值:
- 收集所有需要加密的唯一敏感值
- 对每个值,无需提示即可运行加密命令:
java -cp {skill_base_directory}/assets/secure-properties-tool.jar com.mulesoft.tools.SecurePropertiesTool string encrypt <algorithm> <mode> <key> <value> - 将每个加密后的值与生成的属性键一起保存
- 按顺序执行所有加密命令,无需再次征求许可
步骤 9:创建/更新 Properties 文件
安全 Properties 文件(src/main/resources/local.secure.properties):
- 检查文件是否存在
- 如果存在:追加新的加密属性
- 如果不存在:创建文件和目录结构
- 格式:
property.key=![encrypted_value]
备份 Properties 文件(src/main/resources/local.properties)——可选:
- 仅当用户选择备份原始值时才创建
- 写入未加密的属性值以供参考
- 格式:
property.key=original_value - 在文件顶部添加警告注释:
# WARNING: This file contains unencrypted sensitive values for reference only # DO NOT commit this file to version control # Add this file to .gitignore
步骤 10:更新 XML 文件
对于每个包含敏感数据的 XML 文件,执行以下两类更新:
A. 将硬编码值替换为安全属性占位符:
- 将每个硬编码的敏感值替换为
${secure::property.key.name}
示例:
<mongo:config name="MongoDB_Config">
<mongo:connection username="admin" password="secret123" database="mydb" />
</mongo:config>
<mongo:config name="MongoDB_Config">
<mongo:connection username="${secure::mongodb.MongoDB_Config.username}"
password="${secure::mongodb.MongoDB_Config.password}"
database="mydb" />
</mongo:config>
B. 更新现有属性占位符,添加 secure:: 前缀:
- 如果 XML 已使用类似
${email.password}的属性占位符,将其更新为${secure::email.password} - 重要:仅更新已加密(已移至
.secure.properties)的属性对应的占位符
示例:
<logger message="${email.username}"/>
<logger message="${email.password}"/>
<logger message="${secure::email.username}"/>
<logger message="${secure::email.password}"/>
完成所有更改后,将更新后的 XML 写回磁盘。
步骤 11:创建/更新 global-configs.xml
检查 src/main/mule/global-configs.xml 是否存在:
如果存在:
- 读取文件并检查是否已存在 secure-properties 配置
- 如果不存在,告知用户需要手动添加此配置:
<secure-properties:config name="Secure_Properties_Config"
file="local.secure.properties"
key="${encryption.key}"
doc:name="Secure Properties Config">
<secure-properties:encrypt algorithm="ALGORITHM" mode="MODE" />
</secure-properties:config>
如果不存在:
- 创建新的
global-configs.xml文件,并采用正确的 Mule XML 结构 - 添加 secure-properties 命名空间和配置
- 添加 secure properties 配置元素
模板:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:secure-properties="http://www.mulesoft.org/schema/mule/secure-properties"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/secure-properties http://www.mulesoft.org/schema/mule/secure-properties/current/mule-secure-properties.xsd">
<secure-properties:config name="Secure_Properties_Config"
file="local.secure.properties"
key="${encryption.key}"
doc:name="Secure Properties Config">
<secure-properties:encrypt algorithm="ALGORITHM" mode="MODE" />
</secure-properties:config>
</mule>
步骤 12:使用 Secure Properties 依赖项更新 pom.xml
- 读取项目根目录中的
pom.xml文件 - 检查是否已存在
mule-secure-configuration-property-module依赖项 - 如果不存在,将其添加到
<dependencies>部分:<dependency> <groupId>com.mulesoft.modules</groupId> <artifactId>mule-secure-configuration-property-module</artifactId> <version>1.3.0</version> <classifier>mule-plugin</classifier> </dependency> - 如果依赖项已存在,告知用户并跳过此步骤
步骤 13:使用加密密钥更新 launch.json
- 检查项目根目录中是否存在
.vscode/launch.json - 如果存在:
- 读取文件
- 找到用于运行 Mule 应用程序的配置
- 在每个配置中查找
mule.runtime.args字段 - 如果存在
mule.runtime.args,将-M-Dencryption.key=<their-encryption-key>追加到现有值 - 如果不存在
mule.runtime.args,添加该字段,值为-M-Dencryption.key=<their-encryption-key> - 将更新后的 launch.json 写回磁盘
- 检查 .gitignore:确保
.vscode/或.vscode/launch.json位于.gitignore中- 如果
.gitignore存在,检查其中是否包含.vscode/或.vscode/launch.json - 如果未找到这两种模式中的任何一种,将
.vscode/添加到.gitignore - 如果
.gitignore不存在,则创建该文件并添加.vscode/
- 如果
- 如果不存在,告知用户需要手动将加密密钥添加到运行配置中:
Add to VM arguments: -M-Dencryption.key=<their-encryption-key> Or set as environment variable: export ENCRYPTION_KEY=<their-encryption-key>
步骤 14:在 .gitignore 中保护现有 Properties/YAML 文件
- 对于每个包含敏感数据的 Properties/YAML 文件(在步骤 4 中识别):
- 将该文件添加到
.gitignore,以防止提交敏感数据 - 这包括
local.properties、dev.properties等文件
- 将该文件添加到
步骤 15:最终摘要
提供完成情况摘要:
- ✅ 扫描的 XML 文件数量
- ✅ 扫描的 properties 文件数量
- ✅ 加密的敏感值数量
- ✅ 已创建/更新安全属性文件(例如,
local.secure.properties) - ✅ 已更新的 XML 文件:
- 将硬编码值替换为
${secure::}占位符 - 将现有属性引用从
${property}更新为${secure::property}
- 将硬编码值替换为
- ✅ 已配置带安全属性的 global-configs.xml
- ✅ 已更新 pom.xml,添加安全属性依赖
- ✅ 已更新 launch.json,添加加密密钥
- ✅ 已在 .gitignore 中保护包含敏感数据的现有 properties/YAML 文件
重要提醒:
- 请勿将
local.secure.properties提交到版本控制 - 请勿将
local.properties(如已创建)提交到版本控制 - 请勿将包含敏感数据的任何 properties/YAML 文件提交到版本控制(这些文件现已列入 .gitignore)
- 确认
.secure.properties中的属性名称与 XML 文件中的引用相匹配 - 在提交更改前,使用加密密钥测试应用程序
- 检查所有 XML 文件的更改,确保正确添加了
${secure::}前缀
错误处理
- 如果未安装 Java,请告知用户并退出
- 如果 JAR 下载失败,请提供手动下载说明
- 如果加密失败,请显示错误并跳过该值
- 如果 XML 解析失败,请显示警告并继续处理其他文件
- 如果文件写入失败,请显示错误并列出已完成的内容
安全最佳实践
- 切勿以纯文本形式记录或显示敏感值
- 进行更改前务必征求确认
- 提醒用户不要提交安全属性文件
- 建议添加
.gitignore条目
参考文档
如需了解更多信息,请参阅: https://docs.mulesoft.com/anypoint-code-builder/int-create-secure-configs