Comments 90
Люблю так делать на своих горячо любимых проектах. Впервые такую штуку увидел в IPB.
Хотя php_flag engine 0 для меня в новинку.
Хотя php_flag engine 0 для меня в новинку.
Самое забавное, что можно попробовать загрузить и перезаписать сам .htaccess :)
Поэтому нужен каталог с .htaccess, а в нем уже каталог с файлами.
Ну а самый лучший вариант это все же белый список с рассширениями.
Поэтому нужен каталог с .htaccess, а в нем уже каталог с файлами.
Ну а самый лучший вариант это все же белый список с рассширениями.
Запретить конкретно у .htaccess запись и всё. :)
Это усложняет решение и лишает его элегантности, но тоже вариант.
Это не спасет от переименования и залития нового файла с именем .htaccess
.htaccess нужно класть в другую директорию, повыше, оформляя в Directory или DirectoryMatch.
А если в ту дерикторию залить .htaccess c php_flag engine 1?
Т.к. свойства наследуются, то должно заработать.
Т.к. свойства наследуются, то должно заработать.
В httpd.conf Apache2.2 есть следующие строки:
Если не ошибаюсь, они как раз для этого и служат.
<FilesMatch "^\.ht"> Order allow,deny Deny from all Satisfy All </FilesMatch>
Если не ошибаюсь, они как раз для этого и служат.
Это служит что бы пользователь не мог скачать .htaccess обращаясь например example.com/.htaccess
К Php это отношение не имеет
К Php это отношение не имеет
Я обычно весь загружаемый контент выношу на отдельный поддомен, на котором вообще все скрипты отключены. В итоге не надо дополнительно настраивать конфигурацию веб-сервера для каталога + если поддомен на другом сервере, то и на скорости загрузки страницы это положительно скажется.
Интересна техническая сторона. Как файлы загруженные скриптами положить на другой сервер? Обычным аплоадом здесь не обойтись.
Это вы не подумав спросили :). Поддомен, домен. Соседняя директория с различной степенью «соседства».
ну почему же, соседство поддоменов — дело ясное
но "+ если поддомен на другом сервере" в комментарии присутствует
или же это уже чисто техническая составляющая серверов, а для скрипта- это будет происходит прозрачно и не нужно заморачиваться по поводу того, что поддомен физически находится на другом сервере.
но "+ если поддомен на другом сервере" в комментарии присутствует
или же это уже чисто техническая составляющая серверов, а для скрипта- это будет происходит прозрачно и не нужно заморачиваться по поводу того, что поддомен физически находится на другом сервере.
В большинстве случаев поддомен находится на том же сервере.
Если поддомен находится на другом сервере, то решить проблему можно так.
есть site.ru
все статические файлы находятся на i.site.ru
мы создаем временную папку site.ru/temp/, в которую кладем наши файлы. Там же файл htaccess ридонли, в котором никому доступ, кроме IP сервера i.site.ru
на i.site.ru по крону или как только загружен файл на site.ru/temp/ применяется такая конструкция:
Т.е. мы перекидываем файлы на отдельный домен. Ну и как сказал Insbrook:
Если поддомен находится на другом сервере, то решить проблему можно так.
есть site.ru
все статические файлы находятся на i.site.ru
мы создаем временную папку site.ru/temp/, в которую кладем наши файлы. Там же файл htaccess ридонли, в котором никому доступ, кроме IP сервера i.site.ru
на i.site.ru по крону или как только загружен файл на site.ru/temp/ применяется такая конструкция:
$uploaddir = «temp_folder/»;
$host = $_POST[«host»]; //ccылка вида habrahabr.ru/file.jpg
$expansion = strtolower(strrchr($host, ".")); //выясняем расширение файла в строке
$filename = $uploaddir.«temp_file».$expansion; //полный путь загруженного файла
ini_set('max_execution_time',600);//устанавливаем время работы скрипта
//закачка
$fp=fopen($filename,«w»);//создаем пустой файл
fclose($fp);
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $host);//запускаем сеанс curl
$fp=fopen($filename,«w+»);//открываем файл для записи
curl_setopt($ch, CURLOPT_FILE, $fp);// записываем в файл
curl_setopt($ch, CURLOPT_REFERER, $host);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_exec ($ch);//выполняем команды curl
curl_close ($ch);//завершаем сеанс curl
fclose ($fp);//закрываем файл
$new_file = «новая папка/новое имя файла»; //полный НОВЫЙ путь загружаемого файла
rename($filename, $new_file); //перенесли файл в новое место
@unlink( $filename );
Т.е. мы перекидываем файлы на отдельный домен. Ну и как сказал Insbrook:
Я обычно весь загружаемый контент выношу на отдельный поддомен, на котором вообще все скрипты отключены.
как насчёт
<Files ~ "\.(php[2-5]?|cgi|pl|fcgi|fpl|phtml|shtml|asp|jsp)$"> Deny from all </Files>
Попробуйте скопировать в эту папку file.php.txt (с каким-нибудь echo) и открыть в браузере =)
И что будет?
Мне правда интересно.
Мне правда интересно.
Если в настройках сервера не прописан ContentType для .txt, он может запуститься как php
Все немного сложнее
seclists.org/bugtraq/2004/Dec/0211.html
www.net-security.org/vuln.php?id=3896
Разработчики называют это «фичей».
А файл можно переименовать и в file.php.xxx (найти неуказанное расширение не проблема).
seclists.org/bugtraq/2004/Dec/0211.html
www.net-security.org/vuln.php?id=3896
Разработчики называют это «фичей».
А файл можно переименовать и в file.php.xxx (найти неуказанное расширение не проблема).
Именно поэтому очень полезно php_flag engine 0 :)
Разработчикам апача надо за такое отрывать руки, так как это открывает потенциальную уязвимость.
Хакеру на заметку: многие службы позволяют зарузить файл rar, но сервера при этом не знают такого расширения, и отдают его как text/plain, вполне возможно что file.php.rar может произвести желаемый эффект. Найти бы парочку адресов для проверки :)
Хакеру на заметку: многие службы позволяют зарузить файл rar, но сервера при этом не знают такого расширения, и отдают его как text/plain, вполне возможно что file.php.rar может произвести желаемый эффект. Найти бы парочку адресов для проверки :)
Может и производит, проверял :)
Идиотизм, ведь такую уязвимость очень легко оставить. Параноидальные идеи, типа проверять все части расширения, глупы, так как имя файла вполне может содержать .php., например manual.php.chm. Фигня какая -то, мне даже сказать нечего, почему нельзя было сделать опцию множественных расширений по умолчанию отключеннной. Апач — кривая фигня, чесслово, из-за таких вот «багофич» (аналогичная багофича, это выставление неправильного DOCUMENT_ROOT при использовании VirtualDocumentRoot), которые придуманы только чтобы ломать мозг разработчикам.
.htaccess
не?
Options None Options +FollowSymLinks
не?
к сожалению, хоть это и действенный способ, способ не «универсальный». Хотя лучшего предложить не могу.
Это казалось очевидным все это время, но мало кто это реализовывает.
Если вы уверены, что ваш проект всегда будет работать на Apache, то почему бы и нет?
Но если он может работать еще и на других серверах, то все равно приходится задуматься о защите в самих скриптах. Ну а раз об этом пришлось задуматься, то зачем городить всякие штуки вроде .htaccess?
Красиво, и обязательно к использованию :)
А почему просто не допускать банальнейшую ошибку локального инклюда?
При правильной архитектуре она исключена.
При правильной архитектуре она исключена.
Почему бы просто не пропускать php и тп скрипты?
<FilesMatch ".*">
Order allow,deny
Deny from all
<FilesMatch "\.(список_легетимных_расширений через |)$|^$">
Order deny,allow
Allow from all
Возможно, более верный вариант, незачем баловать «злоумышленников» даже выводом в формате html. А вообще, вернее проверять все на уровне скриптов- загрузчиков.
Обычная ситуация — на сервере находится локальный инклуд, находится компонент, позволяющий закачать данные на сервер(аплоад картинок, документов, аватарок и т.д.), локальным инклудом открывается эта картинка, аватар, в ней есть кусочек пхп кода, например в мета-полях картинки или тупо в конце, злоумышленник получает доступ, и никакой .htaccess тут не поможет.
В IIS в свойствах каталога ставится «Разрешать запуск: ничего».
На некоторых хостингах запрещены в целях безопасности все конфиги php из htaccess.
Все картинки и пр. сохранять на субдомен, на котором отключать выполнение скриптов на корню. Самый верный способ.
добавлю немного: recoilme.ru/blog/comments/237
Никто не мешает в nginx добавить location, который будет блокировать обращение к определенным типам файлов по расширению или просто не передавать их на обработку php. Первый вариант:
location ~ (^\dirname.*\.php$){
deny all;
}
Это только для php, для остального несложно дополнить.
А вопрос с неотдачей а обработку php решается просто более точным прописыванием того, что отдавать таки можно.
location ~ (^\dirname.*\.php$){
deny all;
}
Это только для php, для остального несложно дополнить.
А вопрос с неотдачей а обработку php решается просто более точным прописыванием того, что отдавать таки можно.
Про nginx. Обычно нужно разрешить лишь ограниченное число URL'ов, через которые вызывается PHP код (например, в Drupal только /index.php и, с localhost, /cron.php). Поэтому только их и передаём в PHP, остальное отдаём просто как статику.
У меня есть несколько работающих примеров, можно посмотреть тут.
У меня есть несколько работающих примеров, можно посмотреть тут.
и Deny from all более универсально. имхо
Просто на заметку.
Правило в htaccess:
Или проверка при загрузке:
Это все не работает на файлах с двойным расширением file.php.txt (при чем последнее — не php), а они, между тем, на большинстве хостингов обрабатываются apache как скрипты.
Правило в htaccess:
<Files ~ "\.(php[2-5]?|cgi|pl|fcgi|fpl|phtml|shtml|asp|jsp)$"> Deny from all </Files>
Или проверка при загрузке:
<?php $filename = 'file.php'; $pos = strrpos($filename, '.'); $ext = ($pos !== false ? substr($filename, $pos + 1) : ''); if (in_array($ext, array('php', '...'))) die('forbidden'); ?>
Это все не работает на файлах с двойным расширением file.php.txt (при чем последнее — не php), а они, между тем, на большинстве хостингов обрабатываются apache как скрипты.
а вы при заливке файлов на сервер расширенине не проверяете?
pathinfo() отличная функция.
Для своего блога давно такой .htaccess написал
Я правильно понимаю, что если на сайте нет каких-либо скриптов по закачке чего-либо, можно не беспокоиться?
способ старый, но есть один минус когда используешь в качестве закачки файлов fckeditor (fckeditor.net), на некоторых серверах, по непонятным причинам fckeditor начинает ругаться на папку если в ней есть такой .htaccess и не закачивает файлы.
Ох. Опять велосипеды.
Для этих целей есть RemoveType, кроме того, нужно отключить SSI в HTML, иначе я смогу включить любой файл или сделать exec. Потом надо запретить действие .htaccess для этого каталога (тут уже писали как). Может и ещё что-то упустил с утра (только проснулся, лёг поздно).
В общем, ваш совет вредный.
Для этих целей есть RemoveType, кроме того, нужно отключить SSI в HTML, иначе я смогу включить любой файл или сделать exec. Потом надо запретить действие .htaccess для этого каталога (тут уже писали как). Может и ещё что-то упустил с утра (только проснулся, лёг поздно).
В общем, ваш совет вредный.
вот у меня с этим была беда в своё время.., ломали сайт, а я никак не могу понять как)))))
следы все подтирали за собой… потом разобрался и закрыл дырку иенно таким способом!
следы все подтирали за собой… потом разобрался и закрыл дырку иенно таким способом!
имхо,
отдавать контент скриптами. все, кто запрашивает недопустимые типы — получают
header(«HTTP/1.1 403»);
отдавать контент скриптами. все, кто запрашивает недопустимые типы — получают
header(«HTTP/1.1 403»);
В общем, как я понял, единственный *действительно* надежный способ — проверять расширение загружаемых файлов (например, только картинки).
Из моего опыта.
1. Все пользовательские файлы(аватарки, картинки, приложения) закачиваем, используя ftp функции. Таким образом нам удается полностью отказаться от прав 0777 и это будет работать везде.
2. Директории кешей, а также smarty-вские templates_c тупо закрываем .htaccess deny from all
3. Предложенный автором способ хорош, но не будет работать на некоторых хостингах с fast-cgi php.
1. Все пользовательские файлы(аватарки, картинки, приложения) закачиваем, используя ftp функции. Таким образом нам удается полностью отказаться от прав 0777 и это будет работать везде.
2. Директории кешей, а также smarty-вские templates_c тупо закрываем .htaccess deny from all
3. Предложенный автором способ хорош, но не будет работать на некоторых хостингах с fast-cgi php.
При закачке меняю расширение на ожидаемое и все.
location ~ "^/([^\/]+|admincp/.+|modcp/.+)\.php$" {
fastcgi_pass unix:/tmp/php-fcgi.socket;
fastcgi_index index.php;
fastcgi_param script_FILENAME /usr/local/www$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
location ~ \.php$ {
internal;
}
Один из вариантов для nginx. Кусок конфига от форума с вбуллетином.
fastcgi_pass unix:/tmp/php-fcgi.socket;
fastcgi_index index.php;
fastcgi_param script_FILENAME /usr/local/www$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
location ~ \.php$ {
internal;
}
Один из вариантов для nginx. Кусок конфига от форума с вбуллетином.
в принципе если речь только о заливке картинок то можно после заливки пересоздавать картинку через imagecopyresampled, но эт как дополнение к коду в htaccess`e.
После того, как через дырявый аплоадер старго фцкедитора залили спам рассыльщик и фишинг страницу в папке всех проектов с правами на запись всегда в корне есть файлик
.htaccess
RemoveHandler .php .phtml .php3
AddType application/x-httpd-php-source .php .phtml .php3
RemoveHandler .htm .html
AddType application/x-httpd-php-source .htm .html
.htaccess
RemoveHandler .php .phtml .php3
AddType application/x-httpd-php-source .php .phtml .php3
RemoveHandler .htm .html
AddType application/x-httpd-php-source .htm .html
это лучше сделать сразу в httpd.conf (ну или vhosts.conf, кому как удобней) в секцию и добавить AllowOverride None. И тогда закачивай любой .htaccess — его апачь не будет признавать никак.
А зачем вообще позволять закачивать файлы с такими расширениями? Обычно от юзера требуется jpg, png, gif или на крайний случай архив. Почему просто в самом скрипте закачки не поставить проверку на тип файла и не давать закачивать файлы с расширениями .html, .php, .phtml и т.д.?
AddType «text/html» .php .cgi .pl .fcgi .fpl .phtml .shtml .php2 .php3 .php4 .php5 .asp .jsp
А про XSS не забыли?
А про XSS не забыли?
Sign up to leave a comment.
Превентивная защита ваших и не ваших скриптов