Krzysiek Dróżdż
krzysiek@wpmagus.pl
WPmagus.pl
I to nic nie zmienia :(
Znacznie częstsze niż myślisz!
Dowiedzieliśmy się jak:
https://wpmagus.pl/pliki/prezentacje/bezpieczny-kod-trzy-latwe-kawalki/
Tworząc zabezpieczenia kodu musimy zadbać, żeby nie dało się ich ominąć.
W szczególności niebezpieczny/niezabezpieczony kod NIGDY nie powinien być samodzielny.
Jeśli aplikacja ma tylko jedno wejście, to łatwiej jest go pilnować.
Zamiast
<form action="<?php echo plugins_url( 'process-form.php', __FILE__ ); ?>" method="POST">
Użyj
<form action="<?php echo site_url('/'); ?>" method="POST">
Zamiast
if ( $action == 'save_file' ) {
include "process-form.php";
}
użyj
function process_form() {...}
if ( $action == 'save_file' ) {
process_form();
}
Jest admin-ajax.php
, ale także admin-post.php
, czyli
<form action="<?php echo admin_url('admin-post.php'); ?>" method="POST">
a potem w zależności od przeznaczenia:
add_action( 'wp_post_my_process_form', 'my_process_form_callback' );
lub:
add_action( 'wp_post_nopriv_my_process_form', 'my_process_form_callback' );
Zagadka: O czym zapomniałeś, zabezpieczając dostęp do katalogu wp-admin
?
A gdyby tak wcale się nie włamywać…
… tylko sprawić, żeby użytkownik zrobił coś za nas?
Weryfikować pochodzenie requestów
A może…:
A nazwiemy to… number used once lub krócej… nonce
w linkach:
$complete_url = wp_nonce_url( $bare_url, 'my-action_'.$post->ID );
w formularzach:
wp_nonce_field( 'my-action_'.$post->ID );
gdzie indziej:
$nonce = wp_create_nonce( 'my-action_'.$post->ID );
w panelu admina:
check_admin_referer( 'my-action_'.$post->ID, 'query_arg' );
w requestach AJAX:
check_ajax_referer( 'my-action_'.$post->ID, 'query_arg' );
gdzie indziej:
wp_verify_nonce( $_REQUEST['query_arg'], 'my-action_'.$post->ID );
Każdy plik wgrany na serwer to potencjalne zagrożenie.
Uważaj na to, co pozwalasz wgrywać.
Zabezpiecz się przed tym, co zostało wgrane.
Co tu jest nie tak?
if ( isset( $_FILES['mal_file'] ) ) {
$fname = $_FILES['mal_file']['name'];
$upload_dir = wp_upload_dir();
move_uploaded_file(
$_FILES['mal_file']['tmp_name'],
$upload_dir['path'] .'/'. $fname
);
$file = $upload_dir['url'] .'/'. $fname;
}
Tak będzie lepiej…
$uploaded_file_data = $_FILES['file'];
$upload_overrides = array( 'test_form' => false );
$uploaded_file = wp_handle_upload( $uploaded_file_data, $upload_overrides );
Co znajdzie się w $uploaded_file
?
… lub informacja o błędzie.
Jeśli mają być niedostępne dla wszystkich, to losuj nazwy.
Zablokuj dostęp do .php
<FilesMatch "\.(?i:php)$">
<IfModule !mod_authz_core.c>
Order allow,deny
Deny from all
</IfModule>
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
</FilesMatch>
i zablokuj hotlinkowanie
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(www\.)?yourwebsite\.com/ [NC]
RewriteRule .*$ http://yourwebsite.com/ [NC]
Zagadka: A co, jeśli wgramy kod PHP, jako .jpg, a potem go zainkludujemy?
Krzysiek Dróżdż
krzysiek@wpmagus.pl
WPmagus.pl