Ich habe ein Formularfeld auf meiner Seite, und wenn der Benutzer eine einfache mathematische Gleichung darin eingibt, möchte ich den Wert durch die Lösung ersetzen. Wenn der Benutzer also 1 + 2
in das Feld eingibt und eingibt, gebe ein, ersetze ich den Eingabewert durch 3
.
Derzeit werte ich die Gleichung nur aus, wenn sie mit dieser Regex übereinstimmt:
%Vor%Das heißt, wenn die gesamte Zeichenfolge aus Ziffern, Leerzeichen, Plus-, Minus-, Multiplikations- oder Divisionszeichen besteht.
Dann überprüfe ich den Wert wie folgt:
%Vor%Dieses Formularfeld kann von einem Abfragezeichenfolgenparameter vorab ausgefüllt werden und der Client versucht, es auszuführen. Ein potentieller Angriff wäre mysite.com?inputVal=cookieStealingProgram . Ich möchte nicht, dass Benutzer in der Lage sind, sich mit dem Ausnutzen von Code zu verbinden.
Ich möchte Klammern und Exponenten zum Regex hinzufügen , damit der Benutzer beispielsweise (1 + 2) / 3 ^ 5
eingeben kann. Während ich ziemlich sicher bin, dass keine Exploits mit nur Zahlen und Operatoren möglich sind, bin ich mir nicht sicher über einen Fall mit Klammern.
Ich bin mir bewusst, dass mit nur Kombinationen der Zeichen ! [ ] + ( )
ein vollständig ausführbares Javascript-Programm erstellt werden kann . Ich habe auch versucht, nach "javascript exploit characters" und verschiedenen Kombinationen in Google zu suchen, aber es ist nicht einfach zu finden.
Meine spezielle Frage ist kann ein beliebiges Javascript-Programm nur mit 0-9 . + - / * ( ) ^
(Leerzeichen erlaubt) geschrieben werden? Da es ein bisschen offen ist, wenn nach einigen Tagen kein Beispiel mehr zur Verfügung steht, kann ich diese Frage jetzt abschließen.
Ich implementiere NICHT und mache auch keinen Parser, um das zu tun. Das ist irrelevant für die Frage
Die Antwort auf die Frage lautet no . Es ist unmöglich, ein Arbiträrprogramm unter Verwendung der gegebenen Eingaben, einschließlich Klammern, zu erstellen. Um ein Programm zu erstellen, müssen Sie in der Lage sein, Zeichenfolgen zu erstellen. Mit diesen Einschränkungen erreichen Sie am ehesten NaN
und Infinity
. Es ist jedoch nicht möglich, eine dieser Zeichen in eine Zeichenfolge umzuwandeln, ohne dass Anführungszeichen oder geschweifte Klammern verwendet werden.
tl; dr Sie sind blockiert, weil Sie keine Zeichenfolgen erstellen können.
Die Kommentare haben einige gültige Punkte.
Um Ihre Frage zu beantworten, begrenzen Sie die Größe der Gleichung, die eingegeben werden kann.
Diese document.getElementsByTagName("body")[0].style.display = "none";
Wird in folgendes umgewandelt:
%Vor%Das Obige ist nur ein Bruchteil von dem, in den es verwandelt wird. Das gesamte Skript besteht aus 48.000 Zeichen. Stack ließ mich nicht einmal alles posten
Und das ist so grundlegend wie es für ein Skript, das "voll funktionsfähig" ist, ich bezweifle, dass jeder Benutzer eine Gleichung der Länge auch nur annähernd eingeben möchte.
Eval
ist sehr gefährlich, wie Sie gelernt haben. Die moderne Browser-Escape-Luke, um eval clientseitig, das JSON
-Objekt nicht verwenden zu müssen, wird Ihren Anforderungen nicht gerecht, da Sie Ausdrücke auswerten müssen, die JSON
nicht zulässt.
Auf der positiven Seite wollen Sie wirklich nur ein paar Operatoren, + - / * ^
und Klammern, erlauben, was keine sehr komplexe Ausdruckssprache ist.
Anstatt zu versuchen, reguläre Ausdrücke zu verwenden, um die Eingabe in eval zu validieren, schlage ich vor, dass Sie einfach einen Ausdruck-Evaluator implementieren, entweder in der Clientseite von JavaScript oder in der Sprache Ihrer Serverwahl.
Googeln wird viele verschiedene mit etwas anderen Fähigkeiten finden, oder Sie können es als eine Lernübung nehmen, um Ihre eigenen zu rollen.
Antwort 1. Wenn Sie nur die Symbole verwenden, die Sie aufgelistet haben, können Sie keine Bezeichner erstellen. Die einzigen möglichen Programme sind also arithmetische Ausdrücke. Um die schmale Frage zu beantworten, lautet die Antwort Nein.
Doch Stack Overflow wird von vielen gelesen, und es gibt einige eng verwandte Probleme, die die Konsequenzen in ähnlichen Situationen ändern würden.
Antwort 2. Antwort 1 wird am besten verwendet, wenn die Codebasis von einer einzelnen Person verwaltet wird, die weiß, was sie tut. Wenn jemand später kam und wollte, dass der Benutzer (sagen wir) in der Lage ist, einen Preis anderswo symbolisch zu referenzieren, haben Sie jetzt Kennungen. Wenn eine spätere Änderung einfach darin bestand, einem Regex Zeichen hinzuzufügen, weil das der einfachste Weg ist, um es zum Laufen zu bringen, dann sind Sie gefährdet. Obwohl ich generell kein Fan von Sprachfunktionen bin, die versuchen, Dummheit zu verhindern, ist dies eine besondere Art, Code für eine bestimmte Aufgabe zu schreiben, die viel zu anfällig für schlechte Modifikationen zu sein scheint.
Antwort 3. Die ursprüngliche Referenzimplementierung des JSON-Parsers verwendet eval()
, schützt diese Anweisung jedoch mit einem JSON-Syntaxverifizierer, der sicherstellt, dass die Eingabe wohlgeformt ist. Dies geschieht ohne einen Parser, sondern durch einige geschickt geschriebene reguläre Ausdrücke, die gültige Teilzeichenfolgen erkennen und komprimieren. Es ist etwas analog zu einer Operation reduce
in syntaxgesteuerter Übersetzung, aber ohne den Ausdruck tatsächlich zu bewerten. In der aktuellen Situation schreibt eine Regex-Substitution wie /[0-9]+\+[0-9]+/0/
eine primitive Addition als 0
um. Schreibe eine Regel für jede mögliche Reduktion und lege sie alle in eine Schleife. Die Schleife wird beendet, wenn die anfängliche Zeichenfolge dieselbe Länge wie die letzte Zeichenfolge hat. Das Akzeptanzmuster nach dem Neuschreiben wäre dann /[0-9]+/
und normalerweise nur 0
.
Antwort 4. Die Verwendung eines Parser-Generators ist oft die beste Lösung für diese Klasse von Problemen, wenn die Möglichkeit besteht, dass die Arten von Ausdrücken jemals Identifikatoren benötigen. Ich würde nicht vertrauen, dass ein Regex-Rewriting-System in einem solchen Fall korrekt verwaltet wird. Zugegeben, für die gestellte Frage erscheint es genau wie Overkill.
Ich empfehle Answer 3 für den Produktionscode.
Antwort 2 Erweiterung. Das größte erkennbare Risiko (eine Teilmenge aller Risiken) besteht darin, dass jemand$
zur akzeptierten Liste von Zeichen hinzufügt, weil es schließlich ein Preisfeld ist und "Benutzer haben beschwerte sich". $
ist ein gültiger Bezeichner (häufig als jQuery zugewiesen), aber auch window.%code%
()
und %code% ist ein gültiger Funktionsaufruf. Obwohl dies kein naheliegendes Risiko ist, ist es ein Beitrag, sagen wir, wenn es einen anderen Sicherheitsdefekt gibt, der es erlaubt, die Eigenschaft %code% zu definieren, aber nicht aufzurufen. Ein solcher Code wäre ein Sicherheitsdefekt, selbst wenn er nicht zu einer Sicherheitsverletzung führt.
Tags und Links javascript math regex exploit