Пользователь
0,0
рейтинг
6 июля 2010 в 11:22

Разработка → Ещё 10 уловок для защиты Wordpress'a перевод


На сегодняшний день Wordpress как никогда популярен. Блоги, мини-сайты, а то и целые порталы — всё это строится на основе такого удобного движка-конструктора как Wordpress. Но за удобностью и лёгкостью освоения кроются, прежде всего, вопросы, связанные с безопасностью вашего сайта. Большая распространённость — большее внимание злоумышленников.

В этой статье описаны десять простых уловок, которые позволят сделать ваш сайт на Wordpress’e ещё более защищённым и позволят спокойнее спать по ночам.

1. Защищаем Wordpress от XSS-инъекций


В чём проблема?
Программисты всегда стараются защитить GET- и POST- запросы, однако, иногда этого недостаточно. Необходимо защитить блог от XSS-инъекций и попыток модификации переменных GLOBALS и _REQUEST.

Что делаем?
Этот код блокирует использование XSS-инъекций и попытки модифицировать переменные GLOBALS и _REQUEST. Вставьте код в ваш файл .htaccess, расположенный в корне сайта. (И не забывайте бэкапить этот файл перед внесением любых изменений).

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]


Как это работает?
Код позволяет проверять все запросы. Если запрос содержит тег или попытку модифицировать значение переменных GLOBALS и _REQUEST, он просто блокирует его и выдаёт пользователю 403-ю ошибку.

2. Убираем показ лишней информации


В чём проблема?
Если при попытке зайти в админку Wordpress’a вы ошибётесь с логином или паролем, вежливый движок скажет вам об этом. Ну а зачем злоумышленнику знать, что пароль, который он пытается подобрать – неверен? Давайте просто уберём вывод этой информации и чуток запутаем его.

Что делаем?
Открываем functions.php, лежащий в папке с активной темой нашего блога (wp-content/themes/название-вашей-темы/) и добавляем следующий код:

add_filter('login_errors',create_function('$a', "return null;"));

сохраняем файл. Вуаля – больше никаких сообщений.

Как это работает?
С помощью этого хука мы переписываем стандартную функцию login_errors(). В результате этого, в случае, когда введены неправильный логин или пароль, никакой информации, объясняющей ситуацию не появится — то, что нам нужно.

3. Принудительное использование SSL


В чём проблема?
Если вы хотите, чтобы передаваемая вами информация была защищена, вам необходимо использовать SSL—протокол, обеспечивающий целостность и конфиденциальность обмена данными. В Wordpress’e это сделать проще простого.

Что делаем?
Прежде всего узнаём, есть ли возможность у вашего провайдера использовать SSL. Если да, то открываем файл wp-config.php (обитающий в корне сайта) и добавляем следующую строку:

define('FORCE_SSL_ADMIN', true);

Как это работает?
Всё просто. Wordpress использует множество констант и FORCE_SSL_ADMIN всего лишь одна из них. Эта константа включает принудительное использование SSL при заходе в панель администратора.

4. Используем .htaccess для защиты файла wp-config


В чём проблема?
wp-config.php содержит все данные, необходимые для подключения к серверу MySQL и базе данных. Защита этого файла – одна из самых главных задач.

Что делаем?
Находим файл .htaccess в корне нашего сайта и добавляем следующие строки:

<files wp-config.php>
order allow,deny
deny from all
</files>

Как это работает?
Мы просто запрещаем доступ к этому файлу кому бы то ни было. Теперь уж точно ни один бот не сможет и близко подойти к этому файлу.

5. Скрываем версию Wordpress'a


В чём проблема?
Wordpress автоматически вставляет номер своей версии в исходный код страниц. К сожалению, не всегда удаётся вовремя обновлять движок. А это означает, что зная какая у вас версия Wordpress’a со всеми её брешами и слабыми местами, злоумышленник может очень-очень огорчить вас. Что делаем? Правильно, убираем вывод версии.

Что делаем?
Снова открываем functions.php, лежащий в папке с активной темой нашего блога (wp-content/themes/название-вашей-темы/) и добавляем туда этот код -


remove_action('wp_head', 'wp_generator');

Как это работает?
Хуки Wordpress'a позволяют легко заменять одну функцию на другую. Именно этим мы сейчас и воспользовались – мы просто запретили вывод информации о версии нашего движка.

+ как справедливо указал пользователь rOOse, необходимо также удалить файл readme.html, находящийся в корне сайта. В нём тоже содержится информация о текущей версии Wordpress'a.

6. Баним спамеров и ботов



В чём проблема?
Надоедливые постеры и спамеры. Решение – запретить им доступ к сайту по IP. Конечно, это не защитит от спам-скриптов, постоянно меняющих прокси, но немного облегчить жизнь вполне может.

Что делаем?
Вставьте этот код в файл .htaccess. Просто поменяйте адрес 123.456.789 на IP того редиски нехорошего человека, который вас достаёт и всё — он забанен всерьёз и надолго.

<Limit GET POST PUT>
order allow,deny
allow from all
deny from 123.456.789
</LIMIT>


Как это работает?
И снова нам на помощь приходит apache. Посредством файла .htaccess мы запрещаем доступ к сайтe пользователям с конкретным IP. Нужно забанить ещё кого-то? Просто добавим ещё одну строку, к примеру -

deny from 93.121.788

7. Пишем плагин для защиты от зловредных url-запросов



В чём проблема?
Хакеры и недохакеры всех родов очень часто пытаются найти слабые места при помощи всевозможных зловредных запросов. Wordpress неплохо защищён от этого, но лишняя защита никогда не повредит.

Что делаем?
Создаём новый файл под названием blockbadqueries.php и помещаем его в папку wp-content/plugins. Затем просто активируйте его в админке как любой другой плагин.

<?php
/*
Plugin Name: Block Bad Queries
Plugin URI: perishablepress.com/press/2009/12/22/protect-wordpress-against-malicious-url-requests
Description: Protect WordPress Against Malicious URL Requests
Author URI: perishablepress.com
Author: Perishable Press
Version: 1.0
*/
global $user_ID;
if($user_ID) { if(!current_user_can('level_10')) { if (strlen($_SERVER['REQUEST_URI']) > 255 || strpos($_SERVER['REQUEST_URI'], "eval(") || strpos($_SERVER['REQUEST_URI'], "CONCAT") || strpos($_SERVER['REQUEST_URI'], "UNION+SELECT") || strpos($_SERVER['REQUEST_URI'], "base64")) { @header("HTTP/1.1 414 Request-URI Too Long"); @header("Status: 414 Request-URI Too Long"); @header("Connection: Close"); @exit; } } }
?>


Как это работает?
Работа этого плагина проста – он проверяет все длинные запросы (более 255 символов) и наличие php-функций eval или base64 в URI. Если что-то из этого находится, браузеру пользователя отдаётся страница с ошибкой 414.

8. Личеры!


В чём проблема?
Мир полон добрых людей, которые изо всех сил пытаются донести до других новость или статью, написанную вами. Всё бы ничего, но ведь по доброте душевной они берут картинки прямо с наших с вами серверов, скромно забывая при этом про слово «трафик». А теперь представьте что будет, если ссылки на наши картинки попадут на какой-нибудь популярный китайский блог, с их-то почти уже четырёхсотмиллионным интернет-населением! Свят-свят-свят… Значит сейчас будем защищать хотлинкинг, a.k.a. личинг, a.k.a. «да я просто вставил ссылки на файлы с вашего сервера».

Что делаем?
И опять всемогущий apache поможет защищить нам наш трафик. Достаём в очередной раз файлик .htaccess и пишем следующее:

RewriteEngine On
#Замените ?mysite\.ru/ на адрес вашего сайта
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?mysite\.ru/ [NC]
RewriteCond %{HTTP_REFERER} !^$
#Замените /images/nohotlink.jpg на название вашей картинки с лозунгом «личер идёт на…»
RewriteRule .*\.(jpe?g|gif|bmp|png)$ /images/nohotlink.jpg [L]


Как это работает?
При помощи этих правил мы заставляем сервер проверять откуда пришёл запрос на нашу фотку — если со страниц нашего сайта, он отдаёт её пользователю. Если с «вражеского» — то показывает личерам какую-нибудь обидную картинку.

9. Убить админа. (Нет дефолтному юзернейму «admin»)!



В чём проблема?
Злоумышленникам всегда проще получить доступ к сайту при помощи брута, если уже известен логин. При этом на протяжении многих лет дефолтный логин админа был примитивным до зубного скрежета — «admin».

Надо сказать, что в новом Wordpress 3.0 у вас есть право указать любой логин, какой только душе будет угодно. Для остальных версий нужно применить одно волшебное заклинание.

Что делаем?
Просто выполняем этот запрос к базе данных:

UPDATE wp_users SET user_login = 'Ваш новый логин' WHERE user_login = 'Admin';

Как это работает?
С помощью sql-запроса меняем дефолтный логин. Правда, есть одно «но». Посты, написанные ранее admin'ом не поменяют своего автора. А для того чтобы извести admin'a на корню, необходимо выполнить ещё один запрос:

UPDATE wp_posts SET post_author = 'Ваш новый логин' WHERE post_author = 'admin';

10. Защита директорий на сервере от просмотра


В чём проблема?
Очень многие хостеры позволяют просматривать директории на своих серверах. Поэтому, если ввести в адресную строку www.вашблог.ru/wp-includes, то очень часто можно увидеть всё содержимое этой директории. Безусловно это небезопасно, поэтому лучше это сразу запретить.

Что делаем?
Вы можете либо добавить пустые файлы index.html в папки, просмотр которых хотели бы запретить. Либо дополнить наш .htaccess ещё одной строкой:

Options All -Indexes

Как это работает?
Пустой index.html будет выдаваться каждый раз, когда последует запрос к директории. Ну а директива в .htaccess просто запрещает апачу выдавать список содержимого директории.
Перевод: Jean-Baptiste Jung
Андрей @Barkov
карма
27,9
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (73)

  • +2
    браво
  • +2
    2. Убираем показ лишней информации

    А разве и так не понятно, что если в админку не пустило, то пароль не верный? Хоть выводи сообщение хоть не выводи
    • НЛО прилетело и опубликовало эту надпись здесь
      • +3
        ну если ошибки такие выводит, то смысл в том чтобы их убрать есть конечно
      • 0
        Очень странное поведение по дефолту. Очень.

        И автор, и lukdiman правы абсолютно.
      • +1
        что-то у меня такого не наблюдалось!
        s49.radikal.ru/i125/1007/fa/f79aa5f46d95.png
        • +4
          Но ведь говорит «Неверный логин» вместо «Неверный логин или пароль», зачем давать лишнюю инфу взломщику?
      • +1
        и то хорошо, что пароль не подсказывает как логин=)
      • +2
        Тонкий юмор))

        Вордпресс не хранит открытые пароли, чтобы уметь подсказывать в каких символах пароля я ошибся. Только хеши
        • 0
          блин, я тоже повелся)
      • +2
        Извините, Вы не можете использовать указанный пароль. Такой пароль уже использует пользователь Misha. Пожалуйста, придумайте другой пароль.
        bash.org.ru/quote/399755
    • +2
      Если не пустило, то это совершенно не значит, что логин/пароль неправильные. Иногда глюки скриптов к такому приводят) Вот и пусть думают в чём проблема — неправильный пароль или нерабочая админка)
      • 0
        ну это глупо. тогда уж никого в админку не пустит и зачем туда вообще лезть если там ничего не работает
        • 0
          Я же написал «иногда». В смысле бывает такой глюк. То, что предлагается во втором пункте — всего лишь небольшая имитация этой ошибки)
    • 0
      тут ещё тот вакт что для автоматического подбора нужно определять ошибка или ок.
    • 0
      Надо не скрывать, а показывать!
      Переправить на статическую html-ку залогиненного пользователя.
      Вот это точно будет — «чуток запутаем его».
      • 0
        Ещё прикольнее переправлять на поддельный сайт, имеющий вид, похожий на настоящий
  • 0
    1,4,6,7,10 пункты подойдут не только тем кто пользуется wordpress, в общем взял на заметку
    • 0
      … но и всем, кто пишет на читстом пхп без фреймворков.
      • НЛО прилетело и опубликовало эту надпись здесь
  • –1
    Пункт 7: «страница с ошибкой 414.» — может 404?
    Пункт 8 взял на заметку
  • 0
    Так же, если есть возможность — можно поставить mod_security на апач.
    • 0
      эх, если бы WP нормально работал с mod_security, всё это можно было бы не писать.
  • +4
    Насчет личеров — ботам картинок гугла и яндекса доступ, все-таки, хорошо бы открыть.
    • 0
      а еще можно юзать CDN, благо амазон копейки берет.
  • +4
    Интересно почему заграничные чуваки так любят писать «10 приемов», «5 правил», «7 способов», «10 возможностей», «8 отличий», «6 уловок».
    А вот наши — нет. Наши сделают просто большую простыню текста.
    Из гордости за народ хочется предположить, что это от широты души и от необъятности просторов.
    • +2
      Мне кажется это все — развитый капиталистический мир маркетинга… :)

      Статью\книгу\заметку с «10 примерами» с большей вероятностью прочитают, чем простыню неопределенного размера. Клиповое сознание. А больше читателей = больше профита.
    • +1
      Неправда. Вы просто уже не застали учения в школе наизусть «пяти признаков империализма по работе В.И.Ленина „Империализм, как высшая стадия капитализма“ и прочих перлов Краткого курса истории ВКП(б).
  • +1
    Не совсем понял

    4. Используем .htaccess для защиты файла wp-config

    Ведь апач его и так не отдаст? Или нет?

    и

    9. Убить админа. (Нет дефолтному юзернейму «admin»)!

    UPDATE wp_posts SET post_author = 'Ваш новый логин' WHERE post_author = 'admin';

    разве не оптимальнее было бы давать юзерам id, чтобы не хранить тысячи «admin» вместо «1»? И запрос такой не нужен был бы…
    • 0
      Тоже сразу же задумался об этом.

      И индекс по post_author был бы попроще.
    • +2
      Денормализация снижает нагрузку на БД
      • 0
        Кеширование снижает нагрузку на БД. В т.ч. и кеширвание средствами самой БД.
        • 0
          Абсолютно согласен. Но денормализация тоже)
    • +1
      4. Используем .htaccess для защиты файла wp-config
      Ведь апач его и так не отдаст? Или нет?

      А всё зависит от прямоты рук админов. Может и отдать.
      • 0
        даже если отдаст, то отдаст исполнив php скрипт wp-config.php, в котором нет ни одной строчки вывода на экран, те получим чистую страницу 100%
        • +1
          я как то обнаружил на бесплатном хостинге что пхп вдруг запретили, вот от такого спасёт 100%.
          Если хорошенько погуглить можно найти конфиги в прямом доступе.
          • –1
            На настоящем бесплатном хостинге нет .htaccess :)
            Чтобы не отдал конфиг — его надо перенести на директорию ниже
        • НЛО прилетело и опубликовало эту надпись здесь
  • НЛО прилетело и опубликовало эту надпись здесь
    • +3
      кстати да, вот если бы автор переписал бы все рулесы и реврайты и аксессы на nginx, цены бы ему не было
      • 0
        Факт. Сам юзаю wp, и даже на минимальнейших нагрузках разница между апачем с энжиниксом и без него видна невооруженным взглядом. Так что неистово плюсую
    • +4
      Наверное, потому что большинству проще отредактировать .htaccess, чем колдовать в конфигах nginx)
  • 0
    • 0
      ссылка есть в посте, наведи на автора
    • 0
      Пардон. Не увидел ссылки в функциональном футере поста.

      Спасибо за перевод.
  • 0
    Неправильно переведен исходный текст «the login_errors() function» как «функция the login_errors()»
    • 0
      А как нужно?
      • 0
        просто «функция login_errors()»
        • 0
          Точно)
  • +6
    Ежегодная статья по защите WP на хабре.

    Хоть что-то не меняется
  • 0
    п.4
    доступ к этому сайту кому бы то ни было. Теперь уж точно ни один бот не сможет и близко подойти к этому файлу.

    Да, правильно — прикрыть доступ к сайту лучший способ его обезопасить xD
    • 0
      Спасибо, исправил.
  • +2
    Работа этого плагина проста – он проверяет все длинные запросы (более 255 символов) и наличие php-функций eval или base64 в URI.

    Судя по коду функции она делает не то что вы написали. Она проверяет ВСЕ запросы на наличие этих строчек и помимо этого выдает ошибку на запросах длиннее 255 символов. Сам код плагина тоже один из шедевров говнокодинга в общем то… Собачки перед header и exit, strpos вместо stripos да и само по себе куча strpos-ов подряд. Буэ…

    Вообще статья конечно совсем уж для чайников, многие предложения спорные.

    Еще забавно — частота, с которой в статье встречается слово «просто», сильно зашкаливает)
  • +1
    Насчет скрываем версию WordPress, я и на Smashingmagazine писал, что кроме generator, надо бы файл readme.html удалять, не видел еще чтобы кто-нибудь его удалял.
    • 0
      Спасибо, добавил в статью!
  • +1
    9. Убить админа. (Нет дефолтному юзернейму «admin»)!

    >UPDATE wp_users SET user_login = 'Ваш новый логин' WHERE user_login = 'Admin';

    Прячем админа.

    > UPDATE wp_posts SET post_author = 'Ваш новый логин' WHERE post_author = 'admin';;

    Указываем злоумышленнику на нового админа :)
    • +1
      Указываем злоумышленнику на нового админа :)

      А тут проще. В админке можно указать псевдоним, который будет выводиться как имя автора в постах.
      • 0
        Проблема в том, что выводится псевдоним, но урл на профиль выглядит как «www.имясайта.ru/author/admin/
        ВП версии 3,0,1
  • +1
    Статья интересная, но многие советы спорные.

    Например, стоило бы указать, что банить по ip надо весьма осторожно. Во-первых, этот метод может не работать, если спамер использует плавающий ip. Во-вторых, есть существенный риск забанить ip, отвечающий за целый регион, например, Поволжье, соответсвенно лишиться многих пользователей.

    Проблему личеров можно обойти еще проще — выкладывать картинки на крупные надажные фотохостинги, а не хранить у себя на серваке. Это еще и просто обычный трафик снижает. Риск потери доли поискового трафика мне кажется несущественным для большинства блогов.

    • 0
      или на dropbox
    • 0
      Проблему личеров можно обойти еще проще — выкладывать картинки на крупные надажные фотохостинги, а не хранить у себя на серваке.

      Даже крупные фотохостинги в последнее время стали баловаться заставками по типу «Bandwidth exceeded», так что это тоже не всегда выход.
  • 0
    5. тем самым и убираем копирайт вордпресса т.е powered by — плохо!
    • 0
      А кто мешает отдельно прописать копирайт в футере, к примеру?
  • 0
    кто-нить может пояснить, зачем писать плагин в п.7, когда проверить URI можно и рерайтом в п.1.
  • +2
    1. Если бы тут было применено это правило, то Вы бы не смогли запостить свою статью. Это в чистом виде лечение насморка отрубанием головы.
    4. ни от чего не защищает, так как добираться до этого файла обращаясь к нему никто не будет — только через уязвимости в других файлах.
    7 этот пункт спорный очень
    8 не все корректно отдают referrer. Сами дураки, конечно, но сути совета не меняет.
    В общем, как чтиво — нормально, как руководство к действию — очень неоднозначно.
    • 0
      не, (1) действует на %{QUERY_STRING} а это только GET запросы. Статья постится через POST))

      С выводом абсолютно согласен!
  • 0
    Что-то много лищнего имхо.

    Спамеры дохнут под акисмет
    Для персонального блога лучше просто запретить авторизацию и wp-admin по IP
    Личеры лично меня не беспокоят совершенно поскольку все картинки хранит пикаса.
  • –1
    Давно работаю с Wordpress, неплохие заметки. В принципе этот список можно легко продолжить, ждем продолжения.
  • +3
    1.
    Совершенно неоправдан с точки зрения использования XSS (защитит от банального <script>js code</script>, не более.
    Запрет переопределений через _REQUEST ни в какие ворота не лезет, вероятно вы не совсем понимаете смысла GPC и _request.
    Также не защитит от глобальных переопределений через extract, в принципе единственное что тут можно сделать — перейти на последний пхп, register_globals must die :)

    4.
    Единственное, от чего это может защитить — «падение» php, тоже не особо оправдано :)

    7.
    — Запрет eval() ничего не даст. Обычные ошибки движкописателей, при которых можно выполнять пхп код — это preg_replace с #e и, вероятно, create_function. В первом случае будут использоваться {${phpinfo()}}, во втором — в зависимости от ситуации, но вот eval() там точно не будет присутствовать :)
    — CONCAT — а что мешает хацкеру не использовать объединения?
    — UNION+SELECT — прямой вывод с помощью nion+select обходится многими способами.
    1) union/**/select
    2) подзапросы (просто select)
    3) вывод через ошибки duplicate и многие другие
    — base64 не единственная функция кодирования в пхп :))
    Но что реально тут поможет, или хотя бы затруднит хацкеру взлом, это фильтрация конкретно «select», «substring». Главное чтобы они не встречалось в ваших ЧПУ :)

    8. Ничто не мешает нам поставить реферер :)

  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      А можно это сделать на не вордпресс? Где нет RSS.
  • 0
    как вариант, еще можно добавить во все файлы php в директории /wp-content/ следующую строку

    error_reporting (0);

    Для примера: адрес blog.ru/wp-content/themes/twentyten/ выдаст нам ошибку обработки php, в котором будет раскрыт путь, и соответственно логин доступа с хостингу.

    Как это работает?
    Данная строка запрещает вывод ошибок php, то есть при ошибке в файле php не будут выведен путь к файлу с ошибкой.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.