Back to skill

Security audit

SQL Memory

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a disclosed SQL-backed memory tool, but it exposes broad database escape hatches and configuration behavior that users should review before installing.

Install only if you are comfortable giving this skill access to a dedicated, least-privileged SQL database. Avoid using production or shared credentials, pin and verify sql-connector, control the exact .env path, and do not expose the raw SQL methods or bundled cron guidance to agents unless you have reviewed and restricted those workflows.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
Findings (6)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
sql-memory/sql_memory.py:286
Finding

Task Queue Operations Lack Ownership and State Authorization

Content
View full analysis
bool: """Mark a task as processing.""" return self._db.execute(""" UPDATE memory.TaskQueue SET status='processing', started_at=%s WHERE id=%s """, (datetime.now(timezone.utc), int(task_id))) def complete_task(self, task_id: Any, result: str = '') -> bool: """Mark a task as completed.""" ok = self._db.execute(""" UPDATE memory.TaskQueue SET status='completed', completed_at=%s, error_log=%s WHERE id=%s """, (datetime.now(timezone.utc), result[:500], int(task_id))) _log.info(f"complete_task({task_id})") return ok def fail_task(self, task_id: Any, error: str, retry_count: int = 0, max_retries: int = 3) -> bool: """Fail or re-queue a task based on retry count.""" new_status = 'pending' if retry_count < max_retries else 'failed' ok = self._db.execute(""" UPDATE memory.TaskQueue SET status=%s, retry_count=retry_count+1, error_log=%s WHERE id=%s """, (new_status, error[:800], int(task_id))) _log.info(f"fail_task({task_id}) → {new_status}") return ok ``` ### Technical Analysis The task mutation methods authorize operations solely by task ID. They do not verify that the caller is the task's assigned agent, that the task belongs to an authorized tenant or session, or that its current state permits the requested transition. For example, `claim_task()` does not require `status='pending'`. Two agents can therefore claim the same task, and an agent can reclaim an already completed or processing task. Similarly, `complete_task()` and `fail_task()` can modify any task whose ID is known or guessed. The methods also return only the connector's Boolean result and do not ver ...[truncated 1413 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
sql-memory/sql_memory.py:120
Finding

Public Raw SQL Compatibility Methods Bypass Parameterization

Content
View full analysis
bool: """ Legacy passthrough for raw SQL. Returns bool (v2) instead of stdout string (v1). Callers that checked 'error' in result.lower() should switch to checking False. NOTE: Raw SQL here bypasses parameterisation — migrate to mem.* methods for new code. """ return self._db.execute(query) def execute_scalar(self, query: str) -> Optional[Any]: """Execute query and return first value. Parameterised via scalar().""" return self._db.scalar(query) def execute_via_file(self, query: str, timeout: int = 30) -> bool: """v1.x large-payload workaround — now just delegates to execute() since pymssql has no arg-length limit.""" return self._db.execute(query) def execute_rows(self, query: str) -> List[str]: """Execute query and return rows as list of strings (v1.x compat).""" rows = self._db.query(query) return [str(list(r.values())) for r in rows] ``` ### Technical Analysis These public methods accept complete SQL strings and send them directly to the connector. They provide no parameter argument, statement allowlist, operation restriction, or separation between data and SQL syntax. Although the higher-level memory methods generally use parameterized queries, these compatibility methods provide a direct escape hatch. Any caller that constructs a query from agent output, task payloads, user input, or retrieved memory can introduce SQL injection. This also contradicts documentation stating that all SQL is parameterized and that SQL injection is structurally impossible. The effective privileges are those of the configured SQL account, not merely those needed for memory CRUD operations. ### Attack Path 1. An application or agent uses `execute()`, `exec ...[truncated 1086 chars]
Remediation
View remediation
bool: return self._db.execute(query, params) ``` - Reject multiple statements, comments, DDL, DCL, and dangerous stored procedures in any compatibility layer. - Prefer narrowly scoped methods for every supported operation. - Use a SQL account restricted to the required `memory` tables and operations. - Do not grant schema ownership, server administration, or access to unrelated databases to the runtime account. - Mark the legacy API as deprecated and fail closed unless an explicit configuration flag enables it. - Add tests demonstrating that untrusted values cannot alter SQL syntax. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
sql-memory/sql_memory.py:40
Finding

Automatic Parent-Directory Environment Discovery Can Redirect Sensitive Data

Content
View full analysis
Optional[str]: p = _pathlib.Path(os.path.abspath(__file__)).parent for _ in range(5): c = p / '.env' if c.exists(): return str(c) p = p.parent return None try: from dotenv import load_dotenv _env = _find_env() if _env: load_dotenv(_env, override=True) except ImportError: _env = _find_env() if _env: with open(_env) as f: for line in f: line = line.strip() if line and not line.startswith('#') and '=' in line: k, v = line.split('=', 1) os.environ[k.strip()] = v.strip().strip('"').strip("'") ``` ### Technical Analysis Importing the module automatically searches up to five parent directories for a `.env` file. When `python-dotenv` is installed, the discovered values are loaded with `override=True`, replacing environment variables that may have been deliberately supplied by a trusted process supervisor. This creates two trust-boundary problems: 1. The Skill can silently consume unrelated secrets from a workspace-level or parent-level `.env`. 2. An attacker who can write a searched parent directory can create a `.env` that changes SQL server, database, username, or password settings. Because the Skill stores memories, task payloads, activity data, and session context in the configured backend, changing the SQL destination can redirect sensitive agent data to an attacker-controlled server. The fallback parser does not explicitly use `override=True`, but direct assignments to `os.environ` have the same overriding effect. ### Attack Path 1. An attacker obtains write access to a parent directory searched by `_find_env()`. 2. The attacker c ...[truncated 997 chars]
Remediation
View remediation

T07 · Tool Hijacking and Spoofing

Warning
Location
sql-memory/sql_memory.py:72
Finding

Relative Search Paths Permit SQL Connector Module Hijacking

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
openclaw.skill.json:23
Finding

Security-Critical SQL Connector Dependency Is Not Reproducibly Pinned

Content
View full analysis
=2.0.0" } ``` The installation guide also instructs users to retrieve the dependency without specifying a reviewed version: ```bash clawhub install sql-connector clawhub install sql-memory ``` ### Technical Analysis The connector is a security-critical dependency responsible for processing SQL credentials and transporting persistent agent data. The lower-bound constraint `>=2.0.0` permits any later compatible or incompatible release to be selected. No integrity digest, exact version, signed artifact requirement, or verified source revision is declared. As a result, the code reviewed with this Skill may not be the code executed after installation. A compromised registry account, malicious future release, dependency-name takeover, or accidental incompatible update could change credential handling and network behavior. No evidence shows that the currently referenced dependency is malicious. The vulnerability is the lack of reproducible and integrity-verified dependency resolution. ### Attack Path 1. A malicious or compromised release of `sql-connector` is published under a version accepted by `>=2.0.0`. 2. A user follows the documented `clawhub install sql-connector` command. 3. The package manager resolves the new release rather than the version audited with SQL Memory. 4. The connector executes in the agent process and reads SQL configuration. 5. Malicious connector code steals credentials, redirects database traffic, modifies queries, or returns forged memory data. ### Impact Assessment A compromised connector can obtain all privileges available to the OpenClaw process and configured SQL account. Potential scope includes: - Theft of SQL usernames and passwords. - Disclosure or alteration of memories, ...[truncated 245 chars]
Remediation
View remediation

T06 · System Persistence

Warning
Location
knowledge-base/INFRASTRUCTURE.md:253
Finding

Bundled Deployment Instructions Encourage Persistent Execution of Unreviewed Components

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (48)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

A description-behavior mismatch is dangerous because agents and reviewers may trust the documented purpose while the implementation exposes additional capabilities such as raw SQL passthrough, schema changes, or other out-of-scope operations. That gap can enable misuse, privilege expansion, or destructive database actions under the guise of a benign memory API.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

A description-behavior mismatch is dangerous because agents and reviewers may trust the documented purpose while the implementation exposes additional capabilities such as raw SQL passthrough, schema changes, or other out-of-scope operations. That gap can enable misuse, privilege expansion, or destructive database actions under the guise of a benign memory API.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

A description-behavior mismatch is dangerous because agents and reviewers may trust the documented purpose while the implementation exposes additional capabilities such as raw SQL passthrough, schema changes, or other out-of-scope operations. That gap can enable misuse, privilege expansion, or destructive database actions under the guise of a benign memory API.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
84% confidence
Finding

Automatically walking up multiple directory levels to discover .env files broadens the secret trust boundary and can cause the skill to ingest credentials from unintended parent workspaces. In multi-project, shared, or agent-controlled directories, this can expose unrelated secrets to the skill or lead it to operate with the wrong database credentials.

Content

Scanner excerpt · SKILL_REFERENCE.md (reported line 759)May include surrounding context.

mem = get_memory('staging') # reads SQL_STAGING_* from .env

text

### .env Location Discovery

The module auto-discovers `.env` by walking up to 5 directory levels from the script's location. It will find `.env` at your workspace root as long as sql-memory is installed within your workspace directory tree.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation asserts SQL injection is structurally impossible because queries are parameterized and sealed, yet later advertises legacy raw SQL execution methods. In practice, exposing any raw SQL execution channel invalidates the 'structurally impossible' claim and can let downstream callers reintroduce injection or unsafe query construction.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

A high-level memory/task/audit abstraction should not expose generic raw SQL execution because it bypasses the safety and policy boundaries the abstraction is meant to provide. This creates a direct path to alter arbitrary tables, exfiltrate data, or defeat intended controls such as soft deletes, immutability, and schema scoping.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · knowledge-base/INFRASTRUCTURE.md (reported line 361)May include surrounding context.

md
pip install -r requirements.txt

# 3. Configure .env
cp .env.example .env
# Edit .env with cloud DB credentials

# 4. Run tests

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · openclaw.skill.json (reported line 33)May include surrounding context.

json
},
  "skill": {
    "entrypoint": "sql-memory/sql_memory.py",
    "config_file": ".env",
    "setup_script": "setup_schema.py",
    "skill_file": "SKILL.md"
  },

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · GETTING_STARTED.md (reported line 87)May include surrounding context.

md
python3 setup_schema.py              # uses 'local' profile
    python3 setup_schema.py --cloud      # uses 'cloud' profile

Requires .env with SQL credentials. See README.md for format.
"""
import argparse
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · GETTING_STARTED.md (reported line 151)May include surrounding context.

md
python3 setup_schema.py              # uses 'local' profile
    python3 setup_schema.py --cloud      # uses 'cloud' profile

Requires .env with SQL credentials. See README.md for format.
"""
import argparse
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 130)May include surrounding context.

md
python3 setup_schema.py              # uses 'local' profile
    python3 setup_schema.py --cloud      # uses 'cloud' profile

Requires .env with SQL credentials. See README.md for format.
"""
import argparse
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL_REFERENCE.md (reported line 756)May include surrounding context.

md
python3 setup_schema.py              # uses 'local' profile
    python3 setup_schema.py --cloud      # uses 'cloud' profile

Requires .env with SQL credentials. See README.md for format.
"""
import argparse
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · knowledge-base/INFRASTRUCTURE.md (reported line 360)May include surrounding context.

md
python3 setup_schema.py              # uses 'local' profile
    python3 setup_schema.py --cloud      # uses 'cloud' profile

Requires .env with SQL credentials. See README.md for format.
"""
import argparse
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · knowledge-base/INFRASTRUCTURE.md (reported line 362)May include surrounding context.

md
python3 setup_schema.py              # uses 'local' profile
    python3 setup_schema.py --cloud      # uses 'cloud' profile

Requires .env with SQL credentials. See README.md for format.
"""
import argparse
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · setup_schema.py (reported line 8)May include surrounding context.

python
python3 setup_schema.py              # uses 'local' profile
    python3 setup_schema.py --cloud      # uses 'cloud' profile

Requires .env with SQL credentials. See README.md for format.
"""
import argparse
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · setup_schema.py (reported line 132)May include surrounding context.

python
python3 setup_schema.py              # uses 'local' profile
    python3 setup_schema.py --cloud      # uses 'cloud' profile

Requires .env with SQL credentials. See README.md for format.
"""
import argparse
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · setup_schema.py (reported line 154)May include surrounding context.

python
python3 setup_schema.py              # uses 'local' profile
    python3 setup_schema.py --cloud      # uses 'cloud' profile

Requires .env with SQL credentials. See README.md for format.
"""
import argparse
import sys

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · sql-memory/sql_memory.py (reported line 40)May include surrounding context.

python
python3 setup_schema.py              # uses 'local' profile
    python3 setup_schema.py --cloud      # uses 'cloud' profile

Requires .env with SQL credentials. See README.md for format.
"""
import argparse
import sys

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module header broadly states that queries are parameterized throughout, but the preserved legacy execution path allows non-parameterized arbitrary SQL. Security claims in the header can mislead integrators into granting broader trust to this skill, increasing the chance of misuse and policy bypass.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · sql-memory/sql_memory.py (reported line 46)May include surrounding context.

python
def _find_env() -> Optional[str]:
    p = _pathlib.Path(os.path.abspath(__file__)).parent
    for _ in range(5):
        c = p / '.env'
        if c.exists():
            return str(c)
        p = p.parent

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The docstring claims the wrapper uses parameterized queries and no string interpolation, but the class also exposes raw SQL execution methods that bypass those protections. This mismatch is dangerous because downstream developers, agents, or reviewers may trust the safety claims and use the interface in higher-risk contexts than warranted.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The legacy execute, execute_scalar, execute_rows, and execute_via_file paths accept raw SQL and forward it directly to the connector, enabling arbitrary reads and writes outside the advertised memory abstraction. In an agent setting, any component that can reach this API may bypass intended guardrails and execute destructive, exfiltrative, or privilege-abusing database operations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The getting-started guide instructs users to run schema-creation commands and a setup script that will create or modify objects in the connected SQL Server database, but it does not prominently warn that these operations are state-changing and should only be run against the intended target environment. In an agent or automated setup context, this increases the risk of accidental writes to production or the wrong database, especially because the same shared .env profiles are reused from sql-connector.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README explicitly promotes persistent storage of memories, tasks, and activity logs, including potentially sensitive user data, but does not provide concrete guidance on privacy, retention periods, minimization, access controls, or deletion practices. In an agent-memory skill, this omission is security-relevant because operators may deploy long-lived storage of personal or operational data without understanding the compliance and exposure risks.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill documentation declares no explicit tool scope or permissions, yet the described implementation relies on environment variables, database/network connectivity, and likely shell-capable execution paths through dependent code. In an agent setting, missing scope declarations can cause overbroad execution authority and make it harder for operators to understand or constrain what the skill can access.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.