2010-08-05 4 views
6

Я использую UNLINK с PHP и AJAX. Я знаю, что таким образом очень опасно, потому что каждый может удалить любые файлы. Но мне нужно использовать AJAX, потому что я не могу перезагрузить страницу при удалении файлов.Как избежать рисков безопасности UNLINK в PHP?

Так как мне сделать, чтобы разрешить удалять файл только для пользователя, которому это принадлежит?

Пожалуйста, дайте мне знать, и другие вещи, если вы думаете, что я здесь делаю что-то неправильно или что-то другое, что вы имеете в виду, и вы думаете, что это будет полезно:)

Мой PHP код:


<?php 

    $photo_id  = $_GET['photo_id']; 
    $thumbnail_id = $_GET['thumbnail_id'];  

    function deletePhotos($id){ 
     return unlink($id); 
    } 

    if(isset($photo_id)){ 
     deletePhotos($photo_id); 
    } 
    if(isset($thumbnail_id)){ 
     deletePhotos($thumbnail_id); 
    } 


?> 

Мой AJAX код:


function deletePhoto(photo, thumbnail){ 

     var photos = encodeURIComponent(photo); 
     var thumbnails = encodeURIComponent(thumbnail); 

     if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari 
      xmlhttp=new XMLHttpRequest(); 
     } else {// code for IE6, IE5 
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
     } 

     xmlhttp.onreadystatechange=function() { 
      if (xmlhttp.readyState==4 && xmlhttp.status==200) { 
       document.getElementById("media").innerHTML=xmlhttp.responseText; 
      } 
     } 
     xmlhttp.open("GET", "http://192.168.2.104/images/users/delete_photo.php?photo_id="+photos+"&thumbnail_id="+thumbnails, true); 
     xmlhttp.send(); 
    } 
+0

AJAX не имеет ничего общего с безопасностью. С точки зрения сервера, вызов AJAX ничем не отличается от обычного. Ваша проблема не в AJAX, а в отсутствии авторизации. Раньше вы это понимаете, скорее решите свою проблему. –

+0

Привет @Col. Шрапнель, я не думаю, что вы абсолютно правы, потому что без 'AJAX' мне не нужно делать файл, доступ к которому у кого угодно, и может удалить что-либо с помощью запроса GET. В противном случае я знаю, что проблема здесь в авторизации, поэтому я задал этот вопрос: «Как я могу сделать, чтобы удалить файл только для пользователя, который его владеет?» – Adam

+0

как вы можете позволить пользователю удалить файл без таких скрипт? –

ответ

7

Необходимо как-то аутентифицировать пользователя.

Ваш пользователь должен быть аутентифицирован с именем пользователя и паролем.

PHP-сессия может использоваться для запоминания, и вы должны использовать таблицу базы данных или текстовый файл на сервере для хранения информации о собственности на файл.

Затем, прежде чем отменить что-либо, ваша логика должна убедиться, что текущий «аутентифицированный» пользователь является владельцем файла.

+0

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

+0

, поэтому вам необходимо сохранить права собственности на файл в другой таблице, и перед тем, как отменить что-либо, вы убедитесь, что «аутентифицированный» пользователь является владельцем файла. –

+0

Единственный разумный ответ здесь. @CIRK выслушайте этот комментарий выше. это единственное решение. Вы идете совершенно неправильно. AJAX не является вашей проблемой –

2

Ограничить снятие ссылки с каталога с фотографиями. То есть, не разрешайте .. в пути или проверяем полный путь после выполнения realpath(). В противном случае пользователь может запросить delete_photo.php?photo_id=../../../../etc/passwd и разбить систему.

+0

Если они кодируют «..» в другом наборе символов, это может потенциально пройти. Я читал об этом в прошлом. –

+0

@Wadih да, но это был недостаток (я думаю, в Apache), который был исправлен с тех пор. –

+1

Если php работает как root, я думаю, что у вас больше проблем на руках. – rook

1

В вашем PHP:

  • Убедитесь, что $ _GET [ 'photo_id'] и $ _GET [ 'thumbnail_id'] не содержат "../"
  • Также убедитесь, что вы предварять BasePath к ID.

В противном случае пользователи могут удалить любой файл.

Что касается собственности, вы должны хранить информацию, которая владеет файлом где-то на стороне сервера (например, MySql-DB). Затем перед удалением файла необходимо проконсультироваться с этим местом.

-1

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

(кто-то однажды сказал мне, что файлы были файлами, а базы данных были для данных, а все они разные, но, как я вижу, файлы все равно содержат данные. Mysql имеет идеальный тип LONGBLOB для ввода чего-либо, и вы можете хранить метаданные, такие как тип файла и имя файла, в отдельных полях в той же строке данных, что сохраняет чистоту и простоту)

+0

В случае с изображениями я не думаю, что это хорошая идея хранить их в базе данных (по соображениям производительности). Причина при их отображении вам нужен скрипт PHP для чтения из базы данных. Поскольку изображения представляют собой отдельные HTTP-запросы, это приведет к нескольким подключениям к базе данных, которые необходимо установить. – JochenJung

+0

+1 это хорошая идея. – rook

+0

Fyi, Microsoft SharePoint 3.0 делает это (сохраняет файлы в БД). Я не обязательно согласен с этим решением, так как я сторонник того, что «файловая система» должна использоваться для хранения «файлов» и «баз данных» для табличных данных. Но эта схема проектирования имеет смысл в некоторых сценариях. –

0

Как сказал Вадим М.. Вам необходимо аутентифицировать своего пользователя.Затем вы можете использовать это, чтобы сравнить «Владелец изображения» с «Пользователь, который в настоящее время входит в систему». Это даст вам всю необходимую вам безопасность.

Как я уже говорил, назовите вариблеты так, чтобы они звучали правильно. Когда я вижу «id» в varayable. Я автоматически предполагаю в качестве программиста, что это числовой var.

+0

Идентификатор не является числом: D это «имя_файла» с каким-то уникальным материалом перед ними, что-то вроде 'efb03_orange.png'. Проблема в том, что в этом разделе я еще ничего не отправил в базу данных. Поэтому я не знаю, как проверить, является ли зарегистрированный пользователь пользователем, которому принадлежит файл. – Adam

+0

Я думаю, что такое нарушение правил именования для var. Должно быть как $ imagePlaceholder. Я буду делать дальнейшие обновления в ответ на ваш комментарий. – Anraiki

+0

Я просто замечаю, что ... заставить человека перепрыгнуть через большее обруч, может не понадобиться, как только «проверка» владельца файла проходит. – Anraiki

2

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

только что-то вроде

$photo_id = basename($_GET['photo_id'];) 
$filename = $filebase.$_SESSION['user_id']."/".$photo_id; 
if (file_exists($filename) unlink ($filename); 
0

имел ту же самую проблему и получил вокруг него с помощью ftp_delete функции РНР

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