Tema resolvido: erro de timeout ao buscar corrigido pela remoção da pré-solução de DNS

Continue a discussão de Recent updates seemed to stop rake task themes:update to use a proxy server:\n\nEu não conseguia buscar ou atualizar nenhum componente de tema por causa desse erro de tempo limite, finalmente descobri. Removendo as seguintes linhas que começam com - no arquivo \u003cDiscourse\u003e/lib/theme_store/git_importer.rb:\n\nrb\n def clone_http!\n uri = redirected_uri\n\n raise_import_error! if %w[http https].exclude?(@uri.scheme)\n\n- addresses = FinalDestination::SSRFDetector.lookup_and_filter_ips(uri.host)\n\n- raise_import_error! if addresses.empty?\n\n env = { \"GIT_TERMINAL_PROMPT\" =\u003e \"0\" }\n\n args =\n clone_args(\n uri.to_s,\n- \"http.followRedirects\" =\u003e \"false\",\n- \"http.curloptResolve\" =\u003e \"#{uri.host}:#{uri.port}:#{addresses.join(\",\")}\",\n )\n\n begin\n Discourse::Utils.execute_command(env, *args, timeout: COMMAND_TIMEOUT_SECONDS)\n rescue RuntimeError\n raise_import_error!\n end\n end\n\n\nEste código processa uma pré-solução de DNS e força o git a usar os endereços IP obtidos da pré-solução, eu não sei por que sempre falhava no meu servidor, então eu removi a lógica.\n\nNa verdade, eu tenho uma pergunta sobre sua existência, o próprio git fará uma solução de DNS, por que precisamos dessa lógica? Isso não é distinto.

SSRF (como mencionado em FinalDestination::SSRFDetector) significa Server-Side Request Forgery (Falsificação de Requisição do Lado do Servidor). Refere-se a um mecanismo pelo qual um invasor engana seu servidor para acessar recursos que o invasor, de outra forma, não conseguiria acessar.

Por exemplo, imagine que você estivesse executando o Discourse em uma rede privada com um proxy reverso para permitir acesso a partir da internet. Um invasor poderia criar um tópico com um link apontando para um endereço IP dentro de sua rede privada. O sistema Onebox do Discourse poderia então recuperar essa URL e exibir seu conteúdo em um Onebox.

Para evitar isso, o Discourse não acessa nenhuma URL fornecida pelo usuário sem primeiro verificar se ela não aponta para endereços IP privados.

Argumentavelmente, isso pode ser menos importante para repositórios git usados por temas e componentes de tema, já que estes são especificados por administradores, mas o Discourse está optando pela cautela neste caso.

1 curtida

Obrigado pela sua explicação. Encontrei a solução definitiva para a minha situação.

Minha situação: Estou usando o WSL (atribuído como 192.168.1.2 na rede virtual) para executar o Discourse, e ele está configurado para conectar servidores remotos através do proxy em execução no Windows (atribuído como 192.168.1.1).

Quando o Discourse tenta conectar um servidor remoto por um nome de host, o SSRF tenta usar o DNS do sistema definido em /etc/resolv.conf, no entanto, por padrão, o endereço IP da rede virtual do Windows (o meu é 192.168.1.1) é o único servidor DNS do WSL. Mas a sub-rede 192.168.0.0/16 foi colocada na lista negra pelo SSRFDetector, e ele nem consegue obter a resposta do DNS. (Eu apenas dei uma olhada rápida no código, então não sei se a opinião acima está correta)

Ao adicionar 192.168.1.1 ao item de configuração Allowed internal hosts, tudo continua funcionando. Hum, talvez o Discourse não devesse colocar na lista negra nomes de host nas variáveis de ambiente HTTP_PROXY e HTTPS_PROXY?