T05 · Unauthorized Access and Privilege Escalation
- Location
mmx-monitor-server.js:369- Finding
API key is read and used before explicit user authorization
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a real MiniMax quota dashboard, but its code can use the local API key and expose billable actions more broadly than its documentation promises.
Review before installing. This skill needs access to your MiniMax API key and will make authenticated MiniMax requests. Do not run it on a shared or network-exposed machine, do not rely on --no-probe to block billable probe calls, and assume the dashboard may read and use ~/.mmx/config.json as soon as the page polls quota, not only after the documented credential button is clicked.
mmx-monitor-server.js:369API key is read and used before explicit user authorization
mmx-monitor-server.js:545Local credential proxy is not restricted to loopback and uses spoofable request headers as access controls
mmx-monitor-server.js:10Documented --no-probe security option is not implemented
mmx-monitor-server.js:173Upstream-controlled model names are rendered through innerHTML without escaping
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# Copy template
cp .env.example .env
MINIMAX_API_KEY=sk-cp-…here # MiniMax API Key (Token Plan type)
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# Copy template
cp .env.example .env
MINIMAX_API_KEY=sk-cp-…here # MiniMax API Key (Token Plan type)
Referenced artifact was not completely inspected
- ✅ `<skill-dir>/history.jsonl` is created on first `token_plan` poll and is mentioned in `SKILL.md` Security section + this file.
Referenced artifact was not completely inspected
- ✅ `<skill-dir>/history.jsonl` is created on first `token_plan` poll and is mentioned in `SKILL.md` Security section + this file.
Referenced artifact was not completely inspected
- ✅ `<skill-dir>/history.jsonl` is created on first `token_plan` poll and is mentioned in `SKILL.md` Security section + this file.
The skill uses 'env' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.
Suspicious Unicode normalization or mixed-script content
This markdown file contains natural-language product/skill descriptions, and L074 states the trigger was narrowed to a single Chinese phrase (mmx 仪表盘启动). Elsewhere the changelog also describes user-facing buttons and labels only in Chinese, but this file does not indicate that the skill is intentionally China/Chinese-locale-only or that users can choose language, which can violate language/locale policy requirements.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
1. **Load local credentials on demand, never cached** — Dashboard's "加载本地凭证" button triggers `POST /api/load_cred` which authorizes the server to read `~/.mmx/config.json` fresh on every credentialed request (v1.7.0+). The key is never held in process memory between calls — verified by `lldb memory find` showing no key in the server process. Not returned in any HTTP response.
2. **Poll MiniMax API every 60s** — `https://www.minimaxi.com/v1/token_plan/remains` for quota data.
3. **Write local usage samples** — `<skill-dir>/history.jsonl` is appended on each quota poll (24h ring buffer, contains usage percentages only, no credentials).
4. **Run inference probe on user demand only** — Dashboard button + `confirm()` triggers `/api/probe` (5 chat completion requests, ~180 tokens).
**This service will NOT**:
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
const t0 = Date.now();
try {
const { status, data } = await httpsGet(
'https://api.minimaxi.com/v1/text/chatcompletion_v2',
{
'Authorization': 'Bearer ' + key,
'Content-Type': 'application/json',
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
const t0 = Date.now();
try {
const { status, data } = await httpsGet(
'https://api.minimaxi.com/v1/text/chatcompletion_v2',
{
'Authorization': 'Bearer ' + key,
'Content-Type': 'application/json',
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
const t0 = Date.now();
try {
const { status, data } = await httpsGet(
'https://api.minimaxi.com/v1/text/chatcompletion_v2',
{
'Authorization': 'Bearer ' + key,
'Content-Type': 'application/json',
The comments assert the key is not kept in process memory, but manual input is assigned to the apiKey variable and retained in page memory. While this is not an immediate exfiltration primitive in the provided file, misleading security claims around secret handling can cause unsafe operator assumptions and increase exposure if any other script, extension, crash dump, or debugging path can inspect page state.
The comment at L350 states '启动时不读 config.json,不读 localStorage。直接 startMon。' in a way that suggests a harmless startup path, but startMon at L351 immediately calls fetchQuota, which attempts backend quota access on load. This is an intent/documentation mismatch because the inline documentation frames startup as only avoiding local reads, while the actual code initiates monitoring network activity right away.
The instruction "Keep SKILL.md body in English" is a natural-language locale requirement. Under the policy, forcing a specific language without opt-in or a clear documented justification is a reportable violation.
The line "SKILL.md body must be in English; reference docs in English" mandates a specific language for documentation. This is a locale/language policy issue because it does not offer contributor choice or explain a necessary region- or compliance-based reason.
The main README is written in English, but it instructs users to click a button labeled only as "加载本地凭证" without an English equivalent or any opt-in language selection in the instruction itself. This can be viewed as a locale/language policy issue because the skill's operational guidance assumes a specific language for a required UI interaction rather than offering a user-selectable language path.
Declared permissions with no matching code capability may indicate removed functionality or pre-staging for future abuse.
Declared permissions with no matching code capability may indicate removed functionality or pre-staging for future abuse.
Declared permissions with no matching code capability may indicate removed functionality or pre-staging for future abuse.
The markdown explicitly presents the trigger word as mmx 仪表盘启动, which is a Chinese-only invocation example, and the document does not state that users may choose their preferred language for interacting with the skill. While other example phrases appear earlier in the frontmatter, the main user-facing trigger section emphasizes a single locale-specific phrase without opt-in or language-choice guidance.
The document declares lang="zh-CN", and the UI text and time formatting are consistently hard-coded for Chinese. This imposes a specific language/locale on users without offering an opt-in or language selection, which matches the natural-language locale policy violation criteria.
No suspicious patterns detected.