Thème résolu : erreur de délai d'attente lors de la récupération corrigée en supprimant la pré-résolution DNS

Continuez la discussion à partir de Les mises à jour récentes semblent avoir arrêté la tâche rake themes:update pour utiliser un serveur proxy :

Je n’arrivais pas à récupérer ou à mettre à jour de composant de thème à cause de cette erreur de délai d’attente, j’ai finalement trouvé la solution. Supprimer les lignes suivantes commençant par - dans le fichier \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

Ce code traite une pré-résolution DNS puis force git à utiliser les adresses IP obtenues à partir de la pré-solution, je ne sais pas pourquoi cela échouait toujours sur mon serveur, alors j’ai supprimé la logique.

En fait, j’ai une question sur son existence, git effectue lui-même une résolution DNS, pourquoi avons-nous besoin de cette logique ? Ce n’est pas distinct.

SSRF (comme mentionné dans FinalDestination::SSRFDetector) signifie Server-Side Request Forgery (Falsification de requête côté serveur). Cela fait référence à un mécanisme par lequel un attaquant trompe votre serveur pour qu’il accède à des ressources auxquelles l’attaquant ne pourrait pas accéder autrement.

Par exemple, imaginez que vous exécutez Discourse dans un réseau privé avec un proxy inverse pour permettre l’accès depuis Internet. Un attaquant pourrait créer un sujet avec un lien pointant vers une adresse IP à l’intérieur de votre réseau privé. Le système Onebox de Discourse pourrait alors récupérer cette URL et afficher son contenu dans un Onebox.

Pour éviter cela, Discourse n’accède à aucune URL fournie par l’utilisateur sans vérifier au préalable qu’elle ne pointe pas vers des adresses IP privées.

On pourrait arguer que cela est moins important pour les dépôts git utilisés par les thèmes et les composants de thème, car ceux-ci sont spécifiés par les administrateurs, mais Discourse préfère jouer la prudence ici.

1 « J'aime »

Merci pour votre explication. J’ai trouvé la solution ultime pour ma situation.

Ma situation : J’utilise WSL (assigné 192.168.1.2 dans le LAN virtuel) pour exécuter Discourse, et il est configuré pour se connecter à des serveurs distants via le proxy fonctionnant sous Windows (assigné 192.168.1.1).

Lorsque Discourse veut se connecter à un serveur distant par un nom d’hôte, SSRF essaiera le DNS système défini dans /etc/resolv.conf, cependant, par défaut, l’adresse IP vLAN de Windows (la mienne est 192.168.1.1) est le seul serveur DNS de WSL. Mais le sous-réseau 192.168.0.0/16 a été mis sur liste noire par SSRFDetector, il ne peut même pas obtenir de réponse DNS. (J’ai juste survolé son code, donc je ne sais pas si l’avis ci-dessus est correct)

En ajoutant 192.168.1.1 à l’élément de configuration Allowed internal hosts, tout continue de fonctionner. Euh, peut-être que Discourse ne devrait pas mettre sur liste noire les noms d’hôte dans les variables d’environnement HTTP_PROXY et HTTPS_PROXY ?