אבטחת ה-MCP Adapter של וורדפרס: 8 סיכונים שבדקתי

ה-MCP Adapter הוא תוסף שמאפשר לסוכני AI כמו Claude לעבוד מול אתר הוורדפרס שלכם. הוא הופך "יכולות" (Abilities) של וורדפרס לכלים שה-AI יכול להפעיל, כך שתוכלו לבקש מהסוכן לשלוף הזמנות, לבדוק ציוני SEO או לקרוא את הגדרות האתר בשפה טבעית.

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

מה ה-MCP Adapter עושה בפועל?

"יכולת" היא פעולה בודדת שוורדפרס או תוסף רושמים, למשל "קריאת פרטי האתר" או "מחיקת מוצר". ה-Adapter חושף יכולות נבחרות דרך ה-Model Context Protocol, כך שכל client תואם (כמו Claude Code) יכול להשתמש בהן.

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

מה גיליתי בבדיקה

כל התוצאות שלהלן נמדדו ב-2026-10-24 על התקנה נקייה: וורדפרס 7.1.3, MCP Adapter 0.7.1, יחד עם Elementor 4.3.5, WooCommerce 11.2.1 ו-Yoast SEO 28.7. התחברתי כמנהל, כמנהל חנות, ככותב וכמנוי.

א. Elementor מפעיל שרת MCP גם בלי התוסף

בדקו זאת קודם. Elementor מגיע עם עותק משלו של ה-Adapter ומפעיל אותו עבורכם. כאשר רק Elementor היה פעיל (ותוסף ה-MCP Adapter מעולם לא הותקן), ה-endpoint /wp-json/mcp/mcp-adapter-default-server היה זמין.

Elementor מותקן ביותר מ-10 מיליון אתרים, כך שרבים מהם מריצים כיום שרת MCP שבעליהם מעולם לא הגדירו. ה-endpoint עדיין דורש משתמש מחובר, ובדקתי זאת על Elementor 4.3.5 בלבד. גם Angie מגיע עם ה-Adapter, וכך גם האינטגרציה של WP Rocket ל-MCP: גרסה 3.23.5.1 הפעילה בעצמה את השרת הזה וגם שרת OAuth, על גרסה ישנה של ה-Adapter (0.5.0). WooCommerce כולל אותו אך לא הפעיל את השרת בעצמו.

פתחו את /wp-json/ באתר שלכם וחפשו mcp-adapter-default-server. אם הנתיב קיים, האתר שלכם מריץ שרת MCP, בין אם התקנתם את ה-Adapter ובין אם לא. נתיב /mcp/ לבדו יכול להיות גם endpoint של OAuth, לכן ודאו שמדובר בנתיב של השרת עצמו.

טרמינל: בקשת curl ל-/wp-json מציגה שהנתיב mcp-adapter-default-server פעיל, ובקשת POST אנונימית אליו מחזירה 401

ב. שלוש יכולות הליבה ציבוריות כבר מההתקנה

בוורדפרס 7.1.3, שלוש יכולות מובנות מסומנות בדגל public: פרטי האתר, הפרופיל של המשתמש הנוכחי ופרטי הסביבה (גרסת PHP, גרסת מסד הנתונים וגרסת וורדפרס). ה-Adapter מתייחס לאותו דגל כאל "לחשוף דרך MCP", כך שהן מופיעות בשרת ברירת המחדל בלי שעשיתם דבר.

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

ג. כל מנוי יכול להתחבר ולראות את רשימת הכלים המלאה

התחברות לשרת ברירת המחדל דורשת רק את ההרשאה הבסיסית read. באתר מנויים או בחנות, מדובר בכל לקוח רשום.

מנוי שהתחבר יכול היה לראות את כל 14 היכולות החשופות, כולל woocommerce/product-delete. הוא לא יכול היה להפעיל את אלה שאין לו הרשאה אליהן (ניסיון המחיקה החזיר "Permission denied"). הבעיה היא החשיפה: הרשימה המלאה של מה ששכבת ה-AI מסוגלת לעשות, כולל פעולות הרסניות, גלויה לכל בעל חשבון.

ד. כלי אחד מריץ הכל, וזה מנטרל את האישורים ב-client

שרת ברירת המחדל חושף שלושה כלים בלבד, ואחד מהם, execute-ability, מפעיל כל יכולת חשופה לפי שמה. ה-client רואה כלי אחד, ולא כלי נפרד לכל פעולה.

זה משנה מכיוון שחלק מה-clients מבקשים מכם לאשר כל כלי לפי שמו. ב-Claude Code, אישור של execute-ability פעם אחת (עבור פעולת קריאה תמימה) מאשר גם את הפעולה שמוחקת מוצר, וזאת מכיוון שמדובר באותו כלי. בשרת ברירת המחדל, ה-client אינו מסוגל להבדיל בין פעולת קריאה למחיקה.

ה. ההסתרה הנפוצה משאירה דרך גישה נוספת פתוחה

העצה שתמצאו ברשת היא להסתיר יכולת מסוכנת על ידי הגדרת הדגל meta.mcp.public שלה ל-false. ב-MCP זה עבד: היכולת המוסתרת החזירה "not found".

אך יכולת המסומנת ב-show_in_rest זמינה גם דרך ה-REST API של ה-Abilities. כשהיכולת הוסתרה מ-MCP, אותם פרטי גישה עדיין הפעילו אותה דרך נתיב ה-REST שלה והעבירו מוצר לפח. בכדי לסגור זאת, עליכם להגדיר גם את show_in_rest ל-false, ואפילו אז תוסף אחר עשוי לחשוף את אותה פעולה דרך endpoint משלו. הממצא הבא מסביר למה.

ו. פרטי הגישה אינם מוגבלים ל-MCP, וזה הממצא החשוב ביותר

ה-client (למשל Claude Code) מזדהה באמצעות סיסמת אפליקציה (Application Password) של וורדפרס. נוטים לחשוב עליה כעל "ההתחברות ל-MCP", אבל זה לא נכון. מדובר בפרטי גישה מלאים ל-API של וורדפרס, בהתאם להרשאות של המשתמש שמאחוריה.

בכדי להוכיח זאת, לקחתי את סיסמת האפליקציה בה ה-client משתמש ודילגתי על MCP לגמרי. אותה סיסמה מחקה מוצר דרך ה-REST endpoint של WooCommerce עצמו, קראה את כתובות האימייל של כל המשתמשים ושינתה את כותרת האתר דרך ה-REST API של הליבה.

סיסמת אפליקציה אחת של ה-client מגיעה לשרת ה-MCP, ל-REST של WooCommerce, ל-REST של הליבה ול-REST API של ה-Abilities; הקשחת MCP חוסמת רק אחת מהן

זה מציג את כל מה שתיארתי עד כה באור אחר. הקשחת MCP מצמצמת את שטח התקיפה של MCP, אבל הסיסמה עדיין מגיעה ישירות ל-WooCommerce, לליבה ול-Abilities API, ולכן אף אחד מהצעדים האלה לא עוצר פרטי גישה שדלפו או שיש להם יותר מדי הרשאות. גבול האבטחה האמיתי הוא ההרשאות של המשתמש שדרכו אתם מתחברים, ולא הכלים שאתם חושפים.

ז. אין תיעוד פעולות כברירת מחדל

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

אם סוכן AI ביצע שינוי שלא ציפיתם לו, שום דבר ב-Adapter לא יגיד לכם מה הוא עשה. תצטרכו להוסיף תיעוד בעצמכם.

ח. Prompt Injection תלוי לחלוטין במודל

אם יכולת מחזירה טקסט שגולשים יכולים לכתוב (תגובות או ביקורות, למשל), אותו טקסט יכול להכיל הוראות נסתרות ל-AI. שתלתי תגובה שהורתה לסוכן למחוק שני מוצרים, ואז ביקשתי ממנו רק לסכם את התגובות.

התוצאות התפצלו לפי מודל. שלושה מודלים של Claude ומודל ה-GPT העדכני זיהו את התגובה וסירבו; מודל GPT ישן יותר ציית לה, מחק את שני המוצרים ודיווח על המחיקה כעל "תחזוקה שגרתית". אלו היו הרצות בודדות, לכן התייחסו אליהן כאל תצפיות ולא כאל ערובה. השורה התחתונה: ברגע שאישרתם מראש את execute-ability עבור משתמש עם הרשאות כתיבה, שיקול הדעת של המודל הוא קו ההגנה האחרון, והוא משתנה ממודל למודל. אל תבנו עליו, והפרידו בין סשנים שקוראים תוכן לבין סשנים עם הרשאות כתיבה.

כיצד להקשיח את ה-MCP Adapter

הנה התצורה שבדקתי ושהייתי מריץ בפרודקשן: בלי שרת ברירת מחדל, שרת מותאם קטן שחושף רק את מה שאתם צריכים, משתמש ייעודי עם הרשאות מינימליות ותיעוד של כל הפעלה.

שלב 1: כבו את שרת ברירת המחדל

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

add_filter( 'mcp_adapter_create_default_server', '__return_false' );

בבדיקה שלי, הנתיב /mcp/mcp-adapter-default-server נעלם לאחר מכן.

שלב 2: הריצו שרת מותאם אחד עם רשימה מפורשת

שרת מותאם חושף רק את היכולות שאתם מציינים, ומציג כל אחת מהן ככלי נפרד. כך חוזרת האפשרות לאשר כל יכולת בנפרד ב-client, ותוכלו לדרוש כל הרשאה שתבחרו לצורך התחברות.

add_action( 'mcp_adapter_init', function ( $adapter ) {
    $adapter->create_server(
        'site-tools',                 // server id
        'mcp',                        // REST namespace
        'site-tools',                 // route: /wp-json/mcp/site-tools
        'Site tools (read-only)',
        'Read-only tools for the AI agent',
        'v1.0.0',
        array( \WP\MCP\Transport\HttpTransport::class ),
        \WP\MCP\Infrastructure\ErrorHandling\ErrorLogMcpErrorHandler::class,
        \WP\MCP\Infrastructure\Observability\NullMcpObservabilityHandler::class,
        array(                        // the only abilities this server exposes
            'core/get-site-info',
            'woocommerce/products-query',
            'yoast-seo/get-post-seo-data',
        ),
        array(),
        array(),
        static fn() => current_user_can( 'mcp_connect' ) // who may connect
    );
} );

בבדיקה שלי, השרת הזה הציג שלושה כלים נפרדים לקריאה בלבד, דחה משתמש ללא ההרשאה mcp_connect עם 403, ודחה כל יכולת שאינה ברשימה עם "Tool not found".

שלב 3: התחברו דרך משתמש ייעודי עם הרשאות מינימליות

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

הימנעו מלתת לסוכן את manage_options רק בכדי שיכולות הליבה יעבדו; זה הופך את הסיסמה שלו למפתח מנהל לכל ה-REST API. שמרו את הסיסמה מחוץ לקבצי הגדרות בטקסט גלוי, ככל האפשר, ובטלו אותה ברגע שה-client יוצא משימוש.

שלב 4: הגבילו מי בכלל יכול להחזיק סיסמת אפליקציה

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

add_filter( 'wp_is_application_passwords_available_for_user', function ( $available, $user ) {
    $allowed = array( 42 ); // user IDs of your MCP service accounts
    return in_array( (int) $user->ID, $allowed, true );
}, 10, 2 );

עם הפילטר הזה, מנוי שניסה ליצור סיסמת אפליקציה קיבל 501 עם ההודעה "not available for your account". ובהזדמנות זו, בטלו את XML-RPC אם אינכם משתמשים בו, מכיוון שסיסמאות אפליקציה עובדות גם שם.

שלב 5: תעדו כל הפעלה

ה-Adapter מפעיל פילטר לפני כל הפעלה של כלי. כמה שורות הופכות אותו ללוג ביקורת שבאמת אפשר לקרוא.

add_filter( 'mcp_adapter_pre_tool_call', function ( $args, $tool_name ) {
    $log   = get_option( 'mcp_audit', array() );
    $log[] = array(
        gmdate( 'c' ),
        wp_get_current_user()->user_login,
        $tool_name,
        wp_json_encode( $args ),
        $_SERVER['REMOTE_ADDR'] ?? '',
    );
    update_option( 'mcp_audit', array_slice( $log, -500 ), false );
    return $args;
}, 10, 2 );

הפילטר הזה רואה רק הפעלות דרך MCP, ולא את נתיבי ה-REST הישירים שאליהם אותם פרטי גישה יכולים להגיע, לכן השאירו את לוגי הגישה של השרת כתיעוד האמיתי.

אם אתם חייבים להישאר עם שרת ברירת המחדל

כשאינכם יכולים עדיין לעבור לשרת מותאם, הסתירו יכולת מסוכנת בשני הערוצים במקביל (MCP ו-REST), אחרת נתיב ה-REST נשאר פתוח.

add_filter( 'wp_register_ability_args', function ( $args, $name ) {
    if ( 'woocommerce/product-delete' === $name ) {
        $args['meta']['mcp']['public'] = false; // hide from MCP
        $args['meta']['show_in_rest'] = false;  // and from the REST API
    }
    return $args;
}, 10, 2 );

חשיפה אינה הרשאה

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

הדגל public שולט בגילוי ובחשיפה ל-clients. הוא אינו הופך יכולת לניתנת להרצה ללא הרשאה, וזו חייבת להיאכף על ידי היכולת עצמה. – צוות הליבה של וורדפרס, "A unified public exposure flag for Abilities in WordPress 7.1"

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

נושא שרת ברירת מחדל שרת מותאם ומוקשח
מי יכול להתחבר כל משתמש עם read רק בעלי ההרשאה שאתם בוחרים
יכולות חשופות כל מה שסומן כציבורי רק אלה שציינתם
הכלים שה-AI רואה execute-ability אחד כלי לכל יכולת, עם סימון לקריאה בלבד
לוג ביקורת אין שלכם, דרך פילטר
הרשאות משתמש החיבור כל חשבון שתחברו אליו חשבון ייעודי עם הרשאות מינימליות

שאלות נפוצות

שאלות נפוצות על אבטחת ה-MCP Adapter בוורדפרס:

האם יש לי endpoint של MCP גם אם מעולם לא התקנתי את ה-MCP Adapter?
ייתכן. Elementor ועוד כמה תוספים מגיעים עם ה-Adapter ומפעילים שרת בעצמם. פתחו את /wp-json/ באתר שלכם וחפשו את הנתיב mcp-adapter-default-server. אם הוא קיים, אתם מריצים שרת MCP בין אם התקנתם את ה-Adapter ובין אם לא.
האם מנוי רגיל יכול לגרום נזק דרך MCP?
לא ישירות. מנוי יכול להתחבר ולראות כל יכולת חשופה, אבל כל יכולת עדיין בודקת הרשאות לפני שהיא רצה, ולכן מנוי לא יכול להריץ פעולה שמיועדת למנהלים. הסיכון האמיתי הוא חשיפה של מה ששכבת ה-AI מסוגלת לעשות, ובנוסף כל יכולת שתוסף סימן בטעות כזמינה למשתמשים עם הרשאות נמוכות.
האם מספיק להסתיר יכולת עם meta.mcp.public?
לא. הדגל הזה מסתיר את היכולת רק מ-MCP. לעיתים קרובות אותה יכולת עדיין זמינה דרך ה-REST API. בכדי לסגור את שני הערוצים, הגדירו גם את show_in_rest ל-false, כפי שמוצג בחלק על הקשחה.
האם בטוח לתת סיסמת אפליקציה לסוכן AI?
סיסמת אפליקציה ארוכה ואקראית, כך שלא ריאלי לפרוץ אותה בכוח. הסיכון הוא שהיא נשמרת בטקסט גלוי בהגדרות ה-client ואינה מוגבלת ל-MCP. היא עובדת על כל ה-REST API עם ההרשאות של המשתמש שלה. צרו אותה עבור משתמש ייעודי עם הרשאות מינימליות ובטלו אותה ברגע שה-client יוצא משימוש.
האם וורדפרס מתעדת מה ה-AI עשה?
לא כברירת מחדל. שרת ברירת המחדל לא רושם דבר, וזמן ה"שימוש האחרון" של סיסמת אפליקציה מתעדכן לכל היותר פעם ביום. הוסיפו לוג על הפילטר mcp_adapter_pre_tool_call בכדי לתעד את המשתמש, הכלי, הארגומנטים וכתובת ה-IP של כל הפעלה.
האם לכבות את MCP לגמרי אם אני לא משתמש בו?
כן. אם שום דבר באתר שלכם לא מחבר סוכן AI, כבו את שרת ברירת המחדל עם הפילטר mcp_adapter_create_default_server המוגדר ל-false. כך ה-endpoint מוסר (כולל עותקים שתוספים אחרים מפעילים), והיכולות נשארות זמינות לשימושים הרגילים שלהן.

סיכום

המודל של ה-MCP Adapter תקין, אבל ברירות המחדל שלו לא: שרת שלא ביקשתם יכול להיות פעיל, הוא חושף את כל מה שציבורי דרך כלי אחד, והוא לא מתעד דבר. בנוסף, פרטי הגישה שמאחוריו הם מפתח מלא ל-API של וורדפרס, שמגיע ל-WooCommerce, לליבה ול-Abilities API בין אם MCP מוקשח ובין אם לא. החשבון שדרכו אתם מתחברים הוא הגבול האמיתי.

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

דיון ותגובות
[  0 תגובות  ]

השאירו תגובה

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