Damit ein Besucher PHP-Quellcode ändern kann, müsste er den Server / Script gehackt haben. Und dann ist eh alles verloren. Ob schwach geschützter Server oder Script - läuft beides aufs gleiche raus.
Damit ein Besucher PHP-Quellcode ändern kann, müsste er den Server / Script gehackt haben. Und dann ist eh alles verloren. Ob schwach geschützter Server oder Script - läuft beides aufs gleiche raus.
Wenn man einen Command-Befehl hat, der eine Variable beinhaltet die frei vom User gewählt wurde, ermöglicht man ihm (ohne weitere Absicherung, wie Validierung) die Fähigkeit den Befehl beliebig zu erweitern.
Dazu muss man nichts hacken.
Was auf unzureichende Entwicklung zurückzuführen ist.
Was genau einer der Punkte ist weswegen man Leuten davon abrät diesen Befehl zu nutzen, um so keine mögliche Angriffsfläche zu bieten.
Man kann das "Risiko" bei der Verwendung nicht einfach relativieren oder gar streichen.
Sicher, aber wie schon gesagt, hängt es allein von der Entwicklung ab. Man kann shell_exec ohne Probleme anwenden wenn man sich bewusst ist welche Risiken es birgt. Ist das gleiche wenn man einen Linux-Server nutzt - der birgt noch viel mehr Risiken. Man nutzt auch nicht just4fun beliebige Funktionen/Module ohne sich im Voraus ausreichend informiert zu haben. Und wer es ganz sicher haben möchte, installiert sich einfach eine zweite Instant des Webservice, legt diese auf einen unbekannten Port und regelt per IPTables :) natürlich eher für Backend-Anwendungen. Außerdem bin ich mir ziemlich sicher, dass man genauer definieren kann wovon es angesprochen werden darf.
;P
Wer Werte aus $_GET oder $_POST ungefiltert verwendet hat eh die Kontrolle über sein Leben verloren.
- - - - - - - - - - Beitrag nachträglich erweitert - - - - - - - - - -
Um noch etwas Konstruktives hinzuzufügen:
SQL darf auch nicht mit ungefiltertem Userinput gefüttert werden. Trotzdem rät man nicht generell von SQL ab.
PHP: escapeshellarg - Manual
PHP: escapeshellcmd - Manual
Ja, aber warum denn Syr? Es ist doch ohne Probleme nutzbar. Jetzt auf einmal muss man sich doch des Risikos bewusst sein? Das war genau der Teil, der bei deinem ersten Kommentar gefehlt hat :D. Das Informieren über Risiken ist etwas, dass viele Frischlinge und selbst ein Teil der erfahrenen Leute unterlassen.Zitat:
Man kann shell_exec ohne Probleme anwenden wenn man sich bewusst ist welche Risiken es birgt
Die Frage war, weswegen man es nicht nutzen sollte und die Antwort war auch, wenn man nicht genügend Hirn hat, sollte man es lassen.
Würde ich es persönlich unter Voraussetzung der Asicherung verwenden? Ja, denn die Laufzeit ist wesentlich geringer. Würde ich es jedoch auf biegen und brechen verwenden? Nein.
@HaZe:
Danke für deine Ergänzung, anscheinend hat es sich zu allgemein gelesen. Erst bei Syr kritisieren, dass er früher etwas nicht im Text erwähnt hat und dann selbst das gleiche machen :D. Ich füge jetzt an der Stelle noch was dazu (editierter Text, weil erst unlogischer Zusammenhang):
Häufig wird dazu geraten, für jede Kleinigkeit eine Alternative und nicht den direkten Weg zu nehmen. An der Stelle hätten wir "verwende immer Prepared Statements", verwende immer Wrapper, nutze möglichst nie exec (usw.). Für Frischlinge und Leute die sich nicht viel mit dem Thema auseinander setzen ist sowas oft besser (können auch Probleme entstehen). Bei Experten die ein Schweizer-Taschenmesser entdecken kann es passieren, dass sie gar nicht mehr auf Alternativen achten, bei denen z.b. die Validierung schon beinhaltet ist.
An der Stelle aber jetzt genug von mir davon, ansonsten findet sich hier noch ein Text über mehrere Seiten wieder, der "sinnvolles" und "nicht sinnvolles" verwenden von Funktionen beinhaltet. Gibt ja viel darüber zu sagen.
Eingaben in SQL unzureichend gefiltert zu benutzen ist gefährlich. Allerdings lässt sich die Nutzung von SQL meist nicht (sinnvoll) vermeiden. Daher rät dir keiner vor SQL ab.
Eingaben in Befehlen unzureichend gefiltert zu benutzen ist deutlich gefährlicher. Es lässt sich oft und vermutlich auch hier sehr gut vermeiden. Daher rät man allgemein vor der Nutzung tendenziell eher ab.
Die genannten escape-Funktionen sind da leider auch keine Wunderwaffen und es sind durchaus subtilere Bugs denkbar. Auf der wirklich sicheren Seite ist man nur, wenn man nur User-Input in diesen Befehlen verarbeitet bei dem man sich 100% sicher ist, dass er ungefährlich ist. Diese Sicherheit hat man (meiner Meinung) allerdings nur dann, wenn man gegen eine Whitelist prüft.
EDIT: Nicht schön, aber selten
PHP-Code:<pre>
<?php
define( 'CRC16POLYN', 0x1021 );
define( 'CRC16POLYI', 0x8408 );
function CRC16Normal( $buffer, $result ) {
if ( ( $length = strlen( $buffer ) ) > 0 ) {
for ( $offset = 0; $offset < $length; $offset++ ) {
$result ^= ( ord( $buffer[$offset] ) << 8 );
for ( $bitwise = 0; $bitwise < 8; $bitwise++ ) {
if ( ( $result <<= 1 ) & 0x10000 ) $result ^= CRC16POLYN;
$result &= 0xFFFF;
}
}
}
return $result;
}
function CRC16Kermit( $buffer ) {
$result = 0;
for ( $x=0; $x<strlen( $buffer ); $x++ ) {
$result = $result ^ ord( $buffer[$x] );
for ( $y = 0; $y < 8; $y++ ) {
if ( ( $result & 0x0001 ) == 0x0001 ) $result = ( ( $result >> 1 ) ^ CRC16POLYI );
else $result = $result >> 1;
}
}
$lowBit = ( $result & 0xff00 ) >> 8;
$highBit = ( $result & 0x00ff ) << 8;
$result = $highBit | $lowBit;
return $result;
}
function out( $in ) {
echo "0x".strtoupper(dechex($in));
echo "\n";
}
if (isset($_POST['mode']) && isset($_POST['input'])) {
switch ($_POST['mode']) {
case 'hex':
$input = hex2bin($_POST['input']);
$mod = "HEX";
break;
case 'dec':
$input = decbin($_POST['input']);
$mod = "DEC";
break;
default:
$input = $_POST['input'];
$mode = "ASCII";
break;
}
echo "Input '".htmlspecialchars($input, ENT_QUOTES, 'UTF-8')."' (mode ".$mode.")\n";
echo "CRC-CCITT (XModem):\t";
echo out(CRC16Normal($input, 0x0000));
echo "CRC-CCITT (0xFFFF):\t";
echo out(CRC16Normal($input, 0xFFFF));
echo "CRC-CCITT (0x1D0F):\t";
echo out(CRC16Normal($input, 0x1D0F));
echo "CRC-CCITT (Kermit):\t";
out(CRC16Kermit($input));
}
?>
<form method="post">
<input type="text" name="input">
<select name="mode">
<option value="ascii">ASCII</option>
<option value="hex">HEX</option>
<option value="dec">DEC</option>
<input type="submit">
</select>
</form>
</pre>
Warum sprechen wir eigentlich davon von "SQL" abzuraten?
Es geht ja um folgende Ratschläge:
- Verwende nicht mysql_connect sondern PDO [ gleichzusetzen mit: verwende curl_exec anstatt exec(curl..) - dass eine ist ein Func-Call, dass andere ein neuer Prozess , weswegen man davon abrät ]
- Verwende nicht direkt Variablen sondern Prepared Statements [ Wie wir wissen können prep-statements ohne Validierung sinnlos sein und trotzdem SQL-Inj. erlauben. Das könnte man gleichsetzen mit exec ohne die Validierung des Inputs des Users der gegebenenfalls weitere Parameter einschleust, weswegen man davon abrät ]
In Wirklichkeit könnten wir auch noch ein Dutzend anderer Befehle listen, die Sicherheitsrisiken bieten, wenn man nicht korrekt validiert. Auch kann man sagen, dass im Grunde (ohne andere Fakten zu betrachten) das meiste sicher ist, sofern man alles korrekt spezifiziert und validiert. Validierung heißt in dem Fall sowohl die Eingaben, als auch Ausgaben an jeder Stelle, egal ob Input durch User oder nicht, egal was man nicht macht oder zusätzlich macht.
Aus dem Grund hat auch jeder von uns das Korrekte zu exec gesagt:
- Syr und HaZe, die voraussetzen, dass korrekt validiert wird (deswegen keine Gefahr sehen)
- Nimbus und ich, die darauf Hinweisen, dass man sich durch schlampiges Verhalten selbst eine Sicherheitslücke dadurch schaffen kann (unter anderem wegen der Frage - wieso rät man davon ab)
- y0l0sw4gg3r keine Ahnung warum, denn er hat seinen möglichen Grund für die Ablehnung des Befehls nicht genannt.
Fälle wann etwas sinnvoller wäre steht ja nicht im Raum. Das würde dann jedoch eine über Seiten führende Debatte bzw. Zusammenfassung werden. Immerhin hängts vom "was" und "wie" ab.
Wieso rät man davon ab ist eine Verallgemeinerung - nicht jeder wird einem davon abraten, manchmal ist es sogar dumm jemanden von seinem vorhaben abzuraten, wenn es am Ende so sogar mehr Peformance liefert und gleich sicher oder noch sicherer wird (wink auf Prepared Statements - die für manche der Universalschutz gegen SQL-Inj. sind).
Weil der Hinweis nicht war "Achtung, denk an die Inputvalidierung", sondern "Benutz es lieber nicht!".
Es gibt gute Gründe bestimmte Dinge auszulagern, u.A. Performance oder - wie in diesem Fall hier - bestehende Librarys in anderen Sprachen.
Ich hatte ja auch davon gesprochen einen Wrapper zu schreiben (nichts anderes ist curl_exec ja im Grunde).
Um SQL führt aber nicht viel bzw. nichts herum (notwendiges Übel) außerdem gibt es prepared statements, die SQL-Injections ziemlich effektiv vermeiden. Daher hinkt der Vergleich meiner Meinung nach.
Ich denke ein Hauptgrund für diese Uneinigkeit ist, dass das Risiko-Nutzen-Verhältniss unterschiedlich eingeschätzt wird. Einfachheit (oder manchmal auch Faulheit) und Effizienz sind zwar toll, aber man muss auch die Risiken kennen und hier kann man mit einem kleinen Fehler großen Ärger anrichten. Die angesprochene Input-Validierung ist hier gerade der springende Punkt: sie sollte Perfekt sein und genau das ist schwierig.
Ein PHP Modul (?) um bestehende CRC-Libraries einzubinden klingt für mich nach totalem Overkill.
Das einzige das hier hinkt ist, dass man manchmal Beiträge anders versteht, als sie gemeint sind oder gegebenenfalls zwischenzeitlich nur selektiv liest.
Nimmt man SQL her, könnte man sagen, dass manchmal gesagt wird : Nimm lieber NoSQL anstatt SQL, aber da wären wir ja immer noch beim Punkt (den hat jeder richtig erkannt), dass es kein guter Vergleich wäre.
Was wäre der passende Vergleich? Siehe letzter Beitrag.
@HaZe: Du hast doch nur die simple Frage gestellt, wieso vom Befehl abzuraten sei und die erste Antwort lieferte schon, dass es an der Validierung des Inputs liegt. Hat ja nichts mit deinem zusätzlichen Vorschlag des Wrappers zutun, wo so etwas bereits bedacht wird ;).
Von der Frage des Erstellers dieses Threads ist das aber nun etwas abgeschweift, oder?
Wir sind zwar etwas abgeschweift, aber es ist durchaus eine interessante Diskussion.
Der Threadersteller hat sich zwar nicht mehr öffentlich gemeldet, aber nach meinem Stand tut mein gepostete Code wohl was er soll.
Es ist alles noch im Rahmen.
Da der User sein Problem bereits mit exec gelöst hat (wie einige Beiträge zuvor zu entnehmen ist - bzw. aus dem Kommentar "shell_exec funzt"), war der weitere Verlauf, also die Diskussion im Zusammenhang mit der Verwendung von exec (und alternativen Beispielen) absolut zulässig.
Es empfiehlt sich jedoch den Melde-Button zu betätigen, wenn man denkt, dass ein Gesprächsverlauf ins Off-Topic über geht.