PHP fopen / fwrite () / fclose ожидает, что параметр 1 будет ресурсом / не удалось открыть поток - PullRequest
0 голосов
/ 06 февраля 2019

я стараюсь отличным пользователям Ник (слова / ссылки).

-Words, хорошо работает

-проблемы не работают (я хочу, чтобы пользователи идентифицировали как ссылку) код

<!--
<!--
<?php
if (isset($_GET['enSubmit']) && isset($_GET['uname']) && isset($_GET['rname'])){
    echo'<meta http-equiv="refresh" content="10">';
    $room=$_GET['rname']; 
    $uname=$_GET['uname'];
    if (!is_dir($room)) mkdir($room);
    $files = scandir($room);
    foreach ($files as $user){
        if ($user=='.' || $user=='..') continue;
        $handle=fopen("$room/$user",'r');
        $time = fread($handle, filesize("$room/$user"));
        fclose($handle);
        if ((time()-$time)>20) unlink("$room/$user");
    }
    $contents='';
    $filename="$room.txt";
    if (file_exists($filename)){
        $handle = fopen($filename, "r");
        $contents = fread($handle, filesize($filename));
        fclose($handle);    
    }
    $handle = fopen("$room/$uname", "w");
    fwrite($handle, time());
    fclose($handle);

    $files = scandir($room);
    $users='';
    foreach ($files as $user) if ($user!='.' && $user!='..') $users.=$user."\n";

    if (isset($_POST['Send'])){
        $text=$_POST['txt'];
        $contents.="$uname: $text";
        $handle = fopen("$filename", "a");
        fwrite($handle, "$uname: $text\n");
        fclose($handle);
    }
?>
<body OnLoad="document.myform.txt.focus()">
<form action="" method="post" name="myform">

    <tr>

    <textarea readonly="readonly"  contenteditable="false"  name="txtusers" style=";width: 163px; height: 365px; background-color: #D1F8D8; font-family: 'times New Roman', Times, serif; font-size: 12pt; font-weight: bold; text-align: center;"><?php echo $users?></textarea></td>
    </tr>

   </table>
</form>

<?php
}else {
?>
   <form method="get" action="">
   <table style="border: 1px solid #000000;width: 452px" align="center">
   <tr>
   <td style="font-family: 'Times New Roman', Times, serif;font-size: 17pt;text-align: left; width: 432px; color: #2214B9;;border-style: solid;border-width: 1px;">Nick Name:</td>
    <td style="border-style: solid; border-width: 1px; font-family: 'Times New Roman', Times, serif; font-size: 17pt; text-align: left; color: #2214B9; width: 430px;">
    <input name="uname" style="font-size: medium; width: 260px; color: #B01919;"></td>
</tr>
     <tr>
     <td style="font-family: 'Times New Roman', Times, serif;font-size: 17pt;text-align: left; width: 432px; color: #2214B9;border-style: solid;border-width: 1px;">Select Room:</td>
    <td style="border-style: solid; border-width: 1px; font-family: 'Times New Roman', Times, serif; font-size: 17pt; text-align: left; color: #2214B9; width: 430px;">
    <select name="rname" style="width: 260px; font-size: medium; color: #B01919;">
    <option selected="">project 1</option>
    </select></td>
   </tr>
    <tr>

    <td style="font-family: 'Times New Roman', Times, serif;font-size: 17pt;text-align: center; color: #2214B9; border-left-style: solid; border-left-width: 1px; border-right-style: none; border-right-width: medium; border-top-style: solid; border-top-width: 1px; border-bottom-style: solid; border-bottom-width: 1px; padding-top:10px;padding-bottom:10px" colspan="2">
    <input name="enSubmit" style="width: 118px; height: 63px; font-size: 30pt; font-family: 'Times New Roman', Times, serif; color: #19B024;" type="submit" value="Enter"></td>
    </tr>
   </table>
    </form>
     <?php
     }
     ?>
      <script>
     el=document.myform.txtt
     if (typeof el.selectionStart == "number") {
     el.selectionStart = el.selectionEnd = el.value.length;
     } else if (typeof el.createTextRange != "undefined") {
     el.focus();
     var range = el.createTextRange();
     range.collapse(false);
     range.select();
     }</script>


    </body>

Допустим, я хочу, чтобы пользователи типа идентифицировали как ссылку, поэтому, когда я пытаюсь, например,

https://test.com/user_adam

, я получаю ошибку (это хорошо работает, если имя пользователя не имеет "/"):

Предупреждение: fopen (проект 1 / https://test.com/user_adam): не удалось открыть поток: нет такого файла или каталога в C: \ xampp \ htdocs \ linkey \ live.php в строке 24

Предупреждение: fwrite () ожидает, что параметр 1 будет ресурсом, bool указан в C: \ xampp \ htdocs \ linkey \ live.php в строке 25

Предупреждение: fclose () ожидает, что параметр 1 будет ресурсом,bool указан в C: \ xampp \ htdocs \ linkey \ live.php в строке 26

ссылка, которую я пробовал

http://localhost/linkey/live.php?uname=https://test.com/user_adam&rname=project%201&enSubmit=Enter

1 Ответ

0 голосов
/ 06 февраля 2019

Ладно, думаю, я понял это.

По сути, это неверный ввод, файл, с которым у вас проблемы, на основе ошибки

Предупреждение: fopen (проект 1 / https://test.com/user_adam): не удалось открыть поток: нет такого файла или каталога

Я действительно надеюсь, что у вас нет файлов с именем project 1/https://test.com/user_adam. Но, исходя из того, что вы говорите:

Допустим, я хочу, чтобы пользователи типа идентифицировали как ссылку, поэтому, когда я пытаюсь, например, https://test.com/user_adam, я получаю ошибку (это хорошо работает, если имя пользователя не имеет "/"):

А это:

http://localhost/linkey/live.php?uname=https://test.com/user_adam&rname=project%201&enSubmit=Enter

Что показывает мне, что uname = uname=https://test.com/user_adam и rname = rname=project 1. Или по-английски rnameпапка, а uname - это имя пользователя. Это все денди, пока вы не введете туда URL.

Я бы сделал что-то вроде этого:

 $uname=$_GET['uname'];
 $arr_name = expode('/', $uname); //this offers a small amount of protection too (see below)
 $uname = end($arr_name);

Что в данном случаеоставит $uname со всем после последнего / или user_adam. Тогда ваш путь станет project 1/user_adam.

Обратный путь в каталогах

Однако,Вы широко открыты для атак через каталоги (копаться в коде еще хуже, чем я подозревал).Именно здесь злоумышленник может передать подобные вещи (%2F - это / в кодировке URL)

  http://localhost/linkey/live.php?rname=..%2F..%2Fsomefolder&uname=foo&enSubmit=bar

Что это значит, scandir() будет искать эту папку ../../somefolder.Теперь скажите, что папка содержит все ваши PHP-файлы, затем откроет их и, вероятно, удалит их с помощью unlink:

if (isset($_GET['enSubmit']) && isset($_GET['uname']) && isset($_GET['rname'])){
    echo'<meta http-equiv="refresh" content="10">';

    $room=$_GET['rname'];  //../../somefolder
    $uname=$_GET['uname']; //foo

    if (!is_dir($room)) mkdir($room);

    $files = scandir($room); //../../somefolder
    foreach ($files as $user){
        //$user = somefile.php
        if ($user=='.' || $user=='..') continue; //fails (or false here)

        $handle=fopen("$room/$user",'r'); // ../../somefolder/somefile.php

        $time = fread($handle, filesize("$room/$user")); //time will be a non number string, likly
        fclose($handle);
        if ((time()-$time)>20) unlink("$room/$user"); //time() - string(or 0) is almost always > 20 ... or TRUE here.
    }
 ....
}

Вы можете проверить условие отмены связи здесь, предположив, что первая строка файла phpначинается с <?php.В любом случае мы можем предположить, что это будет нечисловая строка.Затем, когда он преобразуется в целое число (преобразованное путем вычитания), его числовое значение фактически равно 0. Тогда time() - 0 равно time(), что намного больше, чем 20.

  var_dump( (time()-'<?php')>20); //true

Песочница

И поскольку это условие не может остановить его, запускается следующий бит:

 unlink("$room/$user"); //unlink('../../somefolder/somefile.php')

По сути, передавая этот «материал», если я знаю местоположение файла PHP, который запускает пользовательPHP (на сервере) имеет доступ, я могу удалить его.Или я могу в принципе удалить любые «известные» файлы из любой папки на вашем сервере, к которой PHP может получить доступ.Как бы я их знал, ну все, что мне нужно сделать, это посмотреть URL в большинстве случаев.Я должен был проверить это, чтобы убедиться, но я не вижу ничего, что указывало бы, что это не будет работать.Не дай Бог кто-нибудь поместит туда ../../public_html и сотрет ваш сайт с лица земли (надеюсь, у вас есть резервные копии вашего сервера) ...

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

Это действительно важно, поэтому я подумал, что должен упомянуть об этом.

Приветствия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...