Back to skill

Security audit

Forge AI Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a real Forge AI client, but it needs Review because it handles credentials and account-changing API actions with weak credential storage and disclosure.

Review before installing or using. Use this only for a Forge account you trust with the content you send, avoid typing real passwords directly in shell commands where history or process listings may capture them, and keep .forgeai/session.json out of shared folders, commits, and backups. The artifact does not show deception or destructive local behavior, but its credential handling should be hardened.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Warning
Location
forge_client.py:101
Finding

Forge password exposed through command-line arguments

Content
View full analysis
') email, password = args[0], args[1] data = api_request('auth', 'login', {'email': email, 'password': password}, require_auth=False) save_session({'user': data['user'], 'token': data['token']}) ``` The documented command reinforces this behavior: ```text forge_client.py login ``` ### Technical Analysis The login password is accepted as a positional command-line argument. Although transmitting the credentials to the declared Forge HTTPS authentication endpoint is necessary for login, putting the password in the process argument vector is not necessary. Depending on the operating system and local configuration, command-line arguments may be visible through process-monitoring interfaces or utilities while the command is running. The command may also be retained in interactive shell history, terminal logs, audit logs, automation logs, or diagnostic output. This behavior exceeds the minimum privilege and data-exposure requirements of the authentication feature because the password can be collected interactively without placing it in the argument vector. ### Attack Path 1. A user follows the documented command and runs `forge_client.py login user@example.com plaintext-password`. 2. The plaintext password is placed in the process argument vector and may also be recorded in shell history. 3. A local user or monitoring process with permission to inspect command lines reads the argument while the login process is active, or an attacker later obtains the user's history or automation logs. 4. The attacker uses the recovered credentials ...[truncated 555 chars]
Remediation
View remediation
') email = args[0] password = getpass.getpass('Forge password: ') data = api_request( 'auth', 'login', {'email': email, 'password': password}, require_auth=False, ) save_session({'user': data['user'], 'token': data['token']}) ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
forge_client.py:77
Finding

Bearer token stored without enforced owner-only permissions

Content
View full analysis
`. 6. The attacker acts with the Forge permissions associated with the victim's session until the token expires or is revoked. This path requires local filesystem access and permissions sufficient to read the insecurely created file. ### Impact Assessment A stolen bearer token may permit account impersonation without obtai ...[truncated 301 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
publish.sh:9
Finding

Publishing script installs an unpinned npm package globally

Content
View full analysis
/dev/null; then echo "Installing clawhub CLI..." npm install -g clawhub fi ``` ### Technical Analysis When `clawhub` is unavailable, the publishing script automatically installs the mutable latest version of the `clawhub` npm package. No exact version or integrity value is specified. An npm installation can execute package lifecycle scripts with the privileges of the user running `publish.sh`. The global `-g` installation also changes the host environment outside the project and may require elevated privileges on some systems. Consequently, compromise of the package, its dependency graph, or the package resolution channel could result in arbitrary code execution. This installation is not required during normal execution of the Forge API client and exceeds the minimum scope necessary for publishing: the script could instead require a separately reviewed tool or use a project-local, version-locked dependency. ### Attack Path 1. A publisher runs `publish.sh` on a system where `clawhub` is not already available. 2. The script automatically executes `npm install -g clawhub`. 3. npm resolves the current package release and its transitive dependencies rather than a reviewed exact version. 4. A compromised or unexpectedly changed package or dependency executes malicious lifecycle code during installation. 5. That code runs with the operating-system privileges of the publishing user. 6. If the script is run from a privileged account, the package code inherits those elevated privileges and may modify the wider system. The audit found no evidence that the current package is malicious; the vulnerability is the unsafe, mutable supply-chain installation mechanism. ### Impact Assessment Exploitation could permit arbitrary code execution as the user inv ...[truncated 311 chars]
Remediation
View remediation
/dev/null; then echo "Error: the reviewed ClawHub CLI version is not installed." >&2 exit 1 fi EXPECTED_VERSION="1.2.3" ACTUAL_VERSION="$(clawhub --version)" if [[ "$ACTUAL_VERSION" != "$EXPECTED_VERSION" ]]; then echo "Error: expected clawhub $EXPECTED_VERSION, found $ACTUAL_VERSION." >&2 exit 1 fi ``` ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documented behavior omits important actions including file upload, persistent local storage of session and content metadata, and the fact that the '/forge-only' trigger rule is not enforced by code. This is dangerous because users may disclose credentials and sensitive content or trigger remote actions under false assumptions about when the skill runs and what data it stores or transmits.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented behavior omits important actions including file upload, persistent local storage of session and content metadata, and the fact that the '/forge-only' trigger rule is not enforced by code. This is dangerous because users may disclose credentials and sensitive content or trigger remote actions under false assumptions about when the skill runs and what data it stores or transmits.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill advertises network, file read, and file write behavior through its documented commands and state files, but it does not declare any tool scope or permission boundaries. This increases the chance of overbroad execution and weak review, because operators and users cannot clearly see what capabilities the skill requires before use.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger keywords include broad terms like 'forge' and 'forge-ai', which can cause unintended invocation outside an explicit '/forge' command context. In a skill that handles authentication, local state, uploads, and remote API actions, accidental activation materially raises the risk of unintended data access or transmission.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill asks for login credentials and sends article, evaluation, and upload content to a remote API, but the description does not explicitly warn users that secrets and content will be transmitted and locally persisted. This undermines informed consent and can lead to accidental exposure of passwords, tokens, proprietary text, or uploaded files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The session token is written in plaintext to a predictable file under the current working directory (.forgeai/session.json) with no permission hardening or secure storage mechanism. On multi-user systems or in shared/project directories, other local users, backup systems, or accidental commits could expose the bearer token and allow account compromise.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code accepts an email and password on the command line and sends them in an HTTP request to a remote API, but there is no user-facing warning, comment, or docstring disclosure about transmitting credentials. The usage text shows the syntax only, which does not meaningfully warn about the sensitivity of passing secrets or that they are being sent off-host.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · forge_client.py (reported line 111)May include surrounding context.

python
if len(args) < 2:
        die('Usage: forge_client.py login <email> <password>')
    email, password = args[0], args[1]
    data = api_request('auth', 'login', {'email': email, 'password': password}, require_auth=False)
    save_session({'user': data['user'], 'token': data['token']})
    user = data['user']
    print(f'Logged in as {user.get("email")} ({user.get("nickname")}) [{user.get("role")}]')

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · forge_client.py (reported line 230)May include surrounding context.

python
if len(args) < 2:
        die('Usage: forge_client.py login <email> <password>')
    email, password = args[0], args[1]
    data = api_request('auth', 'login', {'email': email, 'password': password}, require_auth=False)
    save_session({'user': data['user'], 'token': data['token']})
    user = data['user']
    print(f'Logged in as {user.get("email")} ({user.get("nickname")}) [{user.get("role")}]')

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · forge_client.py (reported line 111)May include surrounding context.

python
if len(args) < 2:
        die('Usage: forge_client.py login <email> <password>')
    email, password = args[0], args[1]
    data = api_request('auth', 'login', {'email': email, 'password': password}, require_auth=False)
    save_session({'user': data['user'], 'token': data['token']})
    user = data['user']
    print(f'Logged in as {user.get("email")} ({user.get("nickname")}) [{user.get("role")}]')

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · forge_client.py (reported line 230)May include surrounding context.

python
if len(args) < 2:
        die('Usage: forge_client.py login <email> <password>')
    email, password = args[0], args[1]
    data = api_request('auth', 'login', {'email': email, 'password': password}, require_auth=False)
    save_session({'user': data['user'], 'token': data['token']})
    user = data['user']
    print(f'Logged in as {user.get("email")} ({user.get("nickname")}) [{user.get("role")}]')

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The evaluation example uses Chinese dimension keys (准确性, 推理能力) with no indication that users may choose their own language or that the locale is region-specific. This can be read as prescribing a specific language format without user opt-in.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.