Szukam funkcji php, która oczyści ciąg i przygotuje go do użycia jako nazwa pliku. Czy ktoś zna poręczny?
(Mógłbym napisać, ale martwię się, że przeoczę jakąś postać!)
Edycja: do zapisywania plików w systemie plików Windows NTFS.
php
string
sanitization
user151841
źródło
źródło
Odpowiedzi:
Zamiast martwić się o przeoczenie postaci - co powiesz na użycie białej listy postaci, z których chętnie korzystasz? Na przykład, można pozwolić tylko good ol”
a-z
,0-9
,_
, i jedno wystąpienie okresu (.
). To oczywiście bardziej ogranicza niż większość systemów plików, ale powinno zapewnić Ci bezpieczeństwo.źródło
Dokonując niewielkiej korekty rozwiązania Tor Valamo by rozwiązać problem zauważony przez Dominic Rodger, to mógłby użyć:
źródło
..
później. Na przykład.?.
skończyłoby się istnieniem..
. Chociaż odkąd filtrujesz/
, nie widzę, jak możesz teraz to wykorzystać, ale pokazuje, dlaczego sprawdzenie..
jest tutaj nieskuteczne. Jeszcze lepiej, nie wymieniaj, po prostu odrzuć, jeśli się nie kwalifikuje.[^a-z0-9_-]
jeśli chcesz być naprawdę restrykcyjny - lub po prostu użyć wygenerowanej nazwy i wyrzucić podaną nazwę i uniknąć wszystkich tych problemów. :-)Oto, jak możesz wyczyścić system plików zgodnie z pytaniem
Wszystko inne jest dozwolone w systemie plików, więc odpowiedź na pytanie jest doskonała ...
... ale dopuszczenie na przykład pojedynczych cudzysłowów w nazwie pliku może być niebezpieczne,
'
jeśli użyjesz go później w niebezpiecznym kontekście HTML, ponieważ ta całkowicie legalna nazwa pliku:staje się otworem XSS :
Z tego powodu popularne oprogramowanie CMS Wordpress usuwa je, ale wszystkie istotne znaki zakrywały dopiero po kilku aktualizacjach :
Wreszcie ich lista zawiera teraz większość znaków, które są częścią listy znaków zastrzeżonych URI i niebezpiecznych znaków URL .
Oczywiście możesz po prostu zakodować wszystkie te znaki na wyjściu HTML, ale większość programistów i ja też stosujemy idiom „Lepiej bezpiecznie niż przepraszam” i usuwamy je z wyprzedzeniem.
W końcu sugerowałbym użycie tego:
Wszystko inne, co nie powoduje problemów z systemem plików, powinno być częścią dodatkowej funkcji:
W tym momencie musisz wygenerować nazwę pliku, jeśli wynik jest pusty i możesz zdecydować, czy chcesz zakodować znaki UTF-8. Ale nie jest to konieczne, ponieważ UTF-8 jest dozwolony we wszystkich systemach plików używanych w kontekstach hostingu internetowego.
Jedyne, co musisz zrobić, to użyć
urlencode()
(jak mamy nadzieję, że robisz to ze wszystkimi adresami URL), aby nazwa plikuსაბეჭდი_მანქანა.jpg
stała się tym adresem URL jako Twój<img src>
lub<a href>
: http://www.maxrev.de/html/img/%E1%83% A1% E1% 83% 90% E1% 83% 91% E1% 83% 94% E1% 83% AD% E1% 83% 93% E1% 83% 98_% E1% 83% 9B% E1% 83% 90% E1% 83% 9C% E1% 83% A5% E1% 83% 90% E1% 83% 9C% E1% 83% 90.jpgStackoverflow to robi, więc mogę opublikować ten link tak, jak zrobiłby to użytkownik:
http://www.maxrev.de/html/img/ საბეჭდი_მანქანა. Jpg
Jest to więc pełna legalna nazwa pliku, a nie problem, o czym @ SequenceDigitale.com wspomniał w swojej odpowiedzi .
źródło
r-u-l-e-s
i nie mam pojęcia, dlaczego tak się dzieje. Jasne, że nie jest to wina funkcji, ale pytanie - co może być przyczyną takiego zachowania? Niewłaściwe kodowanie?preg_replace
infilter_filename()
.A co z użyciem rawurlencode ()? http://www.php.net/manual/en/function.rawurlencode.php
Oto funkcja, która oczyszcza nawet chińskie znaki:
Oto wyjaśnienie
OK, niektóre nazwy plików nie będą ważne, ale w większości przypadków będą działać.
dawny. Oryginalna nazwa: „საბეჭდი-და-ტიპოგრაფიული. Jpg”
Nazwa wyjścia: "-E1-83-A1-E1-83-90-E1-83-91-E1-83-94-E1-83-AD-E1-83-93-E1-83-98 - E1- 83-93-E1-83-90 - E1-83-A2-E1-83-98-E1-83-9E-E1-83-9D-E1-83-92-E1-83-A0-E1-83 -90-E1-83-A4-E1-83-98-E1-83-A3-E1-83-9A-E1-83-98.jpg ”
To lepsze niż błąd 404.
Mam nadzieję, że to było pomocne.
Carl.
źródło
http://www.maxrev.de/html/img/საბეჭდი_მანქანა.jpg
, abyhttp://www.maxrev.de/html/img/%E1%83%A1%E1%83%90%E1%83%91%E1%83%94%E1%83%AD%E1%83%93%E1%83%98_%E1%83%9B%E1%83%90%E1%83%9C%E1%83%A5%E1%83%90%E1%83%9C%E1%83%90.jpg
w kodzie źródłowym HTML, jak mamy nadzieję zrobić ze wszystkimi swoimi adresami URL.strip_tags()
a następnie usuwasz[<>]
. Przez tostrip_tags()
tak naprawdę nie jest w ogóle potrzebne. Ten sam punkt to cytaty. Po dekodowaniu za pomocą nie ma żadnych cudzysłowówENT_QUOTES
. Istr_replace()
nie usuwa kolejnych białych spacji, a następnie używaszstrtolower()
dla ciągu wielobajtowego. I dlaczego w ogóle konwertujesz na małe litery? I w końcu nie złapałeś żadnej zarezerwowanej postaci, jak wspomniał @BasilMusa. Więcej szczegółów w mojej odpowiedzi: stackoverflow.com/a/42058764/318765ROZWIĄZANIE 1 - proste i skuteczne
$file_name = preg_replace( '/[^a-z0-9]+/', '-', strtolower( $url ) );
[^a-z0-9]+
upewni się, że nazwa pliku zawiera tylko litery i cyfry'-'
słowami, aby zachować czytelność nazwy plikuPrzykład:
ROZWIĄZANIE 2 - dla bardzo długich adresów URL
Chcesz przechowywać zawartość adresu URL w pamięci podręcznej i po prostu mieć unikalne nazwy plików. Użyłbym tej funkcji:
$file_name = md5( strtolower( $url ) )
stworzy to nazwę pliku o stałej długości. Skrót MD5 jest w większości przypadków wystarczająco wyjątkowy dla tego rodzaju zastosowań.
Przykład:
źródło
Cóż, tempnam () zrobi to za Ciebie.
http://us2.php.net/manual/en/function.tempnam.php
ale to tworzy zupełnie nową nazwę.
Aby wyczyścić istniejący ciąg, po prostu ogranicz to, co użytkownicy mogą wprowadzać, i nadaj mu litery, cyfry, kropkę, łącznik i podkreślenie, a następnie wyczyść za pomocą prostego wyrażenia regularnego. Sprawdź, jakie znaki należy zmienić lub możesz uzyskać fałszywe alarmy.
źródło
Dodaj / usuń więcej poprawnych znaków w zależności od tego, co jest dozwolone w twoim systemie.
Alternatywnie możesz spróbować utworzyć plik, a następnie zwrócić błąd, jeśli jest zły.
źródło
..
, co może, ale nie musi, stanowić problem.PHP udostępnia funkcję oczyszczania tekstu do innego formatu
filter.filters.sanitize
Jak :
źródło
bezpieczny: zamień każdą sekwencję NIE „a-zA-Z0-9_-” na myślnik; dodaj rozszerzenie samodzielnie.
źródło
Poniższe wyrażenie tworzy ładny, czysty i użyteczny ciąg:
Zmieniamy dzisiejsze finanse: rozliczenia w dzisiejsze-finansowe-rozliczenia
źródło
preg_replace
flagi globalnej jest niejawna. Więc nie ma potrzeby stosowania g, jeśli używany jest preg_replace. Kiedy chcemy kontrolować liczbę podmian, preg_replace ma do tegolimit
parametr. Przeczytaj dokumentację preg_replace, aby uzyskać więcej informacji.Dokonując niewielkiej korekty w rozwiązaniu Seana Vieiry, aby uwzględnić pojedyncze kropki, możesz użyć:
źródło
Mogą być trochę ciężkie, ale są wystarczająco elastyczne, aby odkażać dowolny ciąg do „bezpiecznego”
en
nazwie pliku lub folderu (lub do cholery, nawet wyczyszczone ślimaki i inne rzeczy, jeśli je zgniesz).1) Budowanie pełnej nazwy pliku (z nazwą zastępczą w przypadku całkowitego obcięcia danych wejściowych):
2) Lub używając samego filtra używanego bez budowania pełnej nazwy pliku (tryb ścisły
true
nie zezwala na [] lub () w nazwie pliku):3) A oto te funkcje:
Powiedzmy, że niektóre dane wejściowe użytkownika to:
.....<div></div><script></script>& Weiß Göbel 中文百强网File name %20 %20 %21 %2C Décor \/. /. . z \... y \...... x ./ “This name” is & 462^^ not = that grrrreat -][09]()1234747) საბეჭდი-და-ტიპოგრაფიული
Chcemy przekonwertować go na coś bardziej przyjaznego, aby utworzyć plik tar.gz z nazwą pliku o długości 255 znaków. Oto przykład użycia. Uwaga: ten przykład zawiera zniekształcone rozszerzenie tar.gz jako dowód słuszności koncepcji, nadal należy filtrować rozszerzenie po utworzeniu łańcucha znaków na białej liście (listach).
Wynik byłby następujący:
_wei_gbel_file_name_dcor_._._._z_._y_._x_._this_name_is_462_not_that_grrrreat_][09]()1234747)_.tar.gz
Możesz się nim bawić tutaj: https://3v4l.org/iSgi8
Lub Gist: https://gist.github.com/dhaupin/b109d3a8464239b7754a
EDYCJA: zaktualizowany filtr skryptów
zamiast spacji, zaktualizowany link 3v4lźródło
Najlepsze, co dziś znam, to statyczna metoda Strings :: webalize z frameworka Nette.
Przy okazji, to tłumaczy wszystkie znaki diakrytyczne na ich podstawowe .. š => s ü => u ß => ss itd.
W przypadku nazw plików musisz dodać kropkę „.” parametr dozwolonych znaków.
źródło
urlencode()
przed użyciem nazwy pliku jakosrc
lubhref
. Jedynym obecnie stosowany system plików, który ma problemy z UTF-8 jest FATx (używany przez XBOX): en.wikipedia.org/wiki/Comparison_of_file_systems#Limits I nie sądzę, że to jest wykorzystywane przez serwery WWWWygląda na to, że to wszystko zależy od pytania, czy możliwe jest utworzenie nazwy pliku, której można by użyć do włamania się do serwera (lub wyrządzenia takich innych szkód). Jeśli nie, to wydaje się, że prostą odpowiedzią jest próba utworzenia pliku tam, gdzie ostatecznie będzie on używany (ponieważ bez wątpienia będzie to wybrany system operacyjny). Pozwól systemowi operacyjnemu to rozwiązać. Jeśli narzeka, zgłoś tę skargę z powrotem do użytkownika jako błąd walidacji.
Ma to dodatkową zaletę, że jest niezawodnie przenośne, ponieważ wszystkie (jestem prawie pewien) systemy operacyjne będą narzekać, jeśli nazwa pliku nie zostanie poprawnie utworzona dla tego systemu operacyjnego.
Jeśli jest to możliwe do zrobienia nikczemne rzeczy z nazwy pliku, być może istnieją środki, które mogą być zastosowane przed badaniem nazwę pliku w systemie operacyjnym rezydenta - środki mniej skomplikowane niż pełny „sanitarnych” w nazwie.
źródło
jednokierunkowa
źródło
/
a..
nazwa pliku podana przez użytkownika może być szkodliwa. Więc powinieneś się ich pozbyć przez coś takiego:źródło
..name
który nic by się nie wyrwało . Usunięcie wszystkich znaków separatora ścieżek powinno wystarczyć, aby zapobiec przechodzeniu do katalogu. (Usunięcie..
jest technicznie niepotrzebne.)./.
staje..
. I wreszcie ta odpowiedź pomija wszystkie inne zastrzeżone znaki systemu plików, takie jak NULL. Więcej w mojej odpowiedzi: stackoverflow.com/a/42058764/318765Ponieważ użytkownicy mogą używać ukośnika do oddzielania dwóch słów, lepiej byłoby zastąpić je myślnikiem zamiast NULL
źródło