2012-01-06 14 views
8

Tengo una aplicación ASP.Net WebForms estándar que se ejecuta en IIS 7.0 con una canalización integrada administrada. Muchas de las imágenes en nuestro sitio tienen espacios en los nombres de sus archivos (por ejemplo, './baseball drawing.gif'). Cuando ponemos estas imágenes en nuestras páginas html que url codificar los caminos para que nuestras etiquetas HTML img ven así < img src='./baseball%20drawing.gif' />Permitir doble dirección URL Ruta de solicitud codificada para ser válida

Ahora, el problema viene cuando ciertos motores de búsqueda y webcrawlers tratan de índice de nuestro sitio. Cuando raspen nuestras páginas, codificarán html nuestras rutas ya codificadas en html obteniendo enlaces de imagen como este './baseball%2520drawing.gif' donde %25 es la codificación de URL para '%'. Esto ocasiona dos problemas:

  1. Cuando los usuarios obtienen resultados de estos motores de búsqueda, reciben enlaces rotos.
  2. Cuando los usuarios intentan navegar a estos enlaces rotos arrojan errores en nuestro sistema.

Como puede ver, esta es una situación de perder. Los usuarios obtienen enlaces rotos y recibimos ruido en nuestros registros de errores.

He estado tratando de encontrar la forma de corregir este problema sin suerte. Esto es lo que he intentado:

  1. Establecer <requestFiltering allowDoubleEscaping='true'> en web.config para evitar el "404.11 URL Double Escaped error". Esto corrigió el primer error pero causó uno nuevo, "se encontró un Request.Path potencialmente peligroso".
  2. Se ha eliminado el '%' del <httpRuntime requestPathInvalidChars> para evitar el error "Request.Path potencialmente peligroso". Esto corrigió el segundo error, pero ahora tenemos un tercero, "No se puede encontrar el recurso".
  3. Hice una pausa en mi código para ver Request.Path. Parece que está bien con un valor de 'Ball Image.gif' en lugar de 'Ball% 2520Image.gif'. Siendo este el caso, no estoy seguro de por qué no está funcionando.

Siento que tengo un súper truco en el que tengo que deshabilitar todo sin entender realmente por qué nada está funcionando. Así que supongo que mi pregunta es tres veces

  1. ¿Por qué el intento de solución 1 no solucionó el problema?
  2. ¿Por qué la solución 2 no solucionó el problema?
  3. ¿Por qué mi Request.Path se ve bien en el paso 3 pero todavía no funciona?

Cualquier ayuda que alguien pueda proporcionar sería muy apreciada.

+0

Fuera de interés, ¿qué motor de búsqueda está roto? –

+0

Buena pregunta. Clean Image Search es uno (http://www.cleanimagesearch.com). Para ver un ejemplo de lo que estoy hablando busque "imagen de béisbol". Una de las primeras imágenes que saldrá se romperá. Si hace clic en el enlace a esa imagen y reemplaza el% 25 en la url con simplemente% todo funcionará bien. También hay muchos sitios basura que simplemente son un conglomerado de imágenes de toda la web que también contienen enlaces rotos. Si desea un ejemplo de uno de estos, le puedo enviar un enlace por correo electrónico (no confío en sitios como estos, así que no quiero publicar el enlace aquí). –

+0

También creo que este problema se produce cuando se hace una búsqueda de imágenes de Google en un iPad. En ese caso, sin embargo, Google es lo suficientemente inteligente como para manejar el error correctamente para que la imagen se muestre correctamente. Acabamos de recibir un error en nuestros archivos de registro. En este momento tenemos un filtro en el lugar para ignorar todos los errores causados ​​por Google cuando el UserAgent es un IPad y el error es que Request.Path contiene un%. –

Respuesta

15

OK, después de mucha búsqueda en Internet y mucha experimentación, creo que finalmente entiendo lo que está pasando. Mi problema principal fue un caso de sesgo de confirmación extrema. Todo lo que leí decía lo que quería escuchar en lugar de lo que decía en realidad.Voy a resumir en gran medida los puntos clave que necesitaba entender para poder responder mi pregunta.

  1. Primero, necesitaba entender que IIS y ASP.Net son dos aplicaciones diferentes. Lo que hace IIS en pocas palabras es recibir una solicitud, enrutar esa solicitud a una aplicación que lo maneja, obtener el resultado de la aplicación de manejo y luego enviar el resultado de la aplicación al solicitante. Lo que hace ASP.Net es recibir la solicitud de IIS, manejarla y luego pasar la respuesta a IIS. Esta es una gran generalización excesiva de todo el proceso, pero para mis propósitos aquí es lo suficientemente bueno. 1

  2. Las solicitudes entrantes de ASP.Net deben pasar por dos controladores de acceso. El módulo IIS7 RequestFiltering (configurado en system.webserver/requestFiltering) y luego los filtros de solicitud HttpRuntime de ASP.Net (configurados en system.web/httpRuntime 3).

  3. El módulo IIS RequestFiltering es el único que normaliza las solicitudes entrantes y solo aplica la normalización UNA VEZ. Nuevamente repito que solo lo aplica UNA VEZ. Incluso si <requestFiltering allowDoubleEscaping="true" /> solo aplicará la normalización una vez. Entonces eso significa que '% 2520' se normalizará a '% 20'. En este punto, si allowDoubleEscaping es falso, IIS no permitirá que la solicitud pase desde '% 20' aún podría normalizarse. Sin embargo, si allowDoubleEscaping se establece en true, IIS7 pasará la solicitud '% 20' al siguiente controlador de acceso, ASP.Net. Esta fue la causa del primer error.

  4. El filtro Asp.net es donde se comprueban requestPathInvalidCharacters. Así que ahora nuestro '% 20' no es válido porque de forma predeterminada '%' es una parte de requestPathInvalidCharacters. Si eliminamos el '%' de esa lista, lo haremos a través del segundo controlador de acceso y ASP.Net intentará manejar nuestra solicitud. Esta fue la causa del segundo error.

  5. Ahora ASP.net intentará convertir nuestra ruta virtual en una ruta física en el servidor. Lamentablemente, todavía tenemos un '% 20' en nuestro camino en lugar de '' queremos que ASP.Net no pueda encontrar el recurso que queremos y arroja un 'error de recurso no encontrado'. El motivo por el que la ruta me pareció correcta cuando introduje mi código es porque coloqué un reloj en la propiedad Request.Url. Esta propiedad intenta ser útil al aplicar su propia normalización en su método ToString() haciendo que nuestro% 20 se vea como el "que queremos" aunque no lo sea. Esta fue la causa del error final.

para hacer este trabajo podemos escribir nuestro propio módulo personalizado que recibe la petición después de los dos primeros porteros y totalmente normaliza antes de entregarlo fuera a ASP.Net. Hacer esto, sin embargo, permitiría que cualquier personaje salga mientras esté codificado en la URL. Por ejemplo, normalmente no queremos permitir un '<' o un '>' en nuestras rutas ya que estos se pueden usar para insertar etiquetas en nuestro código. Como las cosas funcionan ahora, el < y> no pasarán el filtro ASP.Net ya que son parte de requestPathInvalidCharacters. Sin embargo, codificados como% 253C y% 253E, pueden si abrimos las dos primeras puertas y luego normalizamos la solicitud en nuestro propio módulo personalizado antes de entregarlo a ASP.Net.

En conclusión, permitir% 2520 estar completamente normalizado no se puede hacer sin crear un gran agujero de seguridad. Si fuera posible decirle al módulo RequestFiltering que normalice completamente cada solicitud que recibe antes de probar esa solicitud contra los primeros dos gatekeepers, entonces sería mucho más seguro, pero ahora mismo esa funcionalidad no está disponible.

Si tengo algo mal, hágamelo saber y espero que esto ayude a alguien.

+1

Explicación realmente agradable y clara. Deberían ser parte de los documentos de MS, como lo soy, lo arruinaron. –

+0

@GrimaceofDespair Gracias Grimace –

+0

Brillante. Esto me ayudó a resolver un problema muy similar. Debo señalar que en el n. ° 2, "in" system.webserver/requestFiltering debe ser system.webserver/security/requestFiltering. Eventualmente pude manejar la decodificación de url en global.asax. – secretwep

0

Si desea permitir doble escape, puede seguir las instrucciones en http://www.iis.net/ConfigReference/system.webServer/security/requestFiltering

Se trabajó para mí en IIS 7.0 con ninguna otra configuración requerida. El doble escape no tiene impacto para el código del sitio web en el que lo implementé; No sé qué implicaciones de seguridad potenciales podría haber para otros sitios.

+0

Gracias por tomarse el tiempo para responder a Andrew. A menos que me haya perdido algo, las instrucciones a las que se vinculó son las mismas que ya he seguido para permitir el doble escape. Esto es lo que vi (http://cl.ly/270I3E3n2U1Z1p0S1F3P). Me pregunto si tenemos algún otro conjunto de configuración configurado para que esto no funcione correctamente. Sin embargo, no puedo encontrar ninguna mención de algo así. Cuando llegue al trabajo el lunes, crearé un nuevo sitio web y veré si esto aún no funciona para mí. Eso nos diría si es alguna otra configuración en mi sitio o no. –

+0

Configuré un sitio de prueba vacío esta mañana con nada más que una imagen y el archivo web.config básico. Puede ver aquí que funciona con la codificación URL correcta http://cl.ly/301o3A3k0x3c2i3E3p1s. Cuando uso% 2520 sin modificar mi archivo web.config en absoluto obtengo este error http://cl.ly/1Y2w2N3D401d1U2s0s2n. Así que eliminé el% de caracteres inválidos y obtuve este http://cl.ly/1C0e2q3F1v1d0Q1N0E2h. Ahora permití la doble codificación URL y obtuve este http://cl.ly/2O0k2I1q3Q0D0x0E3O2m. No estoy seguro de cómo funcionó para usted o para cualquier otra persona sin ninguna otra configuración requerida, pero parece que sí. –

+0

(Disculpa la respuesta tardía.) ¿Estás diciendo que funciona cuando solo cambias la configuración en IIS y no en web.config? Ese es el escenario que funcionó para mí. Empecé con la configuración de IIS, y como eso funcionó, no fui más allá para cambiar web.config. –

Cuestiones relacionadas