Back to skill

Security audit

Auto Authenticator Local

Security checks for vulnerabilities and agentic risk

Overview

This local TOTP helper is coherent in purpose, but its install and seed-entry paths create review-worthy risk for MFA secrets and local files.

Review before installing. Prefer a pinned, inspectable release or manual install instead of curl | bash, avoid entering real TOTP seeds on the command line, and do not set OPENCLAW_SKILL_DIR to any directory containing valuable files. The core local-authenticator idea is not itself malicious, but the current packaging and seed-entry design need care.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
README.md:51
Finding
Unverified Remote Installer Is Executed Directly by Bash<![CDATA[ ## Vulnerability Details **File Location**: `README.md:51-55` **Vulnerability Type**: Remote payload retrieval and immediate execution **Risk Level**: Critical ### Vulnerable Code ```markdown One-line install: ```bash curl -fsSL https://raw.githubusercontent.com/LucasZH7/auto-authenticator-local/main/install.sh | bash ``` ``` ### Technical Analysis The documented installation command retrieves `install.sh` from the mutable `main` branch of a personal GitHub repository and pipes the response directly into Bash. The content is executed without an opportunity for inspection and without validating a version, commit digest, checksum, or cryptographic signature. Although the bundled copy of `install.sh` contains no overt malicious payload, the command does not guarantee that users receive the audited copy. The effective payload can change at any time after review. Compromise of the repository owner, GitHub repository, branch, or delivery path could therefore turn the installation command into an arbitrary-code execution mechanism. This behavior is not necessary for the declared local TOTP functionality. A versioned, verified installation process can provide the same functionality with substantially less risk. ### Attack Path 1. An attacker compromises the repository account or otherwise gains permission to modify `main/install.sh`. 2. The attacker replaces the installer with a payload that steals credentials, modifies Skills, or establishes persistence. 3. A user follows the one-line command in the README. 4. `curl` retrieves the attacker's current payload. 5. Bash executes it immediately with all permissions available to the invoking user. ### Impact Assessment Successful exploitation provides arbitrary code execution in the invoking user's security context. The payload could read user-accessible files, alter OpenClaw Skills, access locally available credentials subject to operating-system controls, install persistence, or transmit sensitive da ...[truncated 103 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the `curl | bash` installation instruction. - Publish immutable, versioned releases rather than installing from `main`. - Instruct users to download the installer as a separate file, verify its checksum or cryptographic signature, inspect it, and only then execute it. - Pin the download URL to a release artifact or immutable commit. - Publish expected SHA-256 checksums through a separately protected release channel. - Do not recommend elevated execution. ]]>

T08 · Insecure Dependencies

Error
Location
install.sh:4
Finding
Installation Uses Mutable Repository State and Unpinned Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:4,21-29`; `requirements.txt:1` **Vulnerability Type**: Unsafe software supply-chain configuration **Risk Level**: High ### Vulnerable Code ```bash REPO_URL="https://github.com/LucasZH7/auto-authenticator-local.git" ``` ```bash if [ -d "$TARGET_DIR/.git" ]; then echo "Existing installation detected. Pulling latest changes..." git -C "$TARGET_DIR" pull --ff-only else rm -rf "$TARGET_DIR" git clone "$REPO_URL" "$TARGET_DIR" fi python3 -m pip install -r "$TARGET_DIR/requirements.txt" ``` ```text keyring>=25.0.0 ``` ### Technical Analysis The installer clones the repository's default branch or updates an existing checkout with `git pull --ff-only`. It does not check out an immutable reviewed commit, verify a signed tag, or validate repository content against a known digest. The dependency declaration accepts any `keyring` release at or above version 25.0.0. No upper bound, exact version, lockfile, or package hash is provided. Pip may consequently install future versions and transitive dependencies that were not covered by this audit. Python packages can execute code during installation or when imported by the Skill. The reviewed dependency name does not exhibit obvious typosquatting or dependency-confusion indicators. The vulnerability is the lack of reproducibility and integrity controls, not evidence that the current `keyring` package is malicious. ### Attack Path 1. An attacker compromises the upstream repository, dependency publication account, or a permitted transitive package. 2. The attacker publishes altered repository content or a package version satisfying `keyring>=25.0.0`. 3. A user runs the installer. 4. Git retrieves mutable repository state, or pip resolves the attacker-controlled package version. 5. Malicious code executes during package installation, import, or later Skill invocation. ### Impact Assessment A compromised repository or dependency can execute arbitr ...[truncated 334 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Install from a versioned release pinned to an immutable commit digest. - Verify signed Git tags or release signatures before installation. - Replace version ranges with exact dependency and transitive-dependency versions. - Generate a lockfile and require hashes, such as with pip's `--require-hashes`. - Install dependencies into a dedicated virtual environment instead of the user's global Python environment. - Add automated dependency review and controlled update procedures. - Re-audit dependencies and repository changes before updating pinned versions. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/totp_add.py:13
Finding
TOTP Seeds Are Exposed Through Process Arguments and Shell History<![CDATA[ ## Vulnerability Details **File Location**: `README.md:65-69`; `install.sh:34-35`; `scripts/totp_add.py:13-23`; `scripts/secret_store.py:51-70` **Vulnerability Type**: Sensitive credential exposure through command-line arguments **Risk Level**: High ### Vulnerable Code ```markdown Store a seed: ```bash python3 scripts/totp_add.py --alias github-work --issuer GitHub --account lucas@example.com --seed JBSWY3DPEHPK3PXP ``` ``` ```bash echo "Try:" echo " python3 \"$TARGET_DIR/scripts/totp_add.py\" --alias github-work --issuer GitHub --account you@example.com --seed JBSWY3DPEHPK3PXP" ``` ```python def main() -> int: parser = argparse.ArgumentParser(description="Store a TOTP seed in macOS Keychain.") parser.add_argument("--alias", required=True, help="Short local alias for the account.") parser.add_argument("--seed", required=True, help="Base32 TOTP seed.") parser.add_argument("--issuer", default="", help="Optional issuer label.") parser.add_argument("--account", default="", help="Optional account label.") args = parser.parse_args() try: seed = normalize_seed(args.seed) backend = store_seed(args.alias, seed, issuer=args.issuer, account=args.account) ``` The macOS fallback also places the secret in the `security` process argument vector: ```python def _store_with_macos_security(alias: str, seed: str, issuer: str = "", account: str = "") -> None: label = f"{issuer} {account}".strip() or alias subprocess.run( [ "security", "add-generic-password", "-U", "-a", alias, "-s", KEYCHAIN_SERVICE, "-l", label, "-w", seed, ], check=True, capture_output=True, text=True, ) ``` ### Technical Analysis The only supported interface for adding a seed requires `--seed` on the command line. Shells commonly retain commands in history, and proce ...[truncated 1514 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the required `--seed` argument. - Read the seed from an interactive no-echo prompt using Python's `getpass`. - For noninteractive workflows, accept the secret through a protected file descriptor or standard input only after clearly documenting the residual exposure risks. - Ensure the secret is never included in success messages, error messages, logs, or telemetry. - Change README and installer examples so they do not encourage command-line secret entry. - For the macOS fallback, use a supported input mechanism that does not place the seed in the process argument vector. - Document incident response: users who previously entered real seeds through command-line arguments should clear relevant history and rotate those TOTP seeds. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
install.sh:5
Finding
Installer Recursively Deletes a Caller-Controlled Destination<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:5,19-27` **Vulnerability Type**: Unsafe recursive deletion using an environment-controlled path **Risk Level**: High ### Vulnerable Code ```bash TARGET_DIR="${OPENCLAW_SKILL_DIR:-$HOME/.openclaw/skills/auto-authenticator-local}" ``` ```bash mkdir -p "$(dirname "$TARGET_DIR")" if [ -d "$TARGET_DIR/.git" ]; then echo "Existing installation detected. Pulling latest changes..." git -C "$TARGET_DIR" pull --ff-only else rm -rf "$TARGET_DIR" git clone "$REPO_URL" "$TARGET_DIR" fi ``` ### Technical Analysis `OPENCLAW_SKILL_DIR` completely controls `TARGET_DIR`. If the destination does not contain a `.git` directory, the installer recursively deletes it without confirming that it is a dedicated Skill directory. The script does not canonicalize the path, reject dangerous destinations, check whether the target is empty, verify ownership, create a backup, or ask for confirmation. A typographical error or attacker-influenced environment variable can therefore direct `rm -rf` at an unrelated user-writable directory. The recursive deletion is unnecessary. A least-destructive installer should abort when a destination already exists unless it has positively identified a safe installation that can be updated. ### Attack Path 1. `OPENCLAW_SKILL_DIR` is accidentally or maliciously set to an existing valuable directory. 2. The selected directory does not have a `.git` child. 3. The user executes the installer. 4. The `else` branch invokes `rm -rf "$TARGET_DIR"`. 5. All contents accessible to the invoking user under that path are deleted. 6. Git then attempts to clone the repository into the now-removed location. ### Impact Assessment Exploitation or accidental triggering can destroy arbitrary files and directories writable by the invoking user. If the installer is run with elevated privileges, system-wide data may also be affected. The issue provides destructive capability rather than direct code ...[truncated 39 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Never recursively delete a pre-existing destination as part of normal installation. - Abort if the target exists and is not a positively identified installation of this Skill. - Canonicalize the target path and require it to be a dedicated child of the expected OpenClaw Skills directory. - Explicitly reject empty paths, `/`, the user's home directory, the Skills root, and paths containing unsafe traversal or symlink behavior. - Validate ownership and symlink status before modifying the destination. - If replacement is necessary, require explicit interactive confirmation and create a recoverable backup. - Prefer installing into a newly created versioned directory and switching an atomic link only after successful verification. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (57)

Chaining Abuse

High
Category
Tool Misuse
Content
One-line install:

```bash
curl -fsSL https://raw.githubusercontent.com/LucasZH7/auto-authenticator-local/main/install.sh | bash
```

This installer clones the repository into `~/.openclaw/skills/auto-authenticator-local` by default and installs Python dependencies locally for the tool.
Confidence
97% confidence
Finding
The `| bash` construct turns a remote content fetch into immediate shell execution, which is a high-risk chaining pattern because any compromise of the fetched content becomes instant arbitrary command execution. In the context of a local authenticator handling MFA seeds, successful exploitation could expose stored secrets or subvert authentication workflows, making the risk more severe than for a generic utility.

Credential Access

High
Category
Privilege Escalation
Content
import platform
import subprocess

from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
import platform
import subprocess

from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
import platform
import subprocess

from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
import platform
import subprocess

from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
import platform
import subprocess

from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
import platform
import subprocess

from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
import platform
import subprocess

from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
import platform
import subprocess

from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
from totp_common import KEYCHAIN_SERVICE

try:
    import keyring
    from keyring.errors import KeyringError
except Exception:  # pragma: no cover - exercised through backend selection
    keyring = None
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Static analysis

No suspicious patterns detected.