Проверка правильности ввода PHP для одного ввода для URL - PullRequest
0 голосов
/ 23 февраля 2009

У меня есть очень простой скрипт, который позволяет пользователю указывать URL любого сайта. Сценарий заменяет URL-адрес атрибута «data» в теге объекта для отображения сайта выбора пользователя внутри объекта на странице HTML.

Как я могу проверить ввод, чтобы пользователь не мог загрузить ни одну страницу с моего сайта внутри объекта, потому что я заметил, что он отобразит мой код.

Код:

 <?php
 $url = 'http://www.google.com';
 if (array_key_exists('_check', $_POST)) {
    $url = $_POST['url'];
 }
 //gets the title from the selected page
 $file = @ fopen(($url),"r") or die ("Can't read input stream");
 $text = fread($file,16384);
 if (preg_match('/<title>(.*?)<\/title>/is',$text,$found)) {
         $title = $found[1];
 } else {
         $title = "Untitled Document";
 }
 ?>

Редактировать: (подробнее) Это НЕ предназначено для прокси. Я позволяю пользователям решать, какой веб-сайт загружается в тег объекта (аналогично iframe). Единственное, что собирается прочитать php - это тег title из входного URL, чтобы его можно было загрузить в заголовок моего сайта. (Не беспокойтесь, это не обманывает пользователя) Хотя он может отображать заголовок любого сайта, он не будет обходить никакие фильтры любым другим способом.

Я также знаю об уязвимостях, связанных с тем, что я делаю, поэтому я смотрю на проверку.

Ответы [ 4 ]

3 голосов
/ 23 февраля 2009

Как сказал гаууа, я думаю, вам нужно быть очень осторожным с тем, что вы делаете здесь, потому что вы играете с огнем. Это можно сделать безопасно, но будьте очень осторожны с тем, что вы делаете с данными из URL, который дает вам пользователь.

Хотя для конкретной проблемы, с которой вы столкнулись, я предполагаю, что это произойдет, если вы получите ввод имени файла, например, если кто-то введет «index.php» в поле. Все, что вам нужно сделать, это убедиться, что их URL начинается с "http://", чтобы fopen использовал сетевой метод, а не открывал локальный файл. Примерно так, прежде чем строка fopen должна выполнить свою задачу:

if (!preg_match('/^http:\/\//', $url))
    $url = 'http://'.$url;
3 голосов
/ 23 февраля 2009

parse_url: http://us3.php.net/parse_url

Вы можете проверить схему и хост.

Если схема http, то убедитесь, что хост не является вашим сайтом. Я бы предложил использовать preg_match, чтобы получить часть между точками. Как и в www.google.com или google.com, используйте preg_match, чтобы получить слово google.

Если хост является ip, я не уверен, что вы хотите сделать в этой ситуации. По умолчанию соответствие preg получит только средние 2 числа и точку (при условии, что вы попытаетесь использовать preg_match, чтобы получить имя узла перед .com)

2 голосов
/ 23 февраля 2009

Вам известно, что вы создаете открытый HTTP-прокси, что может быть очень плохой идеей?

Вам даже нужно получить содержимое URL? Почему бы вам не позволить браузеру вашего пользователя сделать это, указав URL-адрес?

Предполагая, что вам нужно получить URL, рассмотрите возможность проверки по известному «белому списку» URL. Если вы не можете ограничить его известным списком, вы снова вернетесь к открытому прокси ...

Используйте регулярное выражение (preg), чтобы убедиться, что это хороший URL-адрес HTTP, а затем используйте расширение CURL для выполнения фактического запроса.

Смешивание семейства функций fopen () с предоставленными пользователем параметрами - это рецепт для потенциальной катастрофы.

0 голосов
/ 25 мая 2017

Вы можете использовать PHP-фильтр.

filter_var ($ url, FILTER_VALIDATE_URL) или вход_фильтра (INPUT_POST, 'url', FILTER_VALIDATE_URL);

http://php.net/manual/en/function.filter-input.php

Также попробуйте эти документы, на которые ссылается этот пост вики, посвященный фильтру https://wiki.php.net/rfc/add_validate_functions_to_filter?s[]=filter Ясуо Охгаки

...