Back to skill

Security audit

Ai Config Admin

Security checks for vulnerabilities and agentic risk

Overview

This skill is a legitimate AI configuration manager, but it can persistently rewrite sensitive agent settings and credentials in ways users should review carefully.

Review this before installing if you use shared machines, CI workers, or sensitive provider credentials. Use it only for deliberate AI config changes, avoid passing real secrets as command-line arguments, inspect diffs before full-file replacements, check permissions on generated config and backup files, and remove old backups that may contain rotated credentials.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/openclaw_config.py:350
Finding
Authentication secrets are accepted through command-line arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:113-114, 151-153`; `scripts/openclaw_config.py:350-351, 365-366`; `scripts/claude_config.py:110-119` **Vulnerability Type**: Exposure of sensitive credentials through process arguments **Risk Level**: Medium ### Complete Code Snippets From `SKILL.md:113-114`: ```bash - For a brand-new provider, `add-model` needs enough provider config to make it valid: at minimum `--base-url` and `--api`; use `--api-key` and `--auth-header` when appropriate. - Use `add-openai-model` only for OpenAI-compatible provider setup flows that require explicit `apiKey` and `api` handling in one step. ``` From `SKILL.md:151-153`: ```bash python3 {baseDir}/scripts/claude_config.py --file ~/.claude/settings.json set-env \ --anthropic-auth-token 'sk-...' \ --attribution-header '0' ``` From `scripts/openclaw_config.py:350-351`: ```python add_model_parser.add_argument("--base-url") add_model_parser.add_argument("--api-key") ``` From `scripts/openclaw_config.py:365-366`: ```python add_openai_model_parser.add_argument("--base-url", required=True) add_openai_model_parser.add_argument("--api-key", required=True) ``` From `scripts/claude_config.py:110-119`: ```python for name in ("set-env", "replace-env"): env_parser = sub.add_parser(name) env_parser.add_argument("--anthropic-auth-token") env_parser.add_argument("--anthropic-base-url") env_parser.add_argument("--anthropic-default-haiku-model") env_parser.add_argument("--anthropic-default-opus-model") env_parser.add_argument("--anthropic-default-sonnet-model") env_parser.add_argument("--anthropic-model") env_parser.add_argument("--api-timeout-ms") env_parser.add_argument("--disable-nonessential-traffic") ``` ### Technical Analysis The Skill instructs the Agent to supply provider API keys and authentication tokens as literal command-line arguments. The scripts then retrieve these secrets through `argparse`. Command-line arguments are ...[truncated 1979 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove secret-bearing command-line options or retain them only as explicitly deprecated compatibility mechanisms. 2. Accept credentials through protected stdin, such as a dedicated `--api-key-stdin` or `--auth-token-stdin` option. 3. Alternatively, accept the name of an environment variable rather than its secret value, while ensuring the Agent runtime does not log environment contents. 4. For structured replacement operations, continue using stdin but ensure tool-call and input logging redact known secret fields. 5. Update `SKILL.md` examples so no token is placed in the command line, even as a placeholder pattern. 6. Implement centralized redaction for `apiKey`, `OPENAI_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, token, and refresh-token fields in errors and execution telemetry. 7. Encourage short-lived, narrowly scoped credentials and provider-side rotation after suspected exposure. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/codex_config.py:59
Finding
Credential-bearing configuration files are created without enforced restrictive permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/openclaw_config.py:27-32`; `scripts/codex_config.py:59-63, 235-237`; `scripts/claude_config.py:46-51`; `scripts/opencode_config.py:27-32` **Vulnerability Type**: Insecure permissions for sensitive configuration and backup files **Risk Level**: Medium ### Complete Code Snippets From `scripts/openclaw_config.py:27-32`: ```python def save_config(path: Path, data: dict) -> None: path.parent.mkdir(parents=True, exist_ok=True) backup_config(path) with path.open("w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2) f.write("\n") ``` The corresponding backup operation in `scripts/openclaw_config.py:19-24` is: ```python def backup_config(path: Path) -> Path | None: if not path.exists(): return None stamp = datetime.now().strftime("%Y%m%d%H%M%S%f") backup_path = path.with_name(f"{path.name}.{stamp}.bak") shutil.copy2(path, backup_path) return backup_path ``` From `scripts/codex_config.py:59-63`: ```python def write_text(path: Path, text: str) -> None: path.parent.mkdir(parents=True, exist_ok=True) backup_file(path) with path.open("w", encoding="utf-8") as f: f.write(text) ``` From `scripts/codex_config.py:235-237`: ```python if args.cmd == "replace-auth-from-stdin": data = load_json_text(sys.stdin.read()) write_text(auth_path, json.dumps(data, ensure_ascii=False, indent=2) + "\n") ``` From `scripts/claude_config.py:46-51`: ```python def save_settings(path: Path, data: dict) -> None: path.parent.mkdir(parents=True, exist_ok=True) backup_file(path) with path.open("w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2) f.write("\n") ``` From `scripts/opencode_config.py:27-32`: ```python def save_config(path: Path, data: dict) -> None: path.parent.mkdir(parents=True, exist_ok=True) backup_config(path) with path.open("w", encoding="utf ...[truncated 2360 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create credential-bearing files with owner-only mode `0600`, independent of the process umask. 2. Ensure sensitive configuration directories are owned by the expected user and use mode `0700` where compatible. 3. Write updates atomically: - Create a temporary file in the destination directory with mode `0600`. - Flush and synchronize the file. - Replace the destination with `os.replace()`. 4. Verify that the destination is a regular file owned by the current user before modifying it. 5. Reject unsafe symbolic-link destinations or use platform facilities that prevent symlink following. 6. Apply mode `0600` to every backup after creation and verify its ownership. 7. Define a backup-retention policy so old credentials are not retained indefinitely. 8. Preserve restrictive existing permissions when updating files, but fail safely if an existing credential file is group-readable, world-readable, or owned by an unexpected account. 9. Add automated tests using a permissive umask to confirm that active files, temporary files, and backups remain accessible only to their owner. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding
The description claims a multi-tool configuration manager spanning OpenClaw, OpenCode, Codex CLI, and Claude Code, plus broader transformation abilities for natural-language, irregular JSON, and TOML inputs. This code chunk does not implement that broad scope. It only operates on Claude Code's settings.json (defaulting to ~/.claude/settings.json or a provided file), and only supports four actions: summary, replace entire config from stdin using valid JSON, set selected env vars, and replace a fixed list of Claude-related env vars. It does not parse TOML, does not handle natural-language input, does not manage other named tools or files, and does not provide generic provider/model management beyond a few Anthropic-related environment keys. While part of the declared description overlaps with Claude Code/settings.json handling, the declared purpose materially overstates the actual behavior of this specific code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The script is narrowly scoped to Codex CLI config/auth management. It reads and writes ~/.codex/config.toml and ~/.codex/auth.json, summarizes current settings, replaces entire files from stdin, and applies targeted updates to a fixed OpenAI provider section. The declared description substantially overstates the scope by covering multiple products and broader transformation capabilities that are absent from the code. While some declared functionality overlaps (Codex config replacement/update, provider/model setting, OPENAI_API_KEY presence in auth), the overall description does not accurately represent the actual behavior of this code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
The declared description is broader than the supplied code. The script is specifically an OpenClaw config editor for a JSON file, not a general multi-tool configuration manager. It has no logic for OpenCode, Codex CLI, Claude Code, auth.json/settings.json/config.toml handling, or natural-language/irregular-format conversion. While many listed OpenClaw-related actions are accurate (add/remove models/providers, set defaults, update provider credentials, write backups), the overall declared purpose materially overstates the scope and supported formats/tools. Therefore this is a description-behavior mismatch.

Agent Config Directory Access

High
Category
Agent Snooping
Content
- OpenClaw: `~/.openclaw/openclaw.json`
- OpenCode: `~/.config/opencode/opencode.json`
- Codex CLI: `~/.codex/config.toml`, `~/.codex/auth.json`
- Claude Code: `~/.claude/settings.json`

## Routing
Confidence
92% confidence
Finding
The skill is designed to access and modify sensitive agent configuration files under ~/.codex, which can control model providers, authentication mode, endpoints, and other runtime behavior. Because these files influence future agent execution and may contain secrets or trust settings, write access to them creates a high-risk persistence and redirection surface if the skill is abused or tricked by untrusted input.

Agent Config Directory Access

High
Category
Agent Snooping
Content
- OpenClaw: `~/.openclaw/openclaw.json`
- OpenCode: `~/.config/opencode/opencode.json`
- Codex CLI: `~/.codex/config.toml`, `~/.codex/auth.json`
- Claude Code: `~/.claude/settings.json`

## Routing
Confidence
93% confidence
Finding
Access to ~/.claude/settings.json allows persistent modification of Claude Code environment settings, including base URLs, tokens, and model selection. That can redirect traffic to attacker-controlled services, alter trust boundaries, or persist unsafe settings across sessions, making this particularly dangerous in a skill that accepts natural-language instructions.

Agent Config Directory Access

High
Category
Agent Snooping
Content
```bash
python3 {baseDir}/scripts/codex_config.py --help
python3 {baseDir}/scripts/codex_config.py --config-file ~/.codex/config.toml --auth-file ~/.codex/auth.json summary
python3 {baseDir}/scripts/codex_config.py --config-file ~/.codex/config.toml replace-config-from-stdin <<'EOF'
model_provider = "OpenAI"
model = "gpt-5.4"
Confidence
90% confidence
Finding
The documented command path shows the skill can operate directly on ~/.codex/config.toml, a sensitive runtime configuration file for the coding agent. Persistent modification of model/provider settings in this location can change future behavior, networking, and authentication assumptions beyond the current task.

Agent Config Directory Access

High
Category
Agent Snooping
Content
```bash
python3 {baseDir}/scripts/codex_config.py --help
python3 {baseDir}/scripts/codex_config.py --config-file ~/.codex/config.toml --auth-file ~/.codex/auth.json summary
python3 {baseDir}/scripts/codex_config.py --config-file ~/.codex/config.toml replace-config-from-stdin <<'EOF'
model_provider = "OpenAI"
model = "gpt-5.4"
EOF
Confidence
90% confidence
Finding
The replace-config-from-stdin workflow enables full replacement of the Codex CLI config, which is more dangerous than targeted updates because it can silently remove safeguards or add hostile settings. Full-file replacement on agent config creates a strong persistence primitive for malicious reconfiguration.

Agent Config Directory Access

High
Category
Agent Snooping
Content
```bash
python3 {baseDir}/scripts/claude_config.py --help
python3 {baseDir}/scripts/claude_config.py --file ~/.claude/settings.json summary
python3 {baseDir}/scripts/claude_config.py --file ~/.claude/settings.json set-env \
  --anthropic-auth-token 'sk-...' \
  --attribution-header '0'
Confidence
93% confidence
Finding
The skill can invoke commands that modify ~/.claude/settings.json and set Claude-related env values, including authentication material. This can persistently alter how the agent authenticates and where it sends requests, potentially enabling credential misuse or endpoint hijacking.

Agent Config Directory Access

High
Category
Agent Snooping
Content
```bash
python3 {baseDir}/scripts/claude_config.py --help
python3 {baseDir}/scripts/claude_config.py --file ~/.claude/settings.json summary
python3 {baseDir}/scripts/claude_config.py --file ~/.claude/settings.json set-env \
  --anthropic-auth-token 'sk-...' \
  --attribution-header '0'
python3 {baseDir}/scripts/claude_config.py --file ~/.claude/settings.json replace-env \
Confidence
94% confidence
Finding
The replace-env operation can rewrite the Claude-related environment key set in a persistent settings file. Because these values control backend routing and authentication context, a malicious or mistaken change could redirect all future model traffic or disable expected protections.

Agent Config Directory Access

High
Category
Agent Snooping
Content
python3 {baseDir}/scripts/claude_config.py --file ~/.claude/settings.json set-env \
  --anthropic-auth-token 'sk-...' \
  --attribution-header '0'
python3 {baseDir}/scripts/claude_config.py --file ~/.claude/settings.json replace-env \
  --anthropic-base-url 'https://example.invalid' \
  --anthropic-auth-token 'sk-...' \
  --attribution-header '0'
Confidence
94% confidence
Finding
This example shows direct replacement of Claude settings with attacker-influencable base URL and token values. In context, the skill's purpose is configuration management, which makes such writes expected, but that same context also makes the impact greater because the changes are persistent and affect future agent trust and network destinations.

Agent Config Directory Access

High
Category
Agent Snooping
Content
--anthropic-base-url 'https://example.invalid' \
  --anthropic-auth-token 'sk-...' \
  --attribution-header '0'
python3 {baseDir}/scripts/claude_config.py --file ~/.claude/settings.json replace-from-stdin <<'EOF'
{"env":{"ANTHROPIC_BASE_URL":"https://example.invalid"}}
EOF
```
Confidence
91% confidence
Finding
Whole-file replacement of ~/.claude/settings.json from stdin is a high-risk primitive because it allows broad persistent reconfiguration with minimal structure enforcement. If influenced by adversarial input, it could remove unrelated protections, insert unsafe env values, or corrupt the agent's operating configuration.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill declares broad file read/write behavior over sensitive local configuration files but does not define any explicit tool scope or permission boundaries. In a config-admin skill that can modify agent and provider settings, missing scope increases the chance of overbroad access, unintended writes, or abuse through prompt-driven actions.

Session Persistence

Medium
Category
Rogue Agent
Content
- Follow this skill and the existing script capabilities exactly.
- Do not manually edit config files to bypass script limitations.
- If the request is outside current script support, say so clearly and explain what is missing.
- Before every write, create a backup in the same directory as the original file.
- Perform backup and write through the bundled script, not manual editing.
- Do not echo secrets such as `apiKey`, `OPENAI_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, tokens, or refresh tokens in replies.
Confidence
78% confidence
Finding
Mandatory backup creation introduces additional persistent copies of sensitive configuration files in-place, potentially including API keys, auth tokens, and provider endpoints. Those backup artifacts can expand the secret exposure surface, survive later cleanup, and be read by other tools or users depending on filesystem permissions.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The `replace-auth-from-stdin` path accepts JSON from stdin and overwrites the auth file, which can contain sensitive authentication material such as API keys or tokens. Although the code validates and writes the data, there is no confirmation prompt, log/print disclosure, or inline comment/docstring warning users that credential data will be stored or replaced.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
This code creates parent directories, makes a backup copy, and overwrites the target configuration file, but provides no confirmation prompt, user-facing print/log message, or explanatory comment/docstring around these file modifications. For a code file, safety-relevant file writes should have some visible disclosure unless clearly documented elsewhere, which is not evident in this file.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The function stores a provided API key into the provider configuration, which is credential handling and persistence of sensitive data, but there is no confirmation, user-facing warning, or explanatory comment/docstring in the code. The same pattern is exposed through CLI commands, so users may not be clearly informed that secrets will be written to disk.

Static analysis

No suspicious patterns detected.