2026年11月12日

2026年11月12日

Jak zablokować wykonywanie PHP w katalogu uploads w WordPress

Ten artykuł jest zlokalizowaną wersją japońskiego oryginału. Przeczytaj japoński oryginał

Wstęp

wp-content/uploads/ to katalog, w którym WordPress przechowuje obrazy i inne media. Jeśli w tym katalogu da się umieścić i uruchomić plik PHP, atakujący może wgrać web shell (backdoor) i wykonywać dowolny kod.

Objawy i przyczyny

  • Skaner malware wykrył pliki PHP w wp-content/uploads/
  • Wtyczka bezpieczeństwa ostrzegła, że „w katalogu uploads można wykonywać PHP"
  • Znaleziono podejrzany plik pod ścieżką w rodzaju wp-content/uploads/2024/01/shell.php
  • Web shell został umieszczony przez wykorzystanie luki w funkcji wgrywania plików

Kroki rozwiązania

Krok 1: wykryj istniejące podejrzane pliki PHP

# Znajdź wszystkie pliki PHP w katalogu 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

# Sprawdź pliki PHP utworzone lub zmienione w ostatnich 7 dniach
find /var/www/html/wp-content/uploads -name "*.php" -mtime -7

# Sprawdź zawartość plików (charakterystyczne wzorce malware)
grep -rl "eval(base64_decode" /var/www/html/wp-content/uploads/
grep -rl "system\|exec\|passthru\|shell_exec" /var/www/html/wp-content/uploads/

# Usuń podejrzane pliki PHP
find /var/www/html/wp-content/uploads -name "*.php" -delete
find /var/www/html/wp-content/uploads -name "*.phtml" -delete

Krok 2: zablokuj wykonywanie PHP w Apache (.htaccess)

# Utwórz wp-content/uploads/.htaccess
cat > /var/www/html/wp-content/uploads/.htaccess << 'EOF'
# Całkowicie zablokuj wykonywanie plików PHP
<FilesMatch "\.(php|phtml|php3|php4|php5|php7|phar|shtml)$">
    Order Deny,Allow
    Deny from all
</FilesMatch>

# Wyłącz sam silnik PHP (przy mod_php)
<IfModule mod_php.c>
    php_flag engine off
</IfModule>

# Zablokuj też wykonywanie CGI
Options -ExecCGI
RemoveHandler .php .phtml .php5 .phar

# Wyłącz także listowanie katalogów
Options -Indexes
EOF

chmod 644 /var/www/html/wp-content/uploads/.htaccess
# Sprawdzenie po zmianie konfiguracji
# Utwórz testowy plik PHP i spróbuj go otworzyć
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
# Jeśli wróci 403, wszystko działa
rm /var/www/html/wp-content/uploads/test_block.php

Krok 3: zablokuj wykonywanie PHP w Nginx

# /etc/nginx/sites-available/example.com
server {
    # ... dotychczasowa konfiguracja ...

    # Zablokuj wykonywanie PHP w katalogu uploads
    location ~* /wp-content/uploads/.*\.(php|phtml|php5|phar)$ {
        deny all;
        access_log off;
        log_not_found off;
    }

    # Umieść to przed location dla PHP-FPM
    location ~ \.php$ {
        # Zwykła obsługa 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;
    }
}
# Sprawdź konfigurację Nginx i zastosuj ją
sudo nginx -t && sudo systemctl reload nginx

# Sprawdzenie
curl -o /dev/null -s -w "%{http_code}" https://example.com/wp-content/uploads/shell.php
# Jeśli wróci 403, wszystko działa

Krok 4: zablokuj wgrywanie PHP także od strony WordPress

// functions.php: całkowicie zabroń wgrywania plików PHP

// ① Dodaj rozszerzenia PHP do listy zabronionych typów wgrywania
add_filter('upload_mimes', function(array $mimes): array {
    // Usuń typy MIME związane z PHP (na wszelki wypadek)
    unset($mimes['php'], $mimes['phtml'], $mimes['phar']);
    return $mimes;
});

// ② Wykrywaj i odrzucaj pliki PHP wśród wgrywanych plików
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'] = 'Wgrywanie plików PHP jest zabronione.';
    }

    // Sprawdź także po typie MIME
    if (str_contains($file['type'], 'php')) {
        $file['error'] = 'Wgrywanie plików PHP jest zabronione.';
    }

    return $file;
});

Krok 5: skonfiguruj regularne monitorowanie

# Skrypt cyklicznie monitorujący pliki PHP w katalogu 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 "Ostrzeżenie: w katalogu uploads wykryto pliki PHP:
$PHP_FILES" | mail -s "[PILNE] Możliwe umieszczenie web shella w WordPress" "$ADMIN_EMAIL"

    # Automatyczne usuwanie (używaj ostrożnie)
    # find "$UPLOADS_DIR" -name "*.php" -delete
fi
EOF
chmod +x /usr/local/bin/check-uploads-php.sh

# Sprawdzaj co godzinę
echo "0 * * * * root /usr/local/bin/check-uploads-php.sh" > /etc/cron.d/wp-uploads-php-check

Uwagi

  • php_flag engine off w .htaccess działa tylko przy mod_php. Jeśli używasz php-fpm (FastCGI), zastosuj dyrektywę lub blok location w Nginx
  • W Nginx, jeśli reguły blokujące dla uploads nie znajdą się przed location ~ \.php$, może zadziałać ta druga i pliki zostaną wykonane. Reguły blokujące zawsze umieszczaj wyżej
  • Niektóre wtyczki (np. Slider Revolution) mogą umieszczać pliki .php w uploads. Przed usunięciem sprawdź ich przeznaczenie i dopiero po usunięciu niepotrzebnych wtyczek wprowadź blokadę

Podsumowanie

Blokadę wykonywania PHP w katalogu uploads realizujesz tak: ① wykrywasz i usuwasz istniejące podejrzane pliki przez find wp-content/uploads -name ".php", ② w Apache dopisujesz do uploads/.htaccess wpis Deny from all, ③ w Nginx stosujesz deny all w location ~ /wp-content/uploads/.*\.php$, ④ przez hook wp_handle_upload_prefilter odrzucasz samo wgrywanie PHP, ⑤ co godzinę monitorujesz pliki PHP w uploads przez cron.

Pytania o WordPress? Wydawca tej witryny ma siedzibę w Japonii i odpowiada po japońsku. Kontakt (po japońsku)

お気軽にご相談ください

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