Estoy buscando una función php que desinfecte una cadena y la deje lista para usar como nombre de archivo. ¿Alguien sabe de uno útil?
(¡Podría escribir uno, pero me preocupa que pase por alto un personaje!)
Editar: para guardar archivos en un sistema de archivos NTFS de Windows.
php
string
sanitization
usuario151841
fuente
fuente
Respuestas:
En lugar de preocuparse por pasar por alto los personajes, ¿qué tal si usas una lista blanca de personajes que te gusta que te usen? Por ejemplo, se puede permitir que sólo un buen ol'
a-z
,0-9
,_
, y una sola instancia de un punto (.
). Obviamente, eso es más limitante que la mayoría de los sistemas de archivos, pero debería mantenerlo a salvo.fuente
Al hacer un pequeño ajuste a la solución de Tor Valamo para solucionar el problema observado por Dominic Rodger, podría usar:
fuente
..
después. Por ejemplo.?.
acabaría siendo..
. Aunque ya que filtra/
, no veo cómo explotarlo más en este momento, pero muestra por qué la verificación no..
es efectiva aquí. Mejor aún, probablemente, no reemplace, simplemente rechace si no califica.[^a-z0-9_-]
si desea ser realmente restrictivo, o simplemente usar un nombre generado y desechar el nombre de pila y evitar todos estos problemas. :-)Así es como puede desinfectar un sistema de archivos como se le pide
Todo lo demás está permitido en un sistema de archivos, por lo que la pregunta está perfectamente respondida ...
... pero podría ser peligroso permitir, por ejemplo, comillas simples
'
en un nombre de archivo si lo usa más tarde en un contexto HTML inseguro porque este nombre de archivo absolutamente legal:se convierte en un agujero XSS :
Por eso, el popular software CMS Wordpress los elimina, pero cubrieron todos los caracteres relevantes solo después de algunas actualizaciones :
Finalmente su lista incluye ahora la mayoría de los personajes que forman parte de la URI rerserved caracteres y URL personajes inseguros lista.
Por supuesto, podría simplemente codificar todos estos caracteres en la salida HTML, pero la mayoría de los desarrolladores y yo también, seguimos el modismo "Más vale prevenir que curar" y eliminarlos de antemano.
Entonces, finalmente, sugeriría usar esto:
Todo lo demás que no cause problemas con el sistema de archivos debe ser parte de una función adicional:
Y en este punto, debe generar un nombre de archivo si el resultado está vacío y puede decidir si desea codificar caracteres UTF-8. Pero no lo necesita, ya que UTF-8 está permitido en todos los sistemas de archivos que se utilizan en contextos de alojamiento web.
Lo único que tiene que hacer es usar
urlencode()
(como con suerte lo hace con todas sus URL) para que el nombre del archivo seსაბეჭდი_მანქანა.jpg
convierta en esta URL como su<img src>
o<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 hace eso, así que puedo publicar este enlace como lo haría un usuario:
http://www.maxrev.de/html/img/ საბეჭდი_მანქანა. Jpg
Así que este es un nombre de archivo legal completo y no es un problema como @ SequenceDigitale.com mencionó en su respuesta .
fuente
r-u-l-e-s
y no tengo idea de por qué sucede esto. Seguro que no es culpa de la función, sino simplemente preguntarse: ¿cuál podría ser la razón de tal comportamiento? Codificación incorrecta?preg_replace
enfilter_filename()
.¿Qué pasa con el uso de rawurlencode ()? http://www.php.net/manual/en/function.rawurlencode.php
Aquí hay una función que desinfecta incluso los caracteres chinos:
Aquí está la explicación
Bien, algún nombre de archivo no será relevante, pero en la mayoría de los casos funcionará.
ex. Nombre original: "საბეჭდი-და-ტიპოგრაფიული. Jpg"
Nombre de salida: "-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 "
Es mejor así que un error 404.
Espero que haya sido útil.
Carl.
fuente
http://www.maxrev.de/html/img/საბეჭდი_მანქანა.jpg
ahttp://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
en el código fuente HTML como es de esperar que lo hace con todas sus URL.strip_tags()
y después las eliminas[<>]
. Por esostrip_tags()
realmente no se necesita en absoluto. El mismo punto son las citas. No quedan comillas cuando decodifica conENT_QUOTES
. Ystr_replace()
no elimina los espacios en blanco consecutivos y luego los usastrtolower()
para una cadena de varios bytes. ¿Y por qué convierte a minúsculas? Y finalmente no captó ningún personaje reservado como mencionó @BasilMusa. Más detalles en mi respuesta: stackoverflow.com/a/42058764/318765SOLUCIÓN 1 - simple y eficaz
$file_name = preg_replace( '/[^a-z0-9]+/', '-', strtolower( $url ) );
[^a-z0-9]+
asegurará, el nombre del archivo solo conserva letras y números'-'
mantiene legible el nombre del archivoEjemplo:
SOLUCIÓN 2 : para URL muy largas
Desea almacenar en caché el contenido de la URL y solo necesita tener nombres de archivo únicos. Usaría esta función:
$file_name = md5( strtolower( $url ) )
esto creará un nombre de archivo con una longitud fija. El hash MD5 es en la mayoría de los casos lo suficientemente único para este tipo de uso.
Ejemplo:
fuente
Bueno, tempnam () lo hará por ti.
http://us2.php.net/manual/en/function.tempnam.php
pero eso crea un nombre completamente nuevo.
Para desinfectar una cadena existente, simplemente restrinja lo que sus usuarios pueden ingresar y conviértalo en letras, números, puntos, guiones y subrayados y luego desinfecte con una simple expresión regular. Compruebe qué caracteres deben escaparse o podría obtener falsos positivos.
fuente
Agregue / elimine más caracteres válidos dependiendo de lo que esté permitido para su sistema.
Alternativamente, puede intentar crear el archivo y luego devolver un error si es malo.
fuente
..
, lo que puede ser un problema o no.PHP proporciona una función para desinfectar un texto a un formato diferente
filter.filters.sanitize
Cómo :
fuente
seguro: reemplace cada secuencia de NOT "a-zA-Z0-9_-" por un guión; agregue una extensión usted mismo.
fuente
La siguiente expresión crea una cadena agradable, limpia y utilizable:
Convirtiendo lo financiero de hoy: facturación en facturación financiera de hoy
fuente
preg_replace
el indicador global está implícito. Por tanto, no es necesario utilizar g si se utiliza preg_replace. Cuando queremos controlar el número de reemplazos, preg_replace tiene unlimit
parámetro para eso. Lea la documentación de preg_replace para obtener más información.Haciendo un pequeño ajuste a la solución de Sean Vieira para permitir puntos individuales, podría usar:
fuente
Estos pueden ser un poco pesados, pero son lo suficientemente flexibles como para desinfectar cualquier cuerda en una "caja fuerte".
en
nombre de archivo o carpeta de estilo (o diablos, incluso babosas limpias y cosas si se dobla).1) Crear un nombre de archivo completo (con un nombre alternativo en caso de que la entrada esté totalmente truncada):
2) O usando solo la utilidad de filtro sin construir un nombre de archivo completo (el modo estricto
true
no permitirá [] o () en el nombre de archivo):3) Y aquí están esas funciones:
Entonces, digamos que alguna entrada del usuario es:
.....<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) საბეჭდი-და-ტიპოგრაფიული
Y queremos convertirlo en algo más amigable para hacer un tar.gz con una longitud de nombre de archivo de 255 caracteres. Aquí hay un ejemplo de uso. Nota: este ejemplo incluye una extensión tar.gz con formato incorrecto como prueba de concepto, aún debe filtrar la extensión después de que la cadena se construya contra su lista blanca.
La salida sería:
_wei_gbel_file_name_dcor_._._._z_._y_._x_._this_name_is_462_not_that_grrrreat_][09]()1234747)_.tar.gz
Puedes jugar con él aquí: https://3v4l.org/iSgi8
O una esencia: https://gist.github.com/dhaupin/b109d3a8464239b7754a
EDITAR: filtro de script actualizado para en
lugar de espacio, enlace 3v4l actualizadofuente
Lo mejor que sé hoy es el método estático Strings :: webalize de Nette framework.
Por cierto, esto traduce todos los signos diacríticos a su básico .. š => s ü => u ß => ss etc.
Para los nombres de archivo, debe agregar un punto "." al parámetro de caracteres permitidos.
fuente
urlencode()
antes de usar el nombre de archivo comosrc
ohref
. El único sistema de archivos utilizado actualmente que tiene problemas con UTF-8 es FATx (utilizado por XBOX): en.wikipedia.org/wiki/Comparison_of_file_systems#Limits Y no creo que esto sea utilizado por servidores webParece que todo esto depende de la pregunta: ¿es posible crear un nombre de archivo que pueda usarse para piratear un servidor (o hacer algún otro daño)? Si no es así, entonces parece que la respuesta simple es intentar crear el archivo donde, en última instancia, se utilizará (ya que ese será el sistema operativo de elección, sin duda). Deje que el sistema operativo lo resuelva. Si se queja, transfiera esa queja al usuario como un error de validación.
Esto tiene el beneficio adicional de ser confiablemente portátil, ya que todos los sistemas operativos (estoy bastante seguro) se quejarán si el nombre del archivo no está formado correctamente para ese sistema operativo.
Si es posible hacer cosas nefastas con un nombre de archivo, tal vez haya medidas que se puedan aplicar antes de probar el nombre de archivo en el sistema operativo residente; medidas menos complicadas que un "saneamiento" completo del nombre de archivo.
fuente
de una sola mano
fuente
/
y..
en el nombre de archivo proporcionado por el usuario puede ser perjudicial. Entonces deberías deshacerte de estos con algo como:fuente
..name
que no saldrá de nada. Eliminar todos los caracteres separadores de ruta debería ser suficiente para evitar cualquier cruce de directorio. (La eliminación de..
es técnicamente innecesaria.)./.
convierte en..
. Y finalmente esta respuesta pierde todos los demás caracteres reservados del sistema de archivos como NULL. Más en mi respuesta: stackoverflow.com/a/42058764/318765Dado que los usuarios pueden usar la barra para separar dos palabras, sería mejor reemplazarla con un guión en lugar de NULL
fuente