Skip to content

fix[storage]: desensitize addonInfo password fields in ExternalPrimaryStorageInventory#4117

Closed
zstack-robot-2 wants to merge 1 commit into
5.5.22from
sync/songtao.liu/fix/ZSTAC-80822-addon-password-mask-v2
Closed

fix[storage]: desensitize addonInfo password fields in ExternalPrimaryStorageInventory#4117
zstack-robot-2 wants to merge 1 commit into
5.5.22from
sync/songtao.liu/fix/ZSTAC-80822-addon-password-mask-v2

Conversation

@zstack-robot-2
Copy link
Copy Markdown
Collaborator

根因分析

ExternalPrimaryStorageInventory 构造器 (line 65) 对 addonInfo 字段遗漏脱敏处理。已有 desensitizeConfig()config 做 URL 密码脱敏 (line 64),但 addonInfo.mdsInfos[].password 未脱敏,密码明文泄漏到 API 响应中。

  • 位置: ExternalPrimaryStorageInventory.java:65
  • 根因: 构造器中只脱敏了 config,未脱敏 addonInfo

修复方案

  1. 在构造器 line 66 新增 desensitizeAddonInfo(addonInfo) 调用
  2. 新增 desensitizeAddonInfo(Map) 方法:遍历 addonInfo 中 mdsInfos 列表,将每个元素的 password 字段替换为 "******"

测试

4 个单元测试覆盖:密码脱敏、null 安全、无 mdsInfos、mdsInfo 无 password 字段

影响范围

仅影响 API 响应输出,不影响 DB 存储和内部逻辑。风险级别:低。

🤖 Generated with Claude Code

sync from gitlab !10015

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

Review Change Stack

Walkthrough

PR在ExternalPrimaryStorageInventory类中引入了敏感信息脱敏机制,新增MASK常量和多个private静态脱敏方法,在构造函数中对addonInfo进行脱敏处理,调整了config的脱敏逻辑,并新增了8个测试方法覆盖脱敏行为和边界场景。

Changes

密码脱敏与安全处理

Layer / File(s) Summary
脱敏方法实现
header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageInventory.java
新增MASK常量"******"和三组私有静态脱敏方法。desensitizeMdsInfos遍历List类型的mdsInfos,对Map元素中的sshPassword、password、sshUsername字段进行掩码替换;desensitizeAddonInfodesensitizeConfig分别处理两种信息源的mdsInfos列表。
构造函数脱敏集成
header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageInventory.java
构造函数在反序列化addonInfo后,新增调用desensitizeAddonInfo(addonInfo)以确保返回的对象不包含明文凭证。
脱敏逻辑测试覆盖
test/src/test/java/org/zstack/test/header/storage/addon/ExternalPrimaryStorageInventoryTest.java
新增8个测试方法验证:addonInfo的password和sshPassword脱敏、config的mdsUrls凭据脱敏、空值和缺失字段的安全处理、原始密码不泄漏等场景。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 缘在兔年又逢春,敏感密码换面孔,
掩码如纱隐芳华,测试周全防漏洞,
脱敏之道贵在细,安全存储心欢喜!


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Title check ❌ Error The pull request title exceeds the 72 character limit (86 characters). Shorten the title to 72 characters or less, e.g., 'fix[storage]: Desensitize addonInfo passwords in ExternalPrimaryStorage'.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description clearly describes the root cause, fix, tests, and impact related to the password desensitization changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sync/songtao.liu/fix/ZSTAC-80822-addon-password-mask-v2

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageInventory.java (1)

104-113: ⚡ Quick win

建议提取脱敏掩码常量,避免魔法值。

这里直接写死 "******",后续若掩码规则调整,容易出现实现与测试不一致。建议抽成常量并统一复用。

♻️ 建议修改
 public class ExternalPrimaryStorageInventory extends PrimaryStorageInventory {
+    private static final String PASSWORD_MASK = "******";
     private String identity;
@@
                 Map mds = (Map) item;
                 if (mds.containsKey("password")) {
-                    mds.put("password", "******");
+                    mds.put("password", PASSWORD_MASK);
                 }
             }
         }
     }

As per coding guidelines, “避免使用魔法值(Magic Value):直接使用未经定义的数值或字符串应替换为枚举或常量。”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageInventory.java`
around lines 104 - 113, The code in desensitizeAddonInfo currently uses the
magic string "******" to mask passwords; extract that literal into a well-named
constant (e.g., PASSWORD_MASK or DESENSITIZE_MASK) declared on the
ExternalPrimaryStorageInventory class and replace occurrences in
desensitizeAddonInfo where mds.put("password", "******") is used so
callers/tests can reuse the same constant and any future mask changes are
centralized.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageInventory.java`:
- Around line 104-113: The code in desensitizeAddonInfo currently uses the magic
string "******" to mask passwords; extract that literal into a well-named
constant (e.g., PASSWORD_MASK or DESENSITIZE_MASK) declared on the
ExternalPrimaryStorageInventory class and replace occurrences in
desensitizeAddonInfo where mds.put("password", "******") is used so
callers/tests can reuse the same constant and any future mask changes are
centralized.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: http://open.zstack.ai:20001/code-reviews/zstack-cloud.yaml (via .coderabbit.yaml)

Review profile: CHILL

Plan: Pro

Run ID: 6363e681-afa0-4ada-a1cf-021502b1e9e9

📥 Commits

Reviewing files that changed from the base of the PR and between a621cf2 and 61e4ec1.

📒 Files selected for processing (2)
  • header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageInventory.java
  • test/src/test/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageInventoryTest.java

@MatheMatrix MatheMatrix force-pushed the sync/songtao.liu/fix/ZSTAC-80822-addon-password-mask-v2 branch from 61e4ec1 to 0aa6577 Compare May 27, 2026 07:10
…yStorageInventory

Add desensitizeAddonInfo() to mask password, sshPassword, and sshUsername
fields in addonInfo.mdsInfos entries. Also fix desensitizeConfig to use
Map-based desensitizeMdsInfos instead of URL-based desensitizeUrlList for
mdsInfos, since MdsInfo objects serialize with Gson field names
(sshPassword/sshUsername), not embedded in URL strings.

Resolves: ZSTAC-80822

Change-Id: I85a8eb039d7b77ec837521de624da88553d68678
@MatheMatrix MatheMatrix force-pushed the sync/songtao.liu/fix/ZSTAC-80822-addon-password-mask-v2 branch from 0aa6577 to 0205a9d Compare May 27, 2026 07:13
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
test/src/test/java/org/zstack/test/header/storage/addon/ExternalPrimaryStorageInventoryTest.java (1)

105-132: ⚡ Quick win

mdsInfos 的断言收紧到精确掩码值。

这里现在只校验 sshPassword 不等于原始明文;如果后续把字段删掉、置空,或换成其他占位符,这个测试仍然会通过,但 API 返回契约已经变了。建议直接断言为 "******",这样既能保证“不泄漏”,也能保证“字段仍存在且按约定脱敏”。

建议修改
-                    Assert.assertNotEquals("shouldBeMasked", ((Map) item).get("sshPassword"));
+                    Assert.assertEquals("******", ((Map) item).get("sshPassword"));
As per coding guidelines “之前的代码产生的行为不要直接去改动,即使是 bug 也可能用户有依赖”.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@test/src/test/java/org/zstack/test/header/storage/addon/ExternalPrimaryStorageInventoryTest.java`
around lines 105 - 132, The test method testConfigWithoutMdsInfosDoesNotLeak
should tighten its assertion for the mdsInfos sshPassword to expect the exact
mask value instead of only asserting it differs from the original; update the
assertions in ExternalPrimaryStorageInventoryTest (inside
testConfigWithoutMdsInfosDoesNotLeak) to check that each item's "sshPassword"
entry equals the canonical mask string (e.g., "******") and still verify mdsUrls
masking as before, ensuring the field remains present and is masked to the
agreed contract rather than merely non-equal to the plaintext.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@test/src/test/java/org/zstack/test/header/storage/addon/ExternalPrimaryStorageInventoryTest.java`:
- Around line 105-132: The test method testConfigWithoutMdsInfosDoesNotLeak
should tighten its assertion for the mdsInfos sshPassword to expect the exact
mask value instead of only asserting it differs from the original; update the
assertions in ExternalPrimaryStorageInventoryTest (inside
testConfigWithoutMdsInfosDoesNotLeak) to check that each item's "sshPassword"
entry equals the canonical mask string (e.g., "******") and still verify mdsUrls
masking as before, ensuring the field remains present and is masked to the
agreed contract rather than merely non-equal to the plaintext.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: http://open.zstack.ai:20001/code-reviews/zstack-cloud.yaml (via .coderabbit.yaml)

Review profile: CHILL

Plan: Pro

Run ID: bbc6a22f-e2a5-463b-b9af-21e0c63c8bd7

📥 Commits

Reviewing files that changed from the base of the PR and between 61e4ec1 and 0205a9d.

📒 Files selected for processing (2)
  • header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageInventory.java
  • test/src/test/java/org/zstack/test/header/storage/addon/ExternalPrimaryStorageInventoryTest.java

@zstack-robot-1 zstack-robot-1 deleted the sync/songtao.liu/fix/ZSTAC-80822-addon-password-mask-v2 branch May 28, 2026 07:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants