בכל אתר WordPress יש קבצים שאמורים להיות פנימיים בלבד אבל לעיתים מועלים בטעות לשורש האתר ונשארים נגישים דרך HTTP. הקריטיים ביותר: תיקיית .git/, קובץ .env, גיבויי wp-config (.bak, .old, .save), קבצי SQL ישירים, ו-readme.html.
למה זה משנה
כל אחד מהקבצים האלה הוא דליפת נתונים פוטנציאלית: .git/HEAD - אם נעשה 'git pull' על שרת הייצור, התיקייה נשארת. כל ההיסטוריה של הקוד, כולל סיסמאות שנמחקו לפני זמן רב, נגישה דרך כלי 'git-dumper'. .env - קובץ סביבה של Laravel/Node/Symfony שלעיתים מועלה בטעות. מכיל בדרך כלל DB_PASSWORD, API_SECRET, מפתחות AWS. אם הוא נקרא, החלף מיידית כל סיסמה ומפתח שמופיע בו. wp-config.bak - אדמין שעורך את wp-config.php ויוצר גיבוי .bak לפני השינוי. הקובץ עדיין נקרא, ומכיל את הסיסמה ל-DB ואת ה-salts. databases.sql / dump.sql - dump של ה-DB שהושאר בשורש. כולל את wp_users עם hashes של סיסמאות. readme.html ו-license.txt - חושפים את גרסת WordPress המדויקת, מה שמאפשר לתוקף לבחור exploit מתאים. תוקפים סורקים אינטרנט שלם אחר הקבצים האלה - יש כלים מסחריים שעוברים מיליוני אתרים בשעה.
איך לזהות
הבדיקה מבצעת HTTP HEAD/GET לרשימה של נתיבים מסוכנים: /.git/HEAD, /.env, /wp-config.bak, /wp-config.php.bak, /wp-config-sample.php, /readme.html, /license.txt, /backup.sql, /database.sql, /.DS_Store, /composer.json, /composer.lock, /package.json. אם החזרה היא 200 - הקובץ נגיש. ידנית: גש בדפדפן ל-https://example.com/.git/HEAD - אם רואה תוכן ('ref: refs/heads/main') יש בעיה. נסה גם /readme.html. נכתב גם בדיקה אוטומטית בשורת פקודה:
for path in .git/HEAD .env wp-config.bak readme.html; do
echo "$path: $(curl -s -o /dev/null -w '%{http_code}' https://example.com/$path)"
doneאיך לתקן
- אם נמצא .env, .git או wp-config.bak: הקבצים מצביעים על תהליך פריסה לקוי. תקן את התהליך כך שלא יקרה שוב. הוסף .gitignore עם 'wp-config.php' ו-'.env'. עברו ל-deploy script (rsync עם --exclude) במקום 'git pull' על השרת.
- אם .env נחשף: בהנחה שהוא נקרא, החלף מיידית את כל הסיסמאות ומפתחות ה-API שמופיעים בו. ה-DB password, מפתחות Stripe, מפתחות SMTP - הכל. גם אם 'אולי לא נקרא' - בוטים סורקים את הנתיב הזה כל יום.
- מחק את הקבצים: SSH cd לשורש האתר, rm -rf .git wp-config.bak readme.html license.txt.
- הוסף חסימה ברמת השרת לקבצים נסתרים ולסיומות סודיות:
<FilesMatch "^\.|wp-config\.bak$|\.env$|\.git.*$|\.sql$|\.bak$"> Require all denied </FilesMatch> - ל-Nginx:
location ~ /\.(?!well-known) { deny all; return 404; } location ~* \.(bak|sql|env|log|old|save)$ { deny all; } - החסימה צריכה להגיע לפני הכלל שמעביר ל-PHP - אחרת PHP ירוץ והכלל לא תקף.
- בדוק מחדש את כל הנתיבים - אמורים להחזיר 403 או 404, לא 200.
טעויות נפוצות
אל תניח שאם הקובץ ריק או דמה זה בסדר - גם cookies בריקות מציינות לתוקף שיש פה משהו בנושא. אל תחסום רק את הנתיב הספציפי שזוהה (.git/HEAD) ותשכח אחרים (.git/config). חסום את כל ה-prefix .git. אל תמחק את הקובץ בלי לתקן את התהליך - בעדכון הבא הוא יחזור. אל תסמוך על 'הספק שלי כבר חוסם את זה' בלי לבדוק - חסימות ברירת מחדל של Cloudflare/Sucuri מטפלות ברוב אבל לא הכל.
בדיקה לאחר תיקון
הרץ שוב את האודיט - הבדיקה אמורה להפוך לירוקה. ידנית בקליטה ידנית: curl -I עבור כל נתיב חשוד אמור להחזיר 403 או 404. אם החלפת סיסמאות אחרי דליפה של .env, ודא שהאתר עדיין מתחבר ל-DB עם הסיסמה החדשה. בדוק שהאתר עצמו עובד - לפעמים כללי .htaccess גורפים מדי חוסמים גם משאבים תקינים.