PHP: безопасный способ сохранения и отображения пользовательского кода из CodeMirror

Я настраиваю простой веб-редактор кода с помощью CodeMirror, чтобы помочь учащимся изучить основы HTML, CSS и JavaScript.

Я хочу, чтобы учащиеся могли сохранять свой код, чтобы он был виден в отдельном окне браузера с собственной ссылкой, которой можно поделиться с друзьями и семьей, чтобы продемонстрировать свою работу (например, mydomain.com/users/имя пользователя/test.html).

В настоящее время у меня есть следующий PHP, но я знаю, что мое использование $content совсем небезопасно:

if ($_POST['type'] == 'save') {

  $content = stripslashes($_POST['code']);
  $username = addslashes(strip_tags($_POST['username']))); //i.e. markrummel
  $filename = addslashes(strip_tags($_POST['filename']))); //i.e. test, index
  $ext = addslashes(strip_tags($_POST['filetype']))); //i.e. html, css, js
  $path = '/users/' . $username . '/';
  $URL = $path . $filename . '.' . $ext;

  file_put_contents($URL, $content);

}

В большинстве случаев $content должен быть безопасным HTML, CSS или JavaScript, например: <p>My name is Mark</p>, но я хочу быть готовым на случай, если что-то вредоносное будет помещено в редактор кода для сохранения.

Любые предложения о том, как я могу безопасно сохранить и отобразить их код? Есть ли способ изолировать/изолировать папку каждого пользователя от других пользовательских папок и остальной части веб-сайта?

Возможно, нет безопасного способа сделать это, и я не должен позволять никому, кому я не доверяю, сохранять код на моем сервере, но если есть безопасный способ сделать это... это было бы здорово для этого проекта! Если нет, то я придумаю что-нибудь другое.

Спасибо за любую помощь или понимание, которое вы можете предложить! -Отметка


person Mark Rummel    schedule 13.04.2012    source источник
comment
Вы должны во что бы то ни стало проверить ввод, по крайней мере, имя пользователя, имя файла и тип файла. В противном случае любой может разместить любые данные в любом месте вашей файловой системы и, возможно, выполнить любой код на вашем сервере.   -  person Gumbo    schedule 13.04.2012
comment
@Gumbo Спасибо за ваш комментарий! Я предполагаю, что проверка того, что filetype является только HTML, CSS или JS, защитит от таких типов файлов, как PHP , которые могут взаимодействовать с сервером, но могут содержать вредоносный код в HTML и JavaScript. Правильно? Что насчет CSS? Следует ли удалить некоторые вещи из $contents, чтобы сохранить большую часть кода, чтобы он отображался правильно, но удалял потенциально вредоносный код?   -  person Mark Rummel    schedule 13.04.2012
comment
Вы можете сделать так, чтобы все, что ниже /users/…, отображалось как обычный текст.   -  person Gumbo    schedule 13.04.2012
comment
@Gumbo Простой текст выглядит хорошим вариантом. Я нашел AddType text/plain .pl .cgi .php, но не знаю, как написать это в httacess, поэтому это применимо только к /users/.... Кроме того, какие еще расширения я хотел бы включить? .asp? Любые другие? Еще мне попадались: Options -ExecCGI AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi и <FilesMatch "\.(php|pl|py|jsp|asp|htm|shtml|sh|cgi)$"> ForceType text/plain </FilesMatch>. Это то, что нужно учитывать?   -  person Mark Rummel    schedule 13.04.2012
comment
Вы также можете использовать mod_rewrite.   -  person Gumbo    schedule 13.04.2012


Ответы (1)


addslashes и stripslashes здесь для вас вообще ничего не делают. Я не уверен, что вы пытаетесь с ними сделать, но сокращение строки не является полезной формой кодирования для обработки имени файла или действительно любого контекста, который вы, вероятно, встретите в веб-приложении.

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

$URL = $path . $filename . '.' . $ext;
file_put_contents($URL, $content);

Да, это серьезно небезопасно. Помещая сегменты .. в имя пользователя или имя файла, злоумышленник может хранить файлы вне корневого пути. С полным контролем имени файла, включая расширение, которое может включать исполняемые файлы, такие как .php или другие конфиденциальные файлы, такие как .htaccess. (Даже если $ext было ограничено известными значениями, в зависимости от ОС, под которой работает ваш сервер, также может быть возможно избежать добавления этого расширения.)

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

В большинстве случаев $content должен быть безопасным HTML, CSS или JavaScript.

Тогда ты уверен, что это безопасно?

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

Вы можете попытаться очистить отправленный HTML-код, чтобы он использовал только безопасные теги, но это трудно сделать правильно, и это бесполезно, если вы хотите разрешить пользователям запускать CSS/JS!

Есть ли способ изолировать/изолировать папку каждого пользователя от других пользовательских папок и остальной части веб-сайта?

да. Обслуживайте каждую область с другого имени хоста. например. поставить основной сайт на http://www.example.com/ с песочницами на http://tom.users.example.com/, http://dick.users.example.com/ и так далее.

Это предотвращает прямой межсайтовый скриптинг. Чтобы сайты-песочницы не могли считывать файлы cookie с основного сайта, убедитесь, что он также не запущен на example.com (перенаправьте его на www.example.com).

Это не совсем полноценная песочница. Если вам нужно убедиться, что сайты-песочницы не могут записывать файлы cookie на другие сайты (потенциально нарушая их, останавливая работу своих собственных файлов cookie, у вас нет другого выбора, кроме как запускать каждую песочницу в своем собственном полном домене. И если вам нужно защищаться от URL-подключений Java-плагина , каждой песочнице нужен свой IP-адрес. Это быстро обходится дорого! Но это менее серьезные атаки.

person bobince    schedule 14.04.2012