WordPress: 9 дірок, які знаходить наш аудит - і як їх закрити
3 хв читанняWordPressбезпекааудит
Не загальний список порад, а рівно те, що перевіряє наш безкоштовний аудит по кожному сайту. З кодом для кожного пункту.
Наш безкоштовний аудит перевіряє сайт за понад шістдесятьма пунктами, девʼять з них - про безпеку. Нижче всі девʼять, у тому порядку важливості, який використовує сам аудит: спочатку критичні, потім важливі, потім дрібні, але безкоштовні.
Критичні: знаходяться за хвилину скануванням
1. .env і .git відкриті назовні. У .env лежать паролі до бази й ключі платіжних систем, у .git - уся історія коду. Автоматичні сканери щодня перевіряють ці адреси на кожному сайті, який їм трапляється - питання не «чи знайдуть», а «коли».
<FilesMatch "^\.(env|git)">
Require all denied
</FilesMatch>
RewriteRule ^\.git - [F,L]2. http не переводить на https. Хто зайшов без шифрування, лишається на незахищеному звʼязку - у публічному Wi-Fi пароль і дані форми видно відкритим текстом. Google до того ж рахує http- і https-версію двома різними сайтами.
Виправлення - постійний 301-редірект на рівні сервера, а не в PHP: WordPress, завантажений лише для того, щоб перенаправити на себе ж, - зайва секунда на кожен неправильний запит.
Важливі: не критично, але дорога прогалина
3. /wp-json/wp/v2/users віддає логіни адміністраторів будь-кому. Половина злому - вгадати логін; тут його вгадувати не треба, WordPress називає його сам.
add_filter( 'rest_endpoints', function ( $endpoints ) {
if ( is_user_logged_in() ) {
return $endpoints;
}
unset( $endpoints['/wp/v2/users'] );
unset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] );
return $endpoints;
} );4. Немає HSTS. Без цього заголовка перший захід на сайт усе одно йде відкритим http, навіть коли редірект на https налаштований, - і саме той перший запит можна перехопити. Браузер має знати наперед, що сюди можна заходити лише через https.
add_action( 'send_headers', function () {
header( 'Strict-Transport-Security: max-age=15552000; includeSubDomains' );
} );5. Сайт можна вбудувати в чужу сторінку. Без заборони на фрейми хтось інший вставляє ваш сайт у невидимий iframe і накриває його своїми кнопками: людина думає, що тисне у вас, а тисне в них. Для кабінету чи форми замовлення це вже гроші, а не абстрактний ризик.
add_action( 'send_headers', function () {
header( 'X-Frame-Options: SAMEORIGIN' );
} );6. Куки сесії без Secure і HttpOnly. Без HttpOnly куку прочитає будь-який сторонній скрипт на сторінці, без Secure вона їде відкритим каналом. Якщо це кука сесії адміністратора - украсти її означає зайти на сайт замість нього.
Тут є пастка, характерна саме для WordPress за проксі чи CDN: ядро вирішує, чи ставити прапорець Secure, за функцією is_ssl(), а вона дивиться на $_SERVER['HTTPS']. Якщо TLS завершується на CDN, а не на самому сервері, WordPress цього не бачить і тихо не додає Secure, навіть коли відвідувач насправді на https.
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] )
&& $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ) {
$_SERVER['HTTPS'] = 'on';
}Дрібні: але безкоштовні
7. readme.html і xmlrpc.php відкриті. readme.html прямо називає версію WordPress - скануванню лишається звірити її зі списком відомих дірок. xmlrpc.php дозволяє перебирати сотні паролів за один запит.
Той самий фільтр, що ми давали в статті про швидкість заради економії запиту, тут працює заради безпеки - вимкнути xmlrpc, якщо ним нічого не користується.
add_filter( 'xmlrpc_enabled', '__return_false' );8. Сервер називає свою версію. Заголовок на кшталт X-Powered-By: PHP/7.4 підказує зловмиснику, який саме набір відомих вразливостей пробувати першим. Не діра сама по собі - безкоштовна підказка.
9. Немає Content-Security-Policy. CSP - це список того, звідки сторінці дозволено вантажити скрипти. Без нього чужий скрипт, що потрапив через вразливий плагін чи скомпрометовану рекламну вставку, виконується нарівні з вашим власним кодом.
CSP - єдиний пункт із девʼяти, який не можна просто увімкнути: спершу треба зібрати, які домени сайт справді використовує. Почніть з Content-Security-Policy-Report-Only, подивіться в консоль браузера тиждень, і лише тоді вмикайте по-справжньому.
Жодного з цих дев'яти пунктів не видно на головній сторінці - вони не впливають на те, як сайт виглядає, тому їх ніхто не помічає, поки не стане пізно. Саме тому аудит перевіряє їх автоматично, а не сподівається, що хтось згадає про це сам.
