T09 · Insecure Skill Coding Practices
- Location
scripts/validate.py:377- Finding
Untrusted SQLite Native Extension Loading Enables Arbitrary Code Execution
- Content
View full analysis
Vulnerability Details
File Location:
scripts/validate.py, lines 377-394
Vulnerability Type: Untrusted native library loading
Risk Level: HighVulnerable Code
python # Auto-detect sqlite-vec extension path vec_ext_paths = [ args.vec_ext, os.environ.get("SQLITE_VEC_PATH"), os.path.expanduser("~/.npm-global/lib/node_modules/openclaw/node_modules/sqlite-vec-darwin-arm64/vec0.dylib"), os.path.expanduser("~/.npm-global/lib/node_modules/openclaw/node_modules/sqlite-vec-linux-x64/vec0.so"), ] try: conn = sqlite3.connect(args.db) # Try to load sqlite-vec extension for vec0 table support for ext_path in vec_ext_paths: if ext_path and os.path.exists(ext_path): try: conn.enable_load_extension(True) conn.load_extension(ext_path.replace('.dylib', '').replace('.so', '')) print(f"📦 Loaded sqlite-vec from {ext_path}") break except Exception as e: print(f"⚠️ Could not load sqlite-vec from {ext_path}: {e}")Technical Analysis
The validation script enables SQLite extension loading and executes a native shared library selected from either the
--vec-extcommand-line argument or theSQLITE_VEC_PATHenvironment variable. The file is loaded without verifying its cryptographic digest, publisher, ownership, permissions, resolved path, or expected installation directory.SQLite extensions are native executable modules. Loading one invokes its initialization entry point inside the current Python process. Consequently, control over the extension path is equivalent to control over native code executed with the privileges of the user running the validation script.
Loading sqlite-vec is relevant to reading
vec0tables, but implicitly trusting an environment variable is not necessary for the Skill's core quantization functionality and violates least-priv ...[truncated 1494 chars]- Remediation
View remediation
Remediation Suggestions
- Remove automatic native extension loading from environment-controlled paths.
- Require an explicit opt-in flag before enabling extension loading. Do not treat
SQLITE_VEC_PATHas sufficient authorization. - Resolve the extension path with
Path.resolve()and require it to reside under a documented, trusted installation directory. - Reject symlinks and files writable by untrusted users. Verify file ownership and permissions before loading.
- Validate the extension against a pinned SHA-256 digest or trusted digital signature.
- Avoid stripping suffixes with string replacement. Pass a validated canonical path in the form expected by the platform and SQLite API.
- Restrict the accepted extension to the expected sqlite-vec package and version.
- Immediately call
conn.enable_load_extension(False)in afinallyblock after the load attempt. - If possible, open or export the vectors through a trusted helper rather than loading arbitrary native modules into the main process.
- Document that native extension loading executes code with the invoking user's privileges.
