Sichere Weitergabe von Benutzereingaben an den Befehl

Sichere Weitergabe von Benutzereingaben an den Befehl

daemonAuf Server A läuft ein Daemon von mir .

Dort gibt es ein argumentbasiertes Skript zur Steuerung des Daemons daemon_adm.py(Server A). Über dieses Skript kann ich „Nachrichten“ einfügen, die daemonvon Benutzereingaben stammen. Freitext, was immer Sie möchten.

Anschließend gibt es im Server B eine Webschnittstelle für daemon_adm.pyPHP unter Verwendung der SSH2-Klasse von phpseclib.

Ich weiß, dass dringend davon abgeraten wird, Benutzereingaben an die Befehlszeile weiterzugeben, aber es muss doch eine Möglichkeit geben, den Text vom Webserver B an daemon_adm.pyServer A weiterzugeben.

Wie kann ich einen Text sicher als Argument an ein Befehlszeilenprogramm übergeben?

Auch wenn ich die Argumente wiedergebe und sie wie daemon_adm.pyfolgt weiterleite:

<?php 
$command = '/path/to/daemon_adm.py "'.$text.'"';
ssh->exec($command);
// or whatever other library or programming language
?>

Da dieser Befehl von einer SSH-Schnittstelle mit einer formatierten Zeichenfolge ausgeführt wird, könnte Code eingeschleust werden

<?php 
$text = 'safetext"; echo "hazard"';
$command = '/path/to/daemon_adm.py "'.$text.'"';
ssh->exec($command);
// command sent: /path/to/daemon_adm.py "safetext"; echo "hazard"
?>

Meine derzeitige Option besteht darin, jede Benutzereingabe in Base64 zu kodieren (das meines Wissens keine Anführungszeichen und Leerzeichen in seinem Zeichensatz verwendet) und sie darin daemon_adm.pywie folgt zu dekodieren:

<?php 
$text = 'safetext"; echo "hazard"';

// Enconding it to base64

$command = '/path/to/daemon_adm.py '.$encoded_text;
ssh->exec($command);

// command sent: /path/to/daemon_adm.py c2FmZXRleHQiOyBlY2hvICJoYXphcmQi
?>

Ist das sicher genug oder kompliziert?

-- BEARBEITEN --

Eine indirekte Lösung, wie von Barmar vorgeschlagen, würde darin bestehen, daemon_adm.pydie Textdaten von stdin und nicht als von der Shell analysierbares Argument zu akzeptieren.

Antwort1

ssh2::exec()stdingibt einen Stream zurück, der mit den , stdout, und stderrdes Remote-Befehls verbunden ist . Sie können also Folgendes tun:

$command = '/path/to/daemon_adm.py';
$stream = $ssh->exec($command);
fwrite($stream, "$text\n");

Wenn Sie die Parameter nicht über stdin übergeben möchten, können Sie verwendenescapeshellarg():

$command = '/path/to/daemon_adm.py ' . escapeshellarg($text);
$ssh->exec($command);

Antwort2

Um einen String in einen Shell-Ausschnitt einzufügen und dafür zu sorgen, dass die Shell den String wörtlich interpretiert, gibt es zwei relativ einfache Ansätze:

  • Umgeben Sie die Zeichenfolge mit einfachen Anführungszeichen und ersetzen Sie jedes einfache Anführungszeichen 'durch die 4-stellige Zeichenfolge '\''.
  • Stellen Sie jedem ASCII-Satzzeichen das Präfix voran \(Sie können auch anderen Zeichen das Präfix voranstellen) und ersetzen Sie Zeilenumbrüche durch '␤'oder "␤"(Zeilenumbruch zwischen einfachen oder doppelten Anführungszeichen).

Wenn Sie einen Remote-Befehl über SSH aufrufen, beachten Sie, dass die Remote-Shell den Befehl erweitert. Wenn Sie SSH über eine lokale Shell aufrufen, führt darüber hinaus die lokale Shell auch die Erweiterung durch. Sie müssen also zweimal Anführungszeichen setzen.

PHP bietet dieescapeshellargFunktion zum Escapen von Shell-Sonderzeichen.execführt eine Erweiterung durch, rufen Sie es zweimal für die Zeichenfolge auf, die Sie schützen möchten.

Beachten Sie, dass dies für Textzeichenfolgen in Ordnung ist, aber nicht für Bytezeichenfolgen. Die meisten Shells lassen keine Nullbytes durch.

Ein anderer Ansatz, der weniger fehleranfällig ist und beliebige Bytefolgen durchlässt, aber Änderungen am anderen Ende erfordert, istÜbergeben Sie die Zeichenfolge an die Standardeingabe des Remote-Befehls.

Antwort3

Sie könnten so etwas tun wie ...

$ssh->enablePTY();
$ssh->exec('/path/to/daemon_adm.py');
$ssh->write('...');
echo $ssh->read();

verwandte Informationen