בקשה ל-https://example.com/?author=1 ב-WordPress גורמת ל-redirect 301 לעמוד ה-author archive של אותו משתמש – וב-URL היעד מופיע user_nicename, שלרוב זהה ל-user_login. תוקף יכול להריץ סקריפט שמבקש ?author=1 עד ?author=20 ובדקות ספורות לקבל רשימה של כל המנהלים והעורכים באתר. זוהי "מניית משתמשים" – האחות התאומה של חשיפת REST API users.
למה זה משנה
תקיפת brute-force נחלקת לשני שלבים: גילוי שם המשתמש ואז ניחוש הסיסמה. ניחוש שם משתמש לבד מצמצם את כמות הניסיונות פי אלפי מונים. אם תוקף יודע ש-geffen הוא admin (כי ?author=1 חשף זאת), הוא לא צריך לבדוק admin, administrator, root או 50 שמות נפוצים אחרים. הוא ישר עובד עם השם המדויק. בנוסף, ID 1 כמעט תמיד הוא ה-super admin המקורי, ובמקרים רבים אותו אדם משתמש בסיסמאות חוזרות באתרים אחרים – תוקף יבדוק את הסיסמה שלו מ-leak ידוע (Have I Been Pwned) לפני שיתחיל brute-force בכלל.
איך לזהות
במצב גלישה פרטית, גלוש ל-https://example.com/?author=1. אם הדפדפן מוביל אותך לכתובת כמו https://example.com/author/geffen/ – החשיפה פעילה. בדוק גם ?author=2, ?author=3 וכן הלאה. כלי בדיקה מלא: wpscan --url https://example.com --enumerate u – יציג רשימה מלאה של משתמשים שגיליה דרך הווקטור הזה.
איך לתקן
הדרך הנקייה ביותר היא לחסום בקשות עם פרמטר ?author= ברמת WordPress עצמו, לפני שה-redirect קורה. הוסף ל-mu-plugin או לתבנית ילד:
add_action('init', function () {
if (is_admin()) return;
if (!empty($_GET['author']) || !empty($_REQUEST['author'])) {
wp_die('Forbidden', 'Access Denied', ['response' => 403]);
}
}, 1);
// חסימת REDIRECT_QUERY_STRING גם
add_filter('redirect_canonical', function ($redirect, $request) {
if (preg_match('/\?author=\d+/', $request)) {
return false;
}
return $redirect;
}, 10, 2);
חסימה ברמת השרת:
RewriteEngine On
RewriteCond %{QUERY_STRING} (^|&)author=\d+ [NC]
RewriteRule ^ - [F,L]
if ($arg_author) {
return 403;
}
שכבה משלימה: שנה את user_nicename כך שיהיה שונה מ-user_login:
UPDATE wp_users SET user_nicename = CONCAT('user-', SUBSTRING(MD5(RAND()), 1, 8)) WHERE ID IN (1,2,3);
טעויות נפוצות
טעות ראשונה: לחסום רק את /?author=N דרך .htaccess בלי לטפל גם ב-/author/SLUG/. גם אם החסמת את ה-redirect, עדיין יכול תוקף לנחש את ה-slug ולהגיע לעמוד ה-author. אם אינך משתמש ב-author archives בכלל, השבת אותם לחלוטין: add_action('template_redirect', function() { if (is_author()) wp_redirect(home_url(), 301); });. טעות שנייה: לסמוך על "אני שיניתי שם משתמש מ-admin ל-geffen, אז אני מוגן". זה לא עוזר – המנייה תחזיר את geffen באותה קלות. החיסון היחיד הוא חסימת הווקטור עצמו. טעות שלישית: לא לטפל גם ב-REST API. שתי הבדיקות (user_enum ו-rest_users_public) חייבות להיות מטופלות יחד.
בדיקה לאחר תיקון
במצב גלישה פרטית, גלוש שוב ל-?author=1 עד ?author=10. כל אחד צריך להחזיר 403 או 404 – לא redirect לעמוד author. הרץ wpscan --url https://example.com --enumerate u שוב – הפלט אמור להיות "No usernames found". סיים בהרצת האודיט ובדוק שגם user_enum וגם rest_users_public עוברים.
בנוסף, אם אתה מנהל חוות אתרים, שווה לבנות בדיקה אוטומטית: סקריפט שיורץ ב-cron פעם בשבוע ומריץ curl -sI "https://site/?author=1" על כל האתרים. אם מתקבל redirect 301 לעמוד author, התראה. כך אפשר לזהות מהר אתרים שבהם החסימה הוסרה (לדוגמה, אחרי החלפת ערכת נושא או אחרי עדכון תוסף שדרס את ה-functions.php). אבטחה היא תהליך מתמשך, לא הגדרה חד-פעמית.
?author=N ושמור על נתיב /author/SLUG/. אבל ודא שכל ה-slugs שונים משמות התחברות.