# Claude Code 拼出的 curl -u，看 ps 时密码到底藏在哪一层？

**URL:** <https://www.shiqidu.com/t/topic/1921>\
**Category:** 人工智能\
**Tags:** 问与答, 信息安全, Claude, AICoding\
**Created:** [2026 年11 月 4 日 02:16 UTC](https://www.shiqidu.com/t/topic/1921 "2026-11-04T02:16:24Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

作者： ![shiqidu\_editor](https://www.shiqidu.com/user_avatar/www.shiqidu.com/shiqidu_editor/32/528_2.png) [@shiqidu\_editor](https://www.shiqidu.com/u/shiqidu_editor)\
发布日期： [2026 年11 月 4 日 02:16 UTC](https://www.shiqidu.com/t/topic/1921/1 "2026-11-04T02:16:24Z")

</div>

本机 Agent 去调带鉴权的接口，或者顺手连一下开发库，命令看着挺正常：`curl -u user:secret …`，或者 `mysql -u… -p密码`。过一会儿用 `ps` 扫进程列表，密码串还挂在那里。容易先怪 curl / mysql 客户端没把 argv 抹掉。更稳的做法是先拆两层：外层包命令的 shell，和真正干活的那个子进程。两层看清楚了，才知道该改配置、改注入方式，还是别让模型直接拼明文。

## 子进程自己可能已经抹了

MySQL 8.4 手册里的 [End-User Guidelines for Password Security](https://dev.mysql.com/doc/refman/8.4/en/password-security-user.html) 写得很明白：`-ppassword` / `--password=…` 写在命令行上不安全，别的用户用 `ps` 一类工具可能看见。客户端初始化时通常会把 argv 里的密码覆写成零，但仍有一小段可见窗口。有些系统上覆写根本不起作用，密码会一直留在进程列表里。交互式只写 `-p`、不带值，让客户端自己提示输入，比把明文贴在 argv 上稳一些。非交互场景更常见的做法是权限 600（或 400）的 option file，或者用 `mysql_config_editor` 写进混淆过的 `.mylogin.cnf`，再用 `--login-path`。

[mysql\_config\_editor](https://dev.mysql.com/doc/refman/8.4/en/mysql-config-editor.html) 那一节还补了两点容易忽略的：混淆是防无意泄露，不能当不可破的加密。有管理员权限的人仍可能费点功夫解开。登录路径文件还必须只有当前用户可读写，否则工具和客户端都会直接忽略它。终端标题栏如果显示当前命令，明文密码也可能一直挂在窗口标题上——手册里也点过这个坑。

curl 一类工具在自己进程里对 `-u` 做覆写的行为，和 MySQL 客户端类似——你可能看到子进程那一行密码已经空了。别停在这一步就放心。

## 外层 shell 整段命令还在

社区里有用户报告：Claude Code 跑复合命令时，外层会用类似 `zsh -c 'source … && eval …'` 的方式包一层。对照官方 [Security](https://docs.claude.com/en/docs/claude-code/security) 页和 changelog，当前 npm 包版本能查到 2.1.318。Security 页谈的是权限模式、sandbox、凭证存放（macOS Keychain，Linux 上文件 mode 0600 等），并没有把「外层一定是 source && eval」写成官方固定实现。把这类现象标成用户报告更合适。本机复现时直接 `ps` / `pstree` 看自己装的版本，别把社区截图当成产品承诺。

差别在这：子进程把 `-u` 密码抹空，不等于外层 shell 的 argv 也干净了。外层那一行往往是整段脚本字符串，里面如果还带着明文密钥，命令跑多久，`ps` 就能看见多久。有人只盯 curl 那一行觉得「已经空了」，漏掉上面那个还挂着完整命令的 zsh / bash，就会误判成「已经安全」。

站里另有一篇讲 [读不到 .env ≠ 命令行不泄露](https://www.shiqidu.com/t/topic/1824)，角度是文件读权限和 Agent 读环境文件。这篇只盯进程列表和 argv，两边别混成一件事。

## 落地时少踩的几处

- 需要鉴权时，优先把密钥放进环境变量或权限收紧的配置，注入后立刻 `unset` 掉临时变量。别让 Agent 直接拼 `mysql -p密码` 或 `curl -u user:pass`。
- MySQL 本机脚本可以走 `mysql_config_editor set --password`，客户端用 `--login-path=…`。或 `chmod 600` 的 option file，用 `--defaults-file` 指过去。
- 能挡一层就挡一层：本地 socket、只读 MCP / 自写 CLI 包在 Agent 前面，比让模型自由拼 argv 好控。敏感操作尽量走人审或固定封装，而不是对话里随手生成带密码的一行命令。
- 排查时同时看外层 shell 和子进程两行，不要只看 curl / mysql 那一行。必要时用 `ps -ww` / `pstree -a` 把完整命令行展开。

不写怎么绕过沙箱，也不讨论去扫别人机器上的进程列表。你们本机用 Claude Code 跑带密钥的命令时，外层 argv 和子进程是不是经常不一致？有没有更稳、又不挡效率的写法？
