2026年11月12日

2026年11月12日

منع تنفيذ PHP في مجلد uploads في WordPress

هذه المقالة نسخة مُوطَّنة من الأصل الياباني. اقرأ الأصل الياباني

مقدمة

المجلد wp-content/uploads/ هو الذي يحفظ فيه WordPress الوسائط كالصور. إذا وُضعت فيه ملفات PHP وكان تنفيذها ممكنًا، فبإمكان المهاجم رفع Web Shell (باب خلفي) وتنفيذ شيفرة اختيارية.

الأعراض والأسباب

  • اكتشف فحص البرمجيات الخبيثة ملفات PHP داخل wp-content/uploads/
  • حذّرت إضافة أمان من أن «PHP قابل للتنفيذ في مجلد uploads»
  • عُثر على ملف مشبوه بمسار مثل wp-content/uploads/2024/01/shell.php
  • زُرع Web Shell باستغلال ثغرة في وظيفة رفع الملفات

خطوات الحل

الخطوة 1: اكتشاف ملفات PHP المشبوهة الموجودة

# البحث عن كل ملفات PHP داخل مجلد uploads
find /var/www/html/wp-content/uploads -name "*.php" -type f
find /var/www/html/wp-content/uploads -name "*.phtml" -type f
find /var/www/html/wp-content/uploads -name "*.php5" -type f

# فحص ملفات PHP التي أُنشئت أو عُدّلت خلال آخر 7 أيام
find /var/www/html/wp-content/uploads -name "*.php" -mtime -7

# فحص المحتوى (أنماط مميزة للبرمجيات الخبيثة)
grep -rl "eval(base64_decode" /var/www/html/wp-content/uploads/
grep -rl "system\|exec\|passthru\|shell_exec" /var/www/html/wp-content/uploads/

# حذف ملفات PHP المشبوهة
find /var/www/html/wp-content/uploads -name "*.php" -delete
find /var/www/html/wp-content/uploads -name "*.phtml" -delete

الخطوة 2: منع تنفيذ PHP في Apache (.htaccess)

# إنشاء wp-content/uploads/.htaccess
cat > /var/www/html/wp-content/uploads/.htaccess << 'EOF'
# منع تنفيذ ملفات PHP نهائيًا
<FilesMatch "\.(php|phtml|php3|php4|php5|php7|phar|shtml)$">
    Order Deny,Allow
    Deny from all
</FilesMatch>

# تعطيل محرك PHP نفسه (عند استخدام mod_php)
<IfModule mod_php.c>
    php_flag engine off
</IfModule>

# منع تنفيذ CGI أيضًا
Options -ExecCGI
RemoveHandler .php .phtml .php5 .phar

# تعطيل عرض محتويات المجلد أيضًا
Options -Indexes
EOF

chmod 644 /var/www/html/wp-content/uploads/.htaccess
# التحقق بعد الإعداد
# أنشئ ملف PHP تجريبيًا وحاول الوصول إليه
echo "<?php echo 'test'; ?>" > /var/www/html/wp-content/uploads/test_block.php
curl -o /dev/null -s -w "%{http_code}" https://example.com/wp-content/uploads/test_block.php
# إذا أُعيد 403 فقد نجحت العملية
rm /var/www/html/wp-content/uploads/test_block.php

الخطوة 3: منع تنفيذ PHP في Nginx

# /etc/nginx/sites-available/example.com
server {
    # ... الإعدادات الحالية ...

    # منع تنفيذ PHP في مجلد uploads
    location ~* /wp-content/uploads/.*\.(php|phtml|php5|phar)$ {
        deny all;
        access_log off;
        log_not_found off;
    }

    # اكتبه قبل location الخاص بـ PHP-FPM
    location ~ \.php$ {
        # معالجة PHP العادية
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}
# تحقق من إعدادات Nginx ثم طبّقها
sudo nginx -t && sudo systemctl reload nginx

# التحقق
curl -o /dev/null -s -w "%{http_code}" https://example.com/wp-content/uploads/shell.php
# إذا أُعيد 403 فقد نجحت العملية

الخطوة 4: حظر رفع PHP من داخل WordPress أيضًا

// functions.php: حظر رفع ملفات PHP نفسه

// ① إضافة امتدادات PHP إلى قائمة الرفع المحظور
add_filter('upload_mimes', function(array $mimes): array {
    // إزالة أنواع MIME المتعلقة بـ PHP (احتياطًا)
    unset($mimes['php'], $mimes['phtml'], $mimes['phar']);
    return $mimes;
});

// ② اكتشاف PHP في الملفات المرفوعة ورفضه
add_filter('wp_handle_upload_prefilter', function(array $file): array {
    $dangerous_extensions = ['php', 'phtml', 'php3', 'php4', 'php5', 'phar', 'shtml'];
    $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));

    if (in_array($ext, $dangerous_extensions, true)) {
        $file['error'] = 'رفع ملفات PHP محظور.';
    }

    // التحقق من نوع MIME أيضًا
    if (str_contains($file['type'], 'php')) {
        $file['error'] = 'رفع ملفات PHP محظور.';
    }

    return $file;
});

الخطوة 5: إعداد مراقبة دورية

# سكربت لمراقبة ملفات PHP داخل uploads بشكل دوري
cat > /usr/local/bin/check-uploads-php.sh << 'EOF'
#!/bin/bash
UPLOADS_DIR="/var/www/html/wp-content/uploads"
ADMIN_EMAIL="admin@example.com"

PHP_FILES=$(find "$UPLOADS_DIR" -name "*.php" -o -name "*.phtml" -o -name "*.phar" 2>/dev/null)

if [ -n "$PHP_FILES" ]; then
    echo "تحذير: اكتُشفت ملفات PHP في مجلد uploads:
$PHP_FILES" | mail -s "[عاجل] احتمال زرع Web Shell في WordPress" "$ADMIN_EMAIL"

    # حذف تلقائي (استخدمه بحذر)
    # find "$UPLOADS_DIR" -name "*.php" -delete
fi
EOF
chmod +x /usr/local/bin/check-uploads-php.sh

# التحقق كل ساعة
echo "0 * * * * root /usr/local/bin/check-uploads-php.sh" > /etc/cron.d/wp-uploads-php-check

ملاحظات

  • لا يعمل php_flag engine off في .htaccess إلا عند استخدام mod_php. وإذا كنت تستخدم php-fpm (FastCGI) فاعتمد على التوجيه أو على كتلة location في Nginx
  • في Nginx، إذا لم تكتب قاعدة الحجب الخاصة بـ uploads قبل location ~ \.php$ فقد تُقدَّم الأخيرة عليها ويصبح التنفيذ ممكنًا. ضع قاعدة الحجب دائمًا في موضع أعلى
  • بعض الإضافات (مثل Slider Revolution) قد تضع ملفات .php داخل uploads. تحقق من الغرض منها قبل الحذف، واحذف الإضافات غير الضرورية ثم عالج الأمر

الخلاصة

يتم منع تنفيذ PHP في مجلد uploads بما يلي: ① اكتشاف الملفات المشبوهة الموجودة وحذفها بـ find wp-content/uploads -name ".php"، ② في Apache أضف إلى uploads/.htaccess القاعدة <FilesMatch "\.(php|phar)$"> Deny from all، ③ في Nginx استخدم location ~ /wp-content/uploads/.*\.php$ مع deny all، ④ ارفض رفع PHP نفسه بالخطاف wp_handle_upload_prefilter، ⑤ راقب ملفات PHP داخل uploads بمهمة cron كل ساعة.

لديك أسئلة حول WordPress؟ ناشر هذا الموقع موجود في اليابان ويرد باللغة اليابانية. تواصل معنا (باليابانية)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲