Error de tiempo de espera al obtener tema resuelto al eliminar la pre-solución DNS

Continúe la discusión de Recent updates seemed to stop rake task themes:update to use a proxy server:

No pude obtener ni actualizar ningún componente de tema debido a ese error de tiempo de espera, finalmente lo descubrí. Eliminando las siguientes líneas que comienzan con - en el archivo \u003cDiscourse\u003e/lib/theme_store/git_importer.rb:

  def clone_http!
    uri = redirected_uri

    raise_import_error! if %w[http https].exclude?(@uri.scheme)

-    addresses = FinalDestination::SSRFDetector.lookup_and_filter_ips(uri.host)

-    raise_import_error! if addresses.empty?

    env = { "GIT_TERMINAL_PROMPT" => "0" }

    args =
      clone_args(
        uri.to_s,
-        "http.followRedirects" => "false",
-        "http.curloptResolve" => "#{uri.host}:#{uri.port}:#{addresses.join(\",\")}",
      )

    begin
      Discourse::Utils.execute_command(env, *args, timeout: COMMAND_TIMEOUT_SECONDS)
    rescue RuntimeError
      raise_import_error!
    end
  end

Este código procesa una pre-solución de DNS y luego fuerza a git a usar las direcciones IP que se obtienen de la pre-solución, no sé por qué siempre fallaba en mi servidor, así que eliminé la lógica.

De hecho, tengo una pregunta sobre su existencia, el propio git realiza una solución de DNS, ¿por qué necesitamos esta lógica? Esto no es distinto.

SSRF (como se menciona en FinalDestination::SSRFDetector) significa Server-Side Request Forgery (Falsificación de Solicitud del Lado del Servidor). Se refiere a un mecanismo por el cual un atacante engaña a su servidor para que acceda a recursos a los que el atacante no podría acceder de otra manera.

Por ejemplo, imagine que está ejecutando Discourse dentro de una red privada con un proxy inverso para permitir el acceso desde internet. Un atacante podría crear un tema con un enlace que apunte a una dirección IP dentro de su red privada. El sistema Onebox de Discourse podría entonces recuperar esa URL y mostrar su contenido en un Onebox.

Para evitarlo, Discourse no accede a ninguna URL proporcionada por el usuario sin verificar primero que no apunte a direcciones IP privadas.

Podría argumentarse que esto es menos importante para los repositorios git utilizados por temas y componentes de temas, ya que estos son especificados por los administradores, pero Discourse prefiere pecar de precavido en este caso.

1 me gusta

Gracias por tu explicación. Encontré la solución definitiva para mi situación.

Mi situación: Estoy usando WSL (asignado 192.168.1.2 en la red local virtual) para ejecutar Discourse, y está configurado para conectar servidores remotos a través del proxy que se ejecuta en Windows (asignado 192.168.1.1).

Cuando Discourse quiere conectar un servidor remoto por un nombre de host, SSRF intentará usar el DNS del sistema configurado en /etc/resolv.conf, sin embargo, por defecto, la dirección IP de la red local virtual de Windows (la mía es 192.168.1.1) es el único servidor DNS de WSL. Pero la subred 192.168.0.0/16 ha sido incluida en la lista negra por SSRFDetector, por lo que ni siquiera puede obtener una respuesta DNS. (Solo leí superficialmente su código, así que no sé si la opinión anterior es correcta).

Al agregar 192.168.1.1 al elemento de configuración Allowed internal hosts, todo sigue funcionando. Mmm, ¿quizás Discourse no debería incluir en la lista negra los nombres de host en las variables de entorno HTTP_PROXY y HTTPS_PROXY?