¿Es posible utilizar una expresión regular para validar o desinfectar los datos de Base64? Esa es la pregunta simple, pero los factores que impulsan esta pregunta son los que la dificultan.
Tengo un decodificador Base64 que no puede confiar completamente en los datos de entrada para seguir las especificaciones RFC. Entonces, los problemas que enfrento son problemas como quizás los datos Base64 que pueden no dividirse en 78 (creo que es 78, tendría que verificar el RFC, así que no me diga si el número exacto es incorrecto) líneas, o que las líneas no pueden terminar en CRLF; en el sentido de que puede tener solo un CR, o LF, o tal vez ninguno.
Por lo tanto, me ha costado muchísimo analizar datos Base64 formateados como tales. Debido a esto, los ejemplos como el siguiente se vuelven imposibles de decodificar de manera confiable. Solo mostraré encabezados MIME parciales por brevedad.
Content-Transfer-Encoding: base64
VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu
Bien, analizar eso no es un problema, y es exactamente el resultado que esperaríamos. Y en el 99% de los casos, usar cualquier código para al menos verificar que cada carácter en el búfer es un carácter base64 válido, funciona perfectamente. Pero, el siguiente ejemplo arroja una llave inglesa a la mezcla.
Content-Transfer-Encoding: base64
http://www.stackoverflow.com
VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu
Esta es una versión de la codificación Base64 que he visto en algunos virus y otras cosas que intentan aprovechar el deseo de algunos lectores de correo de analizar la mímica a toda costa, frente a los que se rigen estrictamente por el libro, o más bien RFC; Si tu quieres.
Mi decodificador Base64 decodifica el segundo ejemplo en el siguiente flujo de datos. Y tenga en cuenta aquí que la transmisión original son todos los datos ASCII.
[0x]86DB69FFFC30C2CB5A724A2F7AB7E5A307289951A1A5CC81A5CC81CDA5B5C1B19481054D0D
2524810985CD94D8D08199BDC8814DD1858DAD3DD995C999B1BDDC8195E1B585C1B194B8
¿Alguien tiene una buena manera de resolver ambos problemas a la vez? No estoy seguro de que sea posible, aparte de hacer dos transformaciones en los datos con diferentes reglas aplicadas y comparar los resultados. Sin embargo, si adoptó ese enfoque, ¿en qué resultado confía? Parece que la heurística ASCII es la mejor solución, pero ¿cuánto más código, tiempo de ejecución y complejidad agregaría eso a algo tan complicado como un escáner de virus, en el que este código está realmente involucrado? ¿Cómo entrenaría el motor heurístico para aprender qué es Base64 aceptable y qué no?
ACTUALIZAR:
Teniendo en cuenta la cantidad de vistas que sigue recibiendo esta pregunta, he decidido publicar la expresión regular simple que he estado usando en una aplicación C # durante 3 años, con cientos de miles de transacciones. Honestamente, me gusta más la respuesta dada por Gumbo , por eso la elegí como la respuesta seleccionada. Pero para cualquiera que use C # y busque una forma muy rápida de al menos detectar si una cadena o byte [] contiene datos Base64 válidos o no, he encontrado que lo siguiente funciona muy bien para mí.
[^-A-Za-z0-9+/=]|=[^=]|={3,}$
Y sí, esto es solo para una CADENA de datos Base64, NO para un mensaje RFC1341 con el formato adecuado . Por lo tanto, si está tratando con datos de este tipo, téngalo en cuenta antes de intentar utilizar la expresión regular anterior. Si se trata de Base16, Base32, Radix base 64 o incluso para otros fines (URL, nombres de archivo XML de codificación, etc.), entonces es altamente recomendable que lea RFC4648 que Gumbo mencionó en su respuesta que tiene que ser así consciente del juego de caracteres y terminadores usados por la implementación antes de intentar usar las sugerencias en este juego de preguntas / respuestas.
fuente
^
exterior de los corchetes, como un ancla de inicio. Sin embargo, una expresión regular mucho mejor, sin ser tan complicada como la respuesta aceptada, sería^[-A-Za-z0-9+/]*={0,3}$
Respuestas:
Desde el RFC 4648 :
Por lo tanto, depende del propósito de uso de los datos codificados si los datos deben considerarse peligrosos.
Pero si solo busca una expresión regular que coincida con las palabras codificadas en Base64, puede usar lo siguiente:
fuente
name
es una codificación Base64 válida de la secuencia de bytes (hexadecimal)9d a9 9e
.^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$
debe escapar de la reacción violentaEste es bueno, pero coincidirá con una cadena vacía
Este no coincide con la cadena vacía:
fuente
MQ==
no coincidir con su expresiónAQENVg688MSGlEgdOJpjIUC=
es la forma válida.=
. El último?
permite 0=
. Reemplazarlo con{1}
requiere 1 o 2 terminaciones=
Ni un " : " ni un " . " Se mostrarán en Base64 válida, así que creo que puede descartar la
http://www.stackoverflow.com
línea sin ambigüedades . En Perl, digamos, algo comopuede ser lo que quieras. Produce
Este es un ejemplo simple de ASCII Base64 para StackOverflow.
fuente
La mejor expresión regular que pude encontrar hasta ahora está aquí https://www.npmjs.com/package/base64-regex
que está en la versión actual se ve así:
fuente
\\n?
.Para validar la imagen base64 podemos usar esta expresión regular
fuente