
Expresión regular para coincidencia de URLs. Versión mantenida, segura y compatible con navegadores de url-regex. Resuelve CVE-2020-7661 para servidores Node.js.
Expresión regular para coincidir con URLs. Versión mantenida, segura y compatible con navegadores de url-regex. Resuelve CVE-2020-7661 para servidores Node.js. Funciona en Node v14+ y navegadores. Mantenido para Spam Scanner y Forward Email.
Después de descubrir CVE-2020-7661 y revelarlo públicamente (a través de mi trabajo en Spam Scanner y Forward Email) – usé una implementación de url-regex con algo de lógica adicional encima para filtrar coincidencias de URL no deseadas.
Sin embargo, después de usarlo en Forward Email en producción (que procesa cientos de miles de correos electrónicos por semana), encontré y documenté varios problemas principales más con url-regex.
Al darme cuenta de que url-regex ya no se mantiene activamente, tiene 9 solicitudes de extracción abiertas al momento de escribir esto, y además carecía de soporte para navegadores – decidí escribir este paquete para todos y fusionar todas las solicitudes de extracción abiertas.
Es de esperar que este paquete se parezca más al uso real que se le daría a una expresión regular de URL, y que además permita al usuario configurarlo como desee. Por favor, echa un vistazo a Forward Email si este paquete te ayudó, y explora nuestro código fuente en GitHub, que muestra cómo usamos este paquete.
NOTA: El comportamiento predeterminado de este paquete intentará cargar re2 (es una dependencia opcional entre pares utilizada para prevenir ataques de denegación de servicio por expresión regular y más). Si deseas usar este comportamiento, debes tener re2 instalado mediante npm install re2 – de lo contrario, recurrirá a usar instancias normales de RegExp. A partir de v4.0.0 agregamos una opción si deseas forzar a este paquete a que ni siquiera intente cargar re2 (por ejemplo, si está en tu node_modules pero no quieres usarlo) – simplemente pasa re2: false como opción.
npm:
npm install url-regex-safe
Hemos resuelto CVE-2020-7661 incluyendo RE2 para uso en Node.js. Ya no tendrás que envolver manualmente tus expresiones regulares de URL con new RE2(urlRegex()) a través de url-regex-safe (lo hacemos automáticamente por ti).
const urlRegexSafe = require('url-regex-safe');
const str = 'some long string with url.com in it';
const matches = str.match(urlRegexSafe());
for (const match of matches) {
console.log('match', match);
}
console.log(urlRegexSafe({ exact: true }).test('github.com'));
Dado que RE2 no está hecho para el navegador, no se usará y, por lo tanto, CVE-2020-7661 sigue siendo un problema en el lado del cliente. Sin embargo, no es grave, ya que lo máximo que podría hacer es bloquear la pestaña del navegador (mientras que en el lado de Node.js habría bloqueado todo el proceso y lanzado una excepción de falta de memoria).
¡Esta es la solución para ti si solo usas etiquetas <script> en todas partes!
<script src="https://unpkg.com/url-regex-safe"></script>
<script type="text/javascript">
(function() {
var str = 'some long string with url.com in it';
var matches = str.match(urlRegexSafe());
for (var i=0; i<matches.length; i++) {
console.log('match', matches[i]);
}
console.log(urlRegexSafe({ exact: true }).test('github.com'));
})();
</script>
Asumiendo que usas browserify, webpack, rollup u otro bundler, simplemente puedes seguir el uso de Node anterior.
Para usar este paquete con TypeScript, puedes instalar el paquete @types/url-regex-safe para las definiciones de tipos.
npm install --save-dev @types/url-regex-safe
Debes anular el valor predeterminado y establecer strict: true si no deseas coincidir con github.com por sí solo (aunque www.github.com funcionará si strict: false).
A diferencia del paquete obsoleto y sin mantenimiento url-regex, hacemos algunas cosas de manera diferente:
strict en false de forma predeterminada (url-regex lo tenía establecido en true)auth, que está establecida en false de forma predeterminada (url-regex coincide con autenticación básica; la tenía establecida en true - sin embargo, este es un comportamiento obsoleto en Chromium).parens e ipv6, que están establecidas en false y true de forma predeterminada (url-regex tenía parens establecido en true e ipv6 era inexistente o más bien estaba establecido en ).Esta limitación solo aplica si estás usando re2: Dado que no podemos usar la funcionalidad de «negative lookbehinds» (búsqueda hacia atrás negativa) de las expresiones regulares (debido a las limitaciones de RE2), no pudimos fusionar la lógica de esta solicitud de extracción. Esto nos habría permitido hacer que example.jpeg coincidiera solo si fuera example.jp; sin embargo, si pasas example.jpeg ahora mismo, extraerá example.jp de ella (ya que .jp es un TLD). Puede existir una solución alternativa, y agradecemos las contribuciones de la comunidad con respecto a este problema.
| Nombre | Sitio web |
|---|---|
| Forward Email LLC | https://forwardemail.net |
| Kevin Mårtensson | |
| Diego Perini |
| Propiedad | Tipo | Valor predeterminado | Descripción |
|---|
re2 | Boolean | true | Intenta cargar re2 para usarlo en lugar de RegExp al crear nuevas instancias de expresiones regulares. Si pasas re2: false, ni siquiera se intentará cargar re2. | |
exact | Boolean | false | Solo coincide con una cadena exacta. Útil con regex.test(str) para comprobar si una cadena es una URL. Establecemos esto en false de forma predeterminada para poder coincidir con valores de cadena como github.com (en lugar de requerir un protocolo o un subdominio www). Creemos que esto se parece más al uso real previsto de este paquete. | |
strict | Boolean | false | Fuerza a que las URL comiencen con un protocolo válido o con www si se establece en true. Si es true, permitirá cualquier TLD siempre que tenga un mínimo de 2 caracteres válidos. Si es false, comparará el TLD con la lista de TLD válidos usando tlds. | |
auth | Boolean | false | Coincide con cabeceras de autenticación básica. Establecemos esto en false de forma predeterminada ya que fue obsoleto en Chromium, y de lo contrario deja al usuario con coincidencias de URL no deseadas (se parece más al uso real previsto de este paquete al tenerlo también en false de forma predeterminada). | |
localhost | Boolean | true | Permite localhost en la parte del nombre de host de la URL. Consulta test/test.js para obtener más información sobre la prueba de localhost y cómo devolverá un valor que puede no ser deseado. Se consideraría una solicitud de extracción para resolver el problema de "pic.jp" frente a "pic.jpg". | |
parens | Boolean | false | Coincide con paréntesis finales de estilo Markdown. Establecemos esto en false porque debería ser responsabilidad del usuario analizar las URL de Markdown. | |
apostrophes | Boolean | false | Coincide con apóstrofos. Establecemos esto en false porque no queremos que la cadena background: url('http://example.com/pic.jpg'); resulte en http://example.com/pic.jpg'. Consulta este issue para más información. | |
trailingPeriod | Boolean | false | Coincide con puntos finales. Establecemos esto en false de forma predeterminada ya que el comportamiento en el mundo real querría example.com en lugar de example.com. como coincidencia (esto es diferente de url-regex, donde se coincide con el punto final en ese paquete). | |
ipv4 | Boolean | true | Coincide con URL IPv4. | |
ipv6 | Boolean | true | Coincide con URL IPv6. | |
tlds | Array | tlds | Coincide con una lista específica de TLD, o con la lista predeterminada proporcionada por tlds. | |
returnString | Boolean | false | Devuelve la RegExp como una cadena en lugar de una RegExp (útil para lógica personalizada, como hicimos con Spam Scanner). |
falseapostrophe, que está establecida en false de forma predeterminada (url-regex la tenía establecida en true).trailingPeriod, que está establecida en false de forma predeterminada (lo que significa que las coincidencias no contendrán puntos finales, mientras que url-regex la tenía establecida en true).