Back to skill

Security audit

Fal.ai API

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent fal.ai API helper, but users should treat its fal.ai key carefully because the implementation has some credential-handling weaknesses.

Install only if you are comfortable giving this skill a fal.ai API key that may incur usage charges. Prefer FAL_KEY or a protected config entry over --api-key, rotate any key previously passed on a command line, and consider restricting use to trusted model endpoints until redirect and endpoint validation are tightened.

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
fal_api.py:85
Finding

API Credential May Be Disclosed Through Cross-Origin HTTP Redirects

Content
View full analysis

Vulnerability Details

File Location: fal_api.py, lines 60–65 and 85–99
Vulnerability Type: Unrestricted forwarding of an authorization header during automatic redirects
Risk Level: Medium

Vulnerable Code:

python
self.api_key = api_key
self.headers = {
    "Authorization": f"Key {self.api_key}",
    "Content-Type": "application/json",
    "Accept": "application/json",
    "User-Agent": "Mozilla/5.0 (compatible; Klawf/1.0; +https://clawdhub.com/agmmnn/fal-api)"
}
python
def _request(self, method: str, url: str, data: dict = None) -> dict:
    """Make HTTP request to fal.ai API."""
    req = urllib.request.Request(url, method=method)
    for k, v in self.headers.items():
        if method == "GET" and k.lower() == "content-type":
            continue
        req.add_header(k, v)

    if data:
        req.data = json.dumps(data).encode()

    with urllib.request.urlopen(req, timeout=120) as response:
        return json.loads(response.read().decode())

Technical Analysis

The client attaches the FAL_KEY authorization credential to every request and uses urllib.request.urlopen, which automatically processes HTTP redirects. The implementation does not validate redirect destinations, restrict redirects to the original queue.fal.run origin, or explicitly remove the Authorization header when the origin changes.

Consequently, if a credential-bearing endpoint returns a redirect to a different origin and the authorization header is retained by the runtime redirect flow, the API key can be sent to that destination. The public API methods also accept arbitrary model path strings rather than limiting requests to the declared MODELS allowlist, increasing the number of server-side paths that can be requested.

Sending the API key to fal.ai is necessary for the Skill's declared functionality. The security issue is the lack of an origin boundary around subsequent redire ...[truncated 1205 chars]

Remediation
View remediation

Remediation Suggestions

  • Disable automatic redirects for authenticated requests, or implement a custom HTTPRedirectHandler.
  • Permit redirects only when the normalized destination uses HTTPS and its hostname is exactly queue.fal.run.
  • Never forward Authorization when the scheme, hostname, or port changes.
  • Validate the final URL before every credential-bearing request rather than validating only the initial URL.
  • Restrict model to keys or endpoint values in the declared MODELS allowlist unless arbitrary endpoints are explicitly required.
  • Validate request_id and endpoint components against conservative character allowlists before URL construction.
  • Consider using Request.add_unredirected_header for credentials in conjunction with explicit redirect controls.
  • Add tests covering cross-origin, scheme-changing, protocol-relative, and malformed redirects.

T09 · Insecure Skill Coding Practices

Note
Location
fal_api.py:263
Finding

API Key Accepted Through a Process Command-Line Argument

Content
View full analysis

Vulnerability Details

File Location: fal_api.py, lines 263–276
Vulnerability Type: Sensitive credential exposure through process arguments and shell history
Risk Level: Low

Vulnerable Code:

python
parser.add_argument("--api-key", help="FAL_KEY (or set via environment)")

args = parser.parse_args()

if args.list_models:
    print("Available models:")
    for name, endpoint in FalAPI.MODELS.items():
        print(f"  {name:20} → {endpoint}")
    return

if not args.prompt:
    parser.error("--prompt is required unless --list-models is set")

api = FalAPI(api_key=args.api_key)

Technical Analysis

The command-line interface permits users to provide FAL_KEY through --api-key. Command-line arguments are commonly exposed through shell history, process-inspection interfaces, job-control systems, diagnostic captures, audit systems, and CI/CD logs.

The Skill already supports loading the credential from FAL_KEY or protected configuration, so accepting the secret as a command-line argument is not necessary for its declared functionality and unnecessarily expands the credential's exposure surface.

Attack Path

  1. A user runs the Skill with a command such as python3 fal_api.py --api-key SECRET ....
  2. The complete command is retained in shell history, automation logs, or process metadata.
  3. A local user, administrator, monitoring service, or party with access to those logs reads the argument.
  4. The recovered key is reused to make unauthorized fal.ai API requests.

This path requires access to process information, command history, or logs on the system where the Skill runs.

Impact Assessment

An exposed key could allow unauthorized use of the fal.ai account within the credential's assigned privileges, potentially causing quota consumption and financial charges. The flaw does not itself elevate local privileges; its scope is limited to credential disclosure and the remo ...[truncated 44 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove the --api-key command-line option.
  • Continue supporting FAL_KEY and a protected configuration source.
  • If interactive entry is required, use getpass.getpass() so the secret is not echoed.
  • Ensure credential configuration files are readable only by the owning user.
  • Redact secrets from application, CI/CD, and exception logs.
  • Document credential rotation and advise users to rotate any key previously passed through command-line arguments.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (3)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill requires access to an API key in the environment and describes networked and shell-driven usage, but it does not declare an explicit tool scope such as permissions or allowed-tools. This weakens containment by leaving runtime capabilities broader or less auditable than necessary, increasing the chance of unintended command execution, unrestricted outbound requests, or secret exposure if the implementation is compromised.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill executes a local subprocess to access host configuration, expanding its capabilities beyond remote media generation into local system interaction. In agent environments, unnecessary subprocess access increases risk because it can expose local secrets/configuration and creates a foothold for future abuse if the surrounding toolchain or command resolution is compromised.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · fal_api.py (reported line 79)May include surrounding context.

python
"""Get config from clawdbot config if available."""
        try:
            import subprocess
            result = subprocess.run(
                ["clawdbot", "config", "get", f"skill.fal_api.{key}"],
                capture_output=True, text=True
            )

Static analysis

No suspicious patterns detected.