Heim >Backend-Entwicklung >Golang >Grundlegendes zu Command-Injection-Schwachstellen in Go
Go-Entwickler müssen möglicherweise Systembefehle für verschiedene Szenarien verwenden, wie z. B. Bildbearbeitung, bei der sie Bilder verarbeiten oder in der Größe ändern oder Systembefehle ausführen müssen, um Ressourcen zu verwalten oder Metriken oder Protokolle zu sammeln.
Ein anderes Mal bauen Sie vielleicht ein neues System in Go auf, das mit bestehenden Legacy-Systemen verbunden werden muss. Diese Schnittstelle basiert auf der Ausführung von Systembefehlen und der Verarbeitung ihrer Ausgabe.
In jedem Fall ist es wichtig, sichere Codierungskonventionen zu befolgen, wenn Systembefehle erzeugt werden, da dies zu einer Sicherheitslücke führen könnte, die als Befehlsinjektion bekannt ist.
Befehlsinjektion ist eine Sicherheitslücke, wenn eine Anwendung unsichere, vom Benutzer bereitgestellte Daten (z. B. Eingaben aus einem Webformular) an eine System-Shell übergibt. Diese Schwachstelle ermöglicht es einem Angreifer, beliebige Befehle auf dem Host-Betriebssystem unter demselben Anwendungsbenutzer auszuführen.
In Go beinhaltet eine Befehlsinjektion oft die Verwendung des os/exec-Pakets, um Systembefehle zu erzeugen.
Betrachten Sie das folgende Go-Codebeispiel:
func handler(req *http.Request) { cmdName := req.URL.Query()["cmd"][0] cmd := exec.Command(cmdName) cmd.Run() }
In diesem Codeausschnitt wird der cmdName direkt aus den Anforderungsabfrageparametern extrahiert und zum Erstellen eines Befehls verwendet, der auf dem Server ausgeführt wird. Dies ist ein klassisches Beispiel für eine Sicherheitsanfälligkeit durch Befehlsinjektion, da ein Angreifer den Wert der cmd-Abfragezeichenfolge manipulieren kann, um einen beliebigen Befehl auszuführen, was möglicherweise den Server gefährdet.
Ein Angreifer könnte eine Anfrage mit einem böswilligen Befehl erstellen, wie zum Beispiel:
http://example.com/execute?cmd=rm%20-rf%20/
Warum ist die Befehlsinjektion gefährlich? Die Befehlsinjektion ist gefährlich, da sie es Angreifern ermöglicht, beliebige Befehle auf dem Server auszuführen, was schwerwiegende Folgen haben kann, darunter:
Die Auswirkungen eines erfolgreichen Command-Injection-Angriffs können verheerend sein und sich nicht nur auf das kompromittierte System, sondern auch auf den Ruf des Unternehmens und das Vertrauen der Kunden auswirken.
Go-Entwickler, die für ihre Vorliebe für Einfachheit und Leistung bekannt sind, entscheiden sich möglicherweise für die Integration von Systembefehlen, um die Funktionen dieser Dienstprogramme zu nutzen. Dieser Ansatz ermöglicht es ihnen, sich auf die Entwicklung robuster Anwendungen zu konzentrieren, ohne das Rad neu erfinden zu müssen. Allerdings bringt diese Integration ihre eigenen Herausforderungen mit sich, insbesondere im Hinblick auf die Sicherheit.
Um ein realistischeres Szenario zu veranschaulichen, stellen Sie sich eine Go-Anwendung vor, die Bilddateien mithilfe eines Befehlszeilendienstprogramms wie „convert“ verarbeitet.
Wir erkunden eine Go-Anwendung, die darauf ausgelegt ist, Anfragen zur Bildgrößenänderung zu verarbeiten. Die Anwendung verwendet das Gin-Webframework, um einen POST-Endpunkt, /cloudpawnery/image, zu definieren, der die Größenänderung von Bildern basierend auf Benutzereingaben verarbeitet. Dieser Endpunkt akzeptiert Parameter wie „tenantID“, „fileID“ und „fileSize“ aus der Abfragezeichenfolge. Der Parameter „fileSize“ ist optional und beträgt standardmäßig „200“, wenn er nicht angegeben wird.
Der folgende Codeausschnitt zeigt eine anfällige Implementierung in Go.
func handler(req *http.Request) { cmdName := req.URL.Query()["cmd"][0] cmd := exec.Command(cmdName) cmd.Run() }
Die downloadAndResize-Funktion erstellt eine Befehlszeichenfolge, um die Größe des Bildes mithilfe von „convert“ zu ändern, und führt sie mithilfe von exec.CommandContext aus.
Wie erstellt die Funktion downloadAndResize eine Befehlszeichenfolge? Diese Eingabe erfolgt mithilfe der vom Benutzer bereitgestellten Dateigröße. Diese Zeichenfolge wird dann ausgeführt, was es einem Angreifer möglicherweise ermöglicht, schädliche Befehle einzuschleusen. Um dieses Risiko zu mindern, sollten Go-Entwickler alle Benutzereingaben validieren und bereinigen, parametrisierte Befehle verwenden und Sicherheitspraktiken nutzen, die die Befehlsausführung sicher handhaben.
Bei der Go-Entwicklung ist es wie bei jeder anderen Sprache von größter Bedeutung, sicherzustellen, dass Ihr Code vor Schwachstellen durch Befehlsinjektion geschützt ist. Bei der Befehlsinjektion kann ein Angreifer beliebige Befehle auf dem Host ausführen, was zu unbefugtem Zugriff, Datenschutzverletzungen und anderen schwerwiegenden Sicherheitsproblemen führen kann.
Lassen Sie uns einige Best Practices erkunden, um diese Risiken zu mindern.
Einer der grundlegenden Schritte zur Verhinderung der Befehlsinjektion ist eine strenge Eingabevalidierung und -bereinigung. Im bereitgestellten Beispiel erstellt die Funktion „downloadAndResize“ eine Befehlszeichenfolge mithilfe vom Benutzer bereitgestellter Eingaben wie „fileSize“. Wenn diese Eingaben nicht ordnungsgemäß validiert werden, könnte ein Angreifer bösartige Befehle einschleusen.
So können Sie die Eingabevalidierung verbessern:
Hier ist ein Beispiel dafür, wie Sie diese Praktiken umsetzen könnten:
func handler(req *http.Request) { cmdName := req.URL.Query()["cmd"][0] cmd := exec.Command(cmdName) cmd.Run() }
Trotzdem können wir viel besser tun, um Go-Code vor der Befehlsinjektion zu schützen. Lesen Sie weiter!
Eine weitere wirksame Strategie besteht darin, nach Möglichkeit die direkte Ausführung von Systembefehlen zu vermeiden. Nutzen Sie stattdessen sichere APIs oder Bibliotheken, die die erforderliche Funktionalität bereitstellen, ohne Ihre Anwendung dem Risiko der Befehlsinjektion auszusetzen.
Wenn Ihre Anwendung beispielsweise Bilder bearbeiten muss, sollten Sie die Verwendung einer Go-Bibliothek wie github.com/disintegration/imaging in Betracht ziehen, anstatt einen externen Befehl wie „convert“ aus der ImageMagick-Softwarebibliothek aufzurufen. Dieser Ansatz kapselt die Funktionalität in der typsicheren Umgebung von Go und reduziert so die Angriffsfläche.
http://example.com/execute?cmd=rm%20-rf%20/
Durch die Verwendung von Bibliotheken wie Imaging in Go entfällt die Notwendigkeit, Shell-Befehle zu erstellen und auszuführen, wodurch das Risiko einer Befehlsinjektion verringert wird. Dennoch ist es in einigen Bibliotheken und Sprachökosystemen möglich, dass das Drittanbieterpaket ein einfacher Wrapper für die Befehlsausführung ist, sodass eine Überprüfung des Codes für solche sensiblen Vorgänge zwingend erforderlich ist.
Im vorherigen Beispiel haben wir eine potenziell anfällige Go-Anwendung demonstriert, die die Funktion exec.CommandContext zum Ausführen von Shell-Befehlen verwendet. Dieser Ansatz kann, wie bereits erwähnt, zu Schwachstellen bei der Befehlsinjektion führen.
Versuchen wir, die downloadAndResize-Funktion umzugestalten, um sicherzustellen, dass Benutzereingaben nicht zur willkürlichen Befehlsausführung führen.
Eine wirksame Möglichkeit, die Befehlsinjektion zu verhindern, besteht darin, die Erstellung von Shell-Befehlszeichenfolgen direkt aus Benutzereingaben zu vermeiden. Stattdessen können wir die Funktion exec.Command mit separaten Argumenten verwenden, was dabei hilft, Benutzereingaben sicher als Parameter an den Befehl zu übergeben, ohne die Shell aufzurufen und ohne Benutzern die Steuerung des eigentlichen Befehls zu ermöglichen.
Hier ist eine überarbeitete Version der downloadAndResize-Funktion, die die Schwachstelle durch Befehlsinjektion behebt:
func handler(req *http.Request) { cmdName := req.URL.Query()["cmd"][0] cmd := exec.Command(cmdName) cmd.Run() }
In diesem Refactor haben wir den Befehl von seinen Argumenten getrennt. Durch die Verwendung von exec.CommandContext mit separaten Argumenten vermeiden wir die Notwendigkeit, eine Shell-Befehlszeichenfolge zu erstellen. Diese Methode stellt sicher, dass Benutzereingaben als Daten und nicht als ausführbarer Code behandelt werden, wodurch das Risiko einer Befehlsinjektion erheblich verringert wird.
Wir haben auch die Notwendigkeit eines Shell-Aufrufs beseitigt. Der überarbeitete Code ruft nicht die Shell (sh -c) auf, die ein üblicher Vektor für die Befehlsinjektion ist. Stattdessen wird das Konvertierungsdienstprogramm direkt mit den angegebenen Argumenten aufgerufen.
Snyk Code ist ein leistungsstarkes statisches Analysetool, das Entwicklern hilft, Schwachstellen in ihrer Codebasis zu identifizieren und zu beheben. Es lässt sich nahtlos in Ihre IDE und Ihren Entwicklungsworkflow integrieren und bietet Echtzeit-Feedback zu potenziellen Sicherheitsproblemen.
Im bereitgestellten Go-Beispiel erstellt die downloadAndResize-Funktion einen Shell-Befehl mithilfe der vom Benutzer bereitgestellten Eingabe:
http://example.com/execute?cmd=rm%20-rf%20/
Dieser Code ist anfällig für Befehlsinjektionen, da er Benutzereingaben direkt in die Befehlszeichenfolge integriert.
Was wäre, wenn Ihr Team Entwickler hätte, die sich der Schwachstellen bei der Befehlsinjektion nicht bewusst wären?
Wären Sie in der Lage, den Aufruffluss der statischen Analyse zwischen Dateien in einer Codeüberprüfung leicht zu lokalisieren, um diese Schwachstelle durch Befehlsinjektion zu finden?
Hier kommt Snyk ins Spiel.
Sehen Sie sich an, wie Anwendungssicherheit mit der Snyk-Code-Erweiterung vereinfacht wird, die anfälligen Code in Echtzeit im VS-Code-Editor hervorhebt:
Snyk kann dabei helfen, solche Schwachstellen zu identifizieren, indem es Ihren Go-Code scannt und Fälle markiert, in denen Benutzereingaben in Shell-Befehlen unsicher verwendet werden. Snyk zeigt Ihnen echte Commits anderer Open-Source-Projekte, die diese spezifische Schwachstelle gemindert haben, sodass Sie mehrere Code-Referenzen als Beispiele dafür erhalten, wie „gut aussieht“.
Noch mehr: Wenn Sie auf die Registerkarte PROBLEMÜBERSICHT klicken, erhalten Sie einen Drilldown mit weiteren Details und Best Practices zur Verhinderung der Befehlsinjektion. Diese Registerkarte bietet detaillierte Einblicke und Empfehlungen zur Minderung dieser Risiken. Sie ist direkt in der IDE-Ansicht verfügbar, während Sie programmieren, und Sie können diese Aktionen ohne kostspieligen Kontextwechsel verfolgen:
Um weitere Informationen darüber zu erhalten, wie Sie Ihren Code vor solchen Schwachstellen schützen können, sollten Sie die Installation der Snyk Code IDE-Erweiterung und die Verbindung Ihrer Git-Projekte in Betracht ziehen, um Sicherheitsprobleme in Ihren Go-Anwendungen zu identifizieren und zu beheben. Sie können dies einfach und kostenlos tun, indem Sie sich anmelden, um mit dem Scannen Ihres Codes auf Schwachstellen zu beginnen.
Das obige ist der detaillierte Inhalt vonGrundlegendes zu Command-Injection-Schwachstellen in Go. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!