Skip to content

sec/sec26p2-mantou:Secret YAML 类型化解析与体积上限 - #337

Merged
GoSimplicity merged 14 commits into
mainfrom
sec/sec26p2-mantou
Oct 24, 2026
Merged

GoSimplicity merged 14 commits into
mainfrom
sec/sec26p2-mantou

Conversation

@GoSimplicity

Copy link
Copy Markdown
Owner

合入分支 sec/sec26p2-mantou,tip 12494681df44ef8c25faa5d0dc1880476300133d。

在 SEC-29 之上继续 SEC-26:Secret YAML 类型化解析后再恢复占位符,入口上限放宽到 2 MiB,go.yaml.in/yaml/v2 改为直接依赖。

Open in Web Open in Cursor 

- list/detail 只返回键名和值字节数(data_keys/string_data_keys/redacted),
  data/string_data 保留键、值置空;YAML 中 data/stringData 值替换为 <redacted>
- 三个接口都去掉 kubectl.kubernetes.io/last-applied-configuration 注解
- 新增 GET /api/k8s/secret/:cluster_id/:namespace/:name/reveal,每次调用同步写审计
  (仅谁/何时/集群/命名空间/名称/键名,不含值),审计失败时不返回明文
- reveal 在接口目录登记为 k8s:secret:reveal,通配符授权不覆盖该接口
- 更新时回填脱敏值:表单空值保留原值,YAML 占位符还原原值,创建时拒绝占位符
- UpdateSecret:stringData 中值为空且集群已有非空值的键,不再作为 stringData 提交,
  改为在 data 中保留原值,避免 K8s 合并 stringData 时清空 data(与 data 的空值保留规则一致)
- reveal 审计记录 status_code 写实际结果(200/400/404/403/500),不再固定 200;
  同步审计写入失败时返回 HTTP 500(ErrAuditWriteFailed),不含明文
- 显式授权路由只认 api.Path == FullPath 且方法一致的精确匹配,
  参数化授权路径(:param)、具体请求路径、通配符均不覆盖 reveal
- reveal 按 keys 过滤时,data 与 stringData 同名键两处都返回,与全量输出一致
- 补测试:stringData 占位符落到 data 的分支、data/stringData 同名键的脱敏/写回/reveal、
  审计状态码、审计失败 500、参数化授权 403、admin 放行
- 同步更新 docs/release/k8s-secret-redaction.md
- GET /token 只返回注解 service-account.name/uid 与 SA 匹配的 token Secret,借挂的 Secret 被拒绝
- 创建/更新 SA 忽略请求中的 secrets 引用(记 Warn),更新保留集群现有引用;YAML 更新以 URL 的 name/namespace 为准
- GET/POST /token 加入显式授权精确匹配名单,权限码 k8s:serviceaccount:token / k8s:serviceaccount:token:create,
  启动时登记到 cl_system_apis,已有自动名称行按条件改名
- 每次调用同步写 TOKEN_REVEAL / TOKEN_CREATE 审计(仅元数据),审计失败不返回 token(HTTP 500),响应 no-store
- ServiceAccountService 注入 AuditService,重新生成 wire_gen.go
- 文档 docs/release/k8s-serviceaccount-token.md
- renameAutoNamedPermission 的 WHERE 增加 description = '<METHOD> <path>',管理员只改说明的行整行不动
- 读取现有行时一并读取 description
- CreateInBatches(OnConflict DoNothing) 后核对本次登记的权限码,缺行记 Warn(只含权限码)
- 测试:管理员只改说明不被覆盖、自动命名行正确改名、权限码冲突被跳过时告警
- YAML 带 metadata.resourceVersion 时严格乐观锁:只 Update 一次,冲突返回 BusinessError{ErrK8sResourceConflict},
  handler 经 respondBusinessError 映射为 HTTP 409 + code=1;不带版本保持 RetryOnConflict
- 新增 base.Conflict/ConflictError、constants.ErrK8sResourceConflict、utils/manager UpdateServiceAccountWithResourceVersion
- GetServiceAccountSecrets 改为接收已读取的 SA,GetServiceAccountToken / GetServiceAccountTokens 不再重复 Get
- TokenRequest 的 ExpirationTime 先 .UTC() 再格式化
- 测试:乐观锁过期/正确/无版本三条路径、409 映射、UTC 转换、SA 只读一次、末尾斜杠与大小写不能绕过 token 显式授权
- 旧 UpdateServiceAccount 方法保留(留给 SEC-30)
- preserveRedactedData:请求 data 为 nil(未携带/null)时保留集群现有 data;{} 表示删除全部 data 键
- preserveRedactedStringData:stringData 空串只在请求 data 为 nil 或包含该键时恢复原值,否则该键被删除
- 测试:键在 data 中→恢复、键不在→删除;data 为 nil→保留、data 为 {}→清空;更新原有用例到新语义
- 先把 YAML 解析为类型化 Secret(字段与 corev1.Secret 一一对应,data 值保留原始文本),
  在 sec.Data / sec.StringData 上恢复和检查占位符,不再按小写键查 map,
  Data/DATA/StringData/stringdata 等大小写变体与规范写法同样处理
- 拒绝多文档 YAML(含末尾空文档)、任意层级完全重复的键、顶层与 metadata 下只差大小写的字段
- data 解码后(含折行 base64)为占位符或其空白变体、stringData 为占位符空白变体时拒绝
- YAMLToSecret 复用同一解析并兜底拒绝残留占位符
- 解析错误抹除可能回显的值
- 文档补充 SEC-26 P2 行为变化
- P2-1:YAML 库报错按白名单改写,只保留错误类别与行号,invalid map key 等不再回显值
- P3-1:判断占位符前去掉首尾空白、NUL 与 U+200B/U+200C/U+200D/U+FEFF
- P3-2:同一映射中转成字符串后相同的键(1 与 "1")按重复键拒绝,结果确定
- P3-3:注释与文档改为 encoding/json 不区分大小写的规则,补充已知差异与升级风险
- P3-4:补非标准大小写 Metadata 下的重复键测试
- P3-6:Secret YAML 入口 1 MiB 上限,解析前检查
- maxSecretYAMLBytes 由 1 << 20 改为 2 << 20,仍按 YAML 文本字节数计算,在任何解析之前检查;报错文案改为「YAML 超过 2 MiB 上限」,不回显内容。
- data 的值是 base64(膨胀约 4/3),1 MiB 的入口上限会挡住接近 Kubernetes 1 MiB 上限的 Secret;放宽后这类 Secret 也能提交,真正的大小限制交给 apiserver。
- TestR2SizeLimit:2097152 字节通过,2097153 字节在三条路径上均以固定的大小错误拒绝且不回显;恰好上限的语法错误输入进入解析、多 1 字节则在解析前拒绝。
- 发布说明同步更新上限与原因,升级风险中补充超过 2 MiB 的 YAML 会在入口被拒绝。
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-24T03:04:10.406463Z 1249468 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@GoSimplicity
GoSimplicity merged commit 7fe49bf into main Oct 24, 2026
1 of 2 checks passed
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.

1 participant