Mój przyjaciel znalazł problem w moim skrypcie, daje dostęp do plików root.PHP secure root
Ten url daje plik passwd:
http://site.com/attachment.php?file=../../../../../../etc/passwd
jak uciec tę lukę?
Mój przyjaciel znalazł problem w moim skrypcie, daje dostęp do plików root.PHP secure root
Ten url daje plik passwd:
http://site.com/attachment.php?file=../../../../../../etc/passwd
jak uciec tę lukę?
Istnieje kilka różnych rozwiązań. Jeśli może istnieć tylko nazwa pliku, rozwiązanie basename() będzie działać.
Jednakże, jeśli to może być ścieżka bardziej złożone rozwiązanie jest potrzebne
//assume current directory, but can be set anything. Absolute path of course
$basedir = dirname(__FILE__);
//assume our files are below document root.
//Otherwise use it's root dir instead of DOCUMENT_ROOT
$filename = realpath($_SERVER['DOCUMENT_ROOT'].$_GET['file']);
if (substr($filename,0,strlen($basedir)) !== $basedir) {
header ("HTTP/1.0 403 Forbidden");
exit;
}
jest również rozwiązaniem użytecznym konfiguracja PHP open_basedir
Nie pobieraj plików za pomocą ciągu URL ... Określ unikalne identyfikatory, aby wskazać plik, a nie ścieżki.
Być może widzieliście pliki do pobrania takie jak te http://www.mysite.com/download.php?id=23423
, co robią, użyj tego identyfikatora, aby pobrać nazwę pliku i ścieżkę z bazy danych, a następnie pobrać ją.
Przypuszczam, że masz katalog, w którym przechowywane są wszystkie załączniki.
Sprawdź tylko, czy plik znajduje się w twoim katalogu.
// http://www.php.net/manual/en/function.basename.php
// http://cz.php.net/manual/en/function.file-exists.php
if (file_exists($attachments_path . "/" . basename($_GET['file'])) {
// do work
}
Starx opublikował rozwiązanie, które wydaje się w porządku. Można to zrobić bez bazy danych. Jeśli ktoś załaduje plik, możesz zapisać plik jako md5($filename).$extension
i użyć swojego skryptu.
Więc jeśli W katalogu załączników znajduje się plik o nazwie "passwd", kod umożliwia także pobranie pliku/etc/passwd? Nie jestem programistą PHP, ale myślę, że powinieneś bardziej otwarcie powiedzieć, że plik, do którego należy uzyskać dostęp, powinien być utworzony w taki sam sposób: $ filename = $ attachments_path. "/". basename ($ _ GET ['plik']) –
Możesz użyć realpath()
i dirname()
, aby sprawdzić adresy URL przed $_SERVER['DOCUMENT_ROOT']
(lub innego katalogu, który jest "bezpieczny" do pobrania).
Jeśli wynik realpath()
wskazuje poza bezpiecznym katalogiem, można odrzucić żądanie pobrania.
Istnieje również dyrektywa bezpieczeństwa open_basedir (i opcja środowiska wykonawczego od wersji 5.3).
* (odniesienia) * http: //en.wikipedia. org/wiki/Directory_traversal – Gordon
Jak zaznaczył @Starx, staraj się unikać używania ścieżek plików jako identyfikatorów dokumentów (istnieją inne problemy, poza przeglądaniem katalogów). (Pomysł @MartIXa na temat (md5) hashing może pomóc w realizacji lean). Ponadto dobrym pomysłem jest, aby ** nie uruchamiać serwera jako root **. Użyj oddzielnego użytkownika, który ma tylko prawa w systemie, które są niezbędne do wykonania jego zadania. – zpea
(To znaczy, że masz dostęp do plików tylko do odczytu przez użytkownika root, takich jak '/ etc/shadow'.'/Etc/passwd' jest czytelny dla każdego użytkownika w nowoczesnych Unixach, oczywiście) – zpea