הסתרת גרסת WordPress – למה זה עוזר ולמה לא מספיק

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

WordPress פולט את גרסתו במספר מקומות באתר ציבורי: בתוך תג <meta name="generator">, בקובצי RSS feed, בפרמטר ?ver= בטעינת CSS/JS, ובקבצים readme.html ו-license.txt. תוקפים סורקים את האינטרנט אחר אתרים בגרסאות עם CVE ידוע, וכל אינדיקציה לגרסה מקלה על הסינון. הסתרת הגרסה לא מתקנת פגיעות אמיתית, אבל היא מקטינה דרמטית את כמות הסריקות הממוקדות.

למה זה משנה

סורק טיפוסי עובד בשני שלבים: גילוי גרסה ואז ניצול. אם השלב הראשון נכשל (אין meta generator, אין readme, אין ?ver=), הסורק לרוב מוותר ועובר לאתר הבא. זה לא הופך את האתר ל"בלתי פגיע" – תוקף ממוקד עדיין יוכל לנחש גרסה דרך התנהגויות עדינות (זמני תגובה, שגיאות ספציפיות), אבל הוא יצטרך להשקיע מאמץ. ההבדל בין 100 סריקות אוטומטיות ביום ל-2 הוא ההבדל בין "בלוגרים שלא יודעים שמתקפה מתרחשת" ל-"חיים בשקט". בנוסף, הסתרה מקשה על תוקף שמסתכל ב-Wayback Machine למצוא תאריכי שדרוג.

איך לזהות

הרץ:

curl -s https://example.com/ | grep -i "generator"
curl -s https://example.com/feed/ | grep -i "generator"
curl -s https://example.com/readme.html | head -5
curl -sI https://example.com/wp-content/plugins/jquery/jquery.js | grep -i "ver="

אם תראה <meta name="generator" content="WordPress 6.4.2"> או <generator>https://wordpress.org/?v=6.4.2</generator> ב-RSS, הגרסה גלויה. גם פרמטר ?ver=6.4.2 ב-URL של קבצי CSS/JS חושף גרסה.

איך לתקן

הוסף ל-mu-plugin או לתבנית ילד את הקוד הבא. הוא מטפל בכל המקורות בבת אחת:

// 1. הסר meta generator מ-HTML
remove_action('wp_head', 'wp_generator');

// 2. ריקון ה-generator ב-RSS, Atom, RDF
add_filter('the_generator', '__return_empty_string');

// 3. הסרת ?ver= מקבצי CSS/JS של הליבה
add_filter('style_loader_src', 'rp_strip_version_query', 10, 2);
add_filter('script_loader_src', 'rp_strip_version_query', 10, 2);
function rp_strip_version_query($src, $handle) {
    if (strpos($src, 'ver=') !== false) {
        $src = remove_query_arg('ver', $src);
    }
    return $src;
}

טיפול בקבצי readme:

# ב-.htaccess בשורש האתר
<FilesMatch "^(readme\.html|license\.txt|wp-config-sample\.php)$">
    Require all denied
</FilesMatch>
location ~* /(readme\.html|license\.txt|wp-config-sample\.php)$ {
    deny all;
}

טעויות נפוצות

טעות ראשונה: לחשוב שהסתרה היא תחליף לעדכון. היא לא. אתר על WordPress 5.8 יישבר בקרוב גם בלי שהגרסה תתפרסם – פגיעות עתידית לא תתעלם ממנו רק כי המספר חבוי. עדכון הוא היחיד "תיקון אמיתי", הסתרה היא רק שכבה משלימה. טעות שנייה: למחוק ידנית את readme.html – WordPress יחזיר אותו בעדכון הליבה הבא. החסום ברמת השרת ב-.htaccess הוא העמיד היחיד. טעות שלישית: להסיר ?ver= מקבצי תוסף ולגלות שהמטמון של הדפדפן לא מתעדכן. הפרמטר משמש cache busting; אם תסיר אותו, הוסף מנגנון אחר (filemtime או hash) או החזק את הקבצים בשמות עם hash אינטגרל. טעות רביעית: לסמוך רק על תוסף "Hide WP Version" שעלולים להיות בו פגיעויות בעצמו. הקוד הוא 5 שורות – הוסף ידנית, לא צריך תוסף.

בדיקה לאחר תיקון

הרץ שוב את אותם פקודות curl מהשלב "איך לזהות". כל ארבעת הפלטים אמורים להיות ריקים או 403. בנוסף, גלוש לאתר ב-Chrome > View Source ובדוק שאין "WordPress" בתוך ה-HTML. לבסוף, הרץ את wpscan --url https://example.com – אמור להחזיר "Could not detect WordPress version".

טיפ: הסתרת הגרסה היא ה-90% האחרונים אחרי שכל השאר תקין. אם האתר שלך עדיין על WP 6.0 ב-2026, אל תשקיע בהסתרה – השקיע בעדכון.