AI Briefing/בלוג
mcp security·11 באוקטובר 2026·6 דקות קריאה

MCP Security: איך שדה config אחד הפך ל-RCE ב-150 מיליון הורדות

באפריל 2026 באג אחד בעיצוב של MCP STDIO הוליד 10 CVEs על 150 מיליון הורדות. מה נשבר, למה הפילטר לא עזר, ומה לבדוק אצלכם השבוע.

  1. 01חפשו StdioServerParameters בקוד. אם command מגיע מקלט, תחליפו ב-allowlist לפי שם.
  2. 02תצמידו גרסה מדויקת לכל שרת MCP. בלי npx -y לחבילה בלי @version.
  3. 03תשלחו tools/list בלי token לכל endpoint. כל תשובה חוץ מ-401 היא באג.

150 מיליון הורדות. זה היקף הקוד שהחוקרים של OX Security קשרו באפריל 2026 לממצא אחד. וזה לא באג בספרייה של מישהו, זו הדרך שבה MCP מריץ שרתים מקומיים. מהממצא הזה יצאו יותר מ-30 disclosures ו-10 CVEs בכמה שפות, אצל LangFlow, Letta, Flowise, Windsurf וה-adapters של LangChain. הם קראו לזה “The Mother of All AI Supply Chains”. שם דרמטי, אבל הפעם המספרים מצדיקים אותו.

אני מספר את הסיפור הזה כי זה המקרה הכי נקי שראיתי של פרוטוקול חדש שפוגש צוותים ממהרים. ומה שהכי שווה ללמוד ממנו הוא דווקא התיקון הראשון, זה שלא עבד.

נובמבר 2024: שקע אחד לכל הכלים

אנטרופיק שחררו את MCP בנובמבר 2024 עם הבטחה פשוטה: USB-C ל-agents. כותבים שרת פעם אחת, וכל client יודע לדבר איתו. יש שני transports עיקריים. HTTP לשרתים מרוחקים, ו-STDIO לשרתים מקומיים. ב-STDIO ה-client מקבל command ו-args, מרים את השרת כ-subprocess ומדבר איתו דרך stdin ו-stdout.

ב-Python זו שורה אחת: StdioServerParameters(command="npx", args=[...]). משעמם וטוב, כל עוד אתם אלה שכותבים אותה.

ואז כולם רצו. עד פברואר 2026 היו 518 שרתים ב-registry הרשמי, וסריקות של הקהילה מצאו ש-38 עד 41 אחוז מהשרתים לא דורשים authentication בכלל. כל פלטפורמת agents הוסיפה כפתור “Add MCP server” ל-UI או ל-API שלה. הכפתור הזה הוא הגיבור של הסיפור.

אפריל 2026: הגדרה שהופכת לפקודה

הממצא של OX, בגדול: ב-STDIO אין שכבה בין config לבין הרצה. ה-SDK מקבל מחרוזת ומריץ אותה כתהליך. זה לא באג במובן הרגיל, זה העיצוב. ברגע שהשדה command מגיע ממקום שמשתמש, או תוקף, יכול לכתוב אליו, “להוסיף שרת MCP” ו“להריץ פקודה על השרת שלכם” הם אותו דבר.

שלוש תוצאות, לפי הטיימליין ש-AuthZed מתחזקים:

ה-adapters של LangChain נפלו באותה צורה, כי גם הם עוברים דרך StdioServerParameters.

איך המנגנון עובד
איך המנגנון עובד
באג אחד בעיצוב, עשרה CVEs אצל ספקים שונים. ככה נראית בעיה ב-SDK ולא במוצר (OX Security, דרך AuthZed)
באג אחד בעיצוב, עשרה CVEs אצל ספקים שונים. ככה נראית בעיה ב-SDK ולא במוצר (OX Security, דרך AuthZed)

איך זה נראה מבחוץ

פה החלק המטריד. מבחוץ זה לא נראה כמו התקפה. אין crash, אין payload מוזר שה-WAF תופס. יש בקשה תקינה ל-endpoint לגיטימי שאומרת “תוסיף שרת בשם notes, הפקודה היא X”. בלוג זה נראה כמו משתמש שמגדיר כלי.

והתהליך שעולה רץ עם ההרשאות של האפליקציה. משתני הסביבה, API keys, credentials ל-DB, ה-token של ה-cloud. כל מה שהפלטפורמה יודעת, הפקודה החדשה יודעת.

חוץ מזה, 10 CVEs אצל ספקים שונים נראים מבחוץ כמו 10 באגים נפרדים. נראה לי שכל צוות ראה “באג במוצר שלנו”, תיקן וסגר טיקט. לקח זמן עד שמישהו חיבר את זה לדפוס אחד.

הטיימליין מראה דפוס ולא תאונה: אותם כשלים של auth ו-input validation חוזרים מ-2025 עד 2026 (credit: AuthZed)
הטיימליין מראה דפוס ולא תאונה: אותם כשלים של auth ו-input validation חוזרים מ-2025 עד 2026 (credit: AuthZed)

התיקון הראשון: עוד פילטר

רגע, אז למה Flowise לא היה מוגן? הוא דווקא ניסה. היו שם פילטרים על הקלט, והחוקרים עקפו אותם.

וזה צפוי. תחשבו מה צריך לחסום: bash -c, python -c, node -e. בסדר. אבל npx -y some-package מוריד חבילה מ-npm ומריץ אותה, ובשם החבילה אין שום מילה חשודה. uvx עושה בדיוק את אותו דבר. פילטר מחרוזות מנסה לנחש מה רע, והתוקף צריך למצוא רק דבר אחד שהפילטר לא ניחש.

AuthZed כתבו את זה ישר: הבעיה ארכיטקטונית, העיצוב מתיר הרצת subprocess, ולכן סינון קלט אד-הוק לא מספיק.

הדעה שלי: אני לא קונה את ה“זה רק misconfiguration”. כשעשרה צוותים שונים עושים את אותה טעות, הבעיה היא בברירת המחדל של ה-SDK ולא בצוותים. מחרוזת נכנסת, תהליך יוצא, וזה פשוט קל מדי.

הסיבה האמיתית: config הוא קוד

השדה command הוא קוד. מי שיכול לכתוב אותו יכול להריץ קוד. זהו בגדול. החוקרים המליצו על אחד משניים: רשימה סגורה של פקודות שהוגדרה מראש, או דגל “dangerous mode” מפורש שמישהו צריך להדליק בכוונה.

בפועל: המשתמש בוחר שם, והקוד שלכם ממפה את השם לפקודה ולגרסה שנקבעו ב-code review.

mcp_servers.py
import os
import shutil
from mcp import StdioServerParameters
# User input picks a NAME. Command, args and version live here, reviewed in PRs.
ALLOWED_SERVERS = {
"filesystem": ("npx", ["-y", "@modelcontextprotocol/server-filesystem@X.Y.Z", "/srv/shared"], []),
"github": ("docker", ["run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server:X.Y.Z"], ["GITHUB_PERSONAL_ACCESS_TOKEN"]),
}
def server_params(name: str) -> StdioServerParameters:
if name not in ALLOWED_SERVERS:
raise PermissionError(f"MCP server {name!r} is not in the allowlist")
command, args, env_keys = ALLOWED_SERVERS[name]
binary = shutil.which(command)
if binary is None:
raise RuntimeError(f"{command} not found on PATH")
# Only PATH plus what this server needs. Never the whole app env.
env = {"PATH": os.environ["PATH"], **{k: os.environ[k] for k in env_keys}}
return StdioServerParameters(command=binary, args=list(args), env=env)

ובמקביל, הבעיה לא נגמרת בצד ה-client. Canopii סרקו ביולי 2026 את כל ה-11,524 שרתים הפומביים. ב-232 מהם נמצא sink מסוכן מאומת: 141 עם eval של קוד שרירותי, 69 עם command injection, 42 עם deserialization לא בטוח. 184 גרסאות שינו בשקט את הגדרות ה-tools אחרי שפורסמו. ו-741 tools היו פתוחים לכל אחד בלי הזדהות, ב-endpoints שטוענים שהם דורשים auth.

הנתון שהכי הפתיע אותי: שרתים עם יותר מ-1,000 כוכבים ב-GitHub יצאו high-risk ב-18.7 אחוז, מול 3.6 אחוז אצל שרתים עם פחות מ-10 כוכבים.

Teams that whitelist “the famous ones” are selecting for risk, not against it.

— Canopii, State of MCP Security 2026

שורה אחת ב-config היא כל ההבדל בין אינטגרציה ל-RCE, ופילטר לא סוגר אותה. רק מיפוי של שם לפקודה קבועה (OX Security, דרך AuthZed)
שורה אחת ב-config היא כל ההבדל בין אינטגרציה ל-RCE, ופילטר לא סוגר אותה. רק מיפוי של שם לפקודה קבועה (OX Security, דרך AuthZed)

מה לבדוק אצלכם השבוע

והשטח רק גדל. בשבוע שאחרי שאנטרופיק הרחיבו את ה-connectors של קלוד במאי, DataDome ראו קפיצה של פי 50 בתעבורת MCP אצל הלקוחות שלהם.

check-mcp-auth.sh
curl -s -o /dev/null -w '%{http_code}\n' \
-X POST "$MCP_URL" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

צריך לצאת 401. אם קיבלתם 400 על session חסר, תשלחו קודם initialize בלי token ותבדקו שוב. ואם חזרה רשימת tools, אתם בין ה-741. ה-checklist של Helixar מוסיף בדיקה ששווה לעשות: הרשאה ברמת ה-tool ולא רק ב-gateway, כי אפשר לדבר עם שרת MCP ישירות ולעקוף את ה-gateway.

אם משתמש יכול לכתוב את השדה command, אין לכם פיצ’ר של אינטגרציות. יש לכם RCE עם UI יפה.

מקורות

  1. The State of MCP Security [pdf] · 2026-07-12
  2. MCP Security 2026: 30 CVEs in 60 Days · 2026-03-12
  3. The AI agent economy is going mainstream · 2026-05-11
  4. A Timeline of MCP Security Breaches (2025-2026) · 2026-05-07
  5. Show HN: MCP Security Checklist – security controls for MCP server deployments · 2026-03-09

איך נכתב הפוסט: נוסח על ידי הסוכן שלנו מתוך 5 מקורות, ונערך ואושר על ידי קובי אלמוג.

עוד מונחים

כל המונחים →
3/4

ChatGPT מקרוב: הפיצ'רים שמהנדסים משאירים כבויים

Projects, memory, canvas, deep research, agent ו-connectors ב-ChatGPT: מה כל אחד עושה, איפה הוא נופל, ומה להפעיל כבר השבוע.

1/5

Claude Code בפרקטיקה, חלק 1: CLAUDE.md קצר, הרשאות קשוחות

שלושת קבצי ה-CLAUDE.md, auto memory, הרשאות ב-settings.json ופקודות שכדאי שיהיו באצבעות. צעד אחרי צעד, לצוות אמיתי.

2/5

Claude Code בפרקטיקה, חלק 2: hooks, MCP ו-skills, מה הולך לאן

CLAUDE.md אומר מה חייב, skill איך, MCP מה אפשר, hook אוכף. PreToolUse שחוסם commit ל-main, formatter אוטומטי, שרת MCP ו-SKILL.md ראשון.