Im vorherigen Artikel haben wir bereits über das Wesen der Schwachstellen bei SQL-Injection-Angriffen gesprochen, die durch unsachgemäße Codierung durch Programmierer verursacht werden Problem Schauen wir uns zunächst einen Code an:
Kopieren Sie den Codecode wie folgt:
dim sql_injdata,SQL_inj,SQL_Get,SQL_Data,Sql_Post
SQL_injdata = '|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare
SQL_inj = split(SQL_Injdata,|)
Wenn Request.QueryString<> Dann
Für jedes SQL_Get in Request.QueryString
Für SQL_Data=0 bis Ubound(SQL_inj)
if instr(Request.QueryString(SQL_Get),Sql_Inj(Sql_DATA))>0 Dann
Response.Write <Script Language=javascript>alert('SQL-Anti-Injection-System fordert Sie auf, bitte nicht erneut zu injizieren!'); History.back(-1)</Script>
Antwort.Ende
Ende wenn
nächste
Nächste
Ende wenn
Wenn Request.Form<> Dann
Für jeden Sql_Post in Request.Form
Für SQL_Data=0 bis Ubound(SQL_inj)
if instr(Request.Form(Sql_Post),Sql_Inj(Sql_DATA))>0 Dann
Response.Write <Script Language=javascript>alert('SQL-Anti-Injection-System fordert Sie auf, bitte nicht erneut zu injizieren!'); History.back(-1)</Script>
Antwort.Ende
Ende wenn
nächste
nächste
Ende wenn
Hierbei handelt es sich um einen im Internet weit verbreiteten ASP-Anti-Injection-Code. Die Idee besteht darin, die von der Post-Methode und der Get-Methode übermittelten Daten zu überprüfen und die SQL-Injection durch das Filtern sensibler Zeichen wie „Insert“, „Update“ und „And“ zu verhindern usw. Wenn wir genügend Zeichen filtern, können wir theoretisch definitiv garantieren, dass wir nicht durch SQL-Injection angegriffen werden, aber seien Sie bitte vorsichtig. Lesen Sie diesen Code und achten Sie darauf, wie er durch die Funktion instr beurteilt wird. Das heißt, wenn ich das und-Zeichen filtern möchte, wird nicht nur das Wort And gefiltert, sondern auch alle Wörter enthaltend und. Alle Wörter mit den folgenden Zeichenkombinationen wurden herausgefiltert, z. B. Insel, Festland, Hand... Wenn diese Zeichen herausgefiltert würden, wäre irgendjemand immer noch bereit, sie zu verwenden? Daher ist diese Methode zum Filtern sensibler Zeichen überhaupt bedeutungslos. Was mich überrascht, ist, dass so ein Müll tatsächlich als Klassiker im Internet gepostet wird.
Einige Leute sagen, dass SQL-Injection-Angriffe durch das Zusammenfügen von SQL-Abfragezeichenfolgen verursacht werden. Die Verwendung gespeicherter Prozeduren ohne das Zusammenfügen von SQL-Abfragezeichenfolgen kann Sie also vor SQL-Injection-Angriffen schützen. Nicht unbedingt, schauen wir uns ein Beispiel für einen Stored-Procedure-Injection-Angriff an.
Der Code der gespeicherten Prozedur dt_GetNews lautet wie folgt:
PROZEDUR ERSTELLEN dt_GetNews
@newstype int
ALS
Wählen Sie * aus Nachrichten aus, wobei newstype=@newstype ist
GEHEN
Anrufcode:
<%
düstere Adoconnection
setze adoconnection=server.createobject(adodb.connection)
'.........Der relevante Code zum Aufbau einer Datenbankverbindung wird hier weggelassen
adoconnection.execute exec dt_GetNews +request(newstype)
adoconnection.close
%>
Wenn der Wert von request(newstype) gleich 1 ist, besteht das Ergebnis der Operation darin, alle Datensätze zurückzugeben, deren Newstype-Feld in der News-Tabelle 1 ist. Wenn der Wert von request(newstype) jedoch 1 ist, wird die Tabelle „news“ gelöscht Das zurückgegebene Ergebnis ist, dass die Nachrichtentabelle gelöscht wird.
Aus diesem Beispiel geht hervor, dass selbst die Verwendung gespeicherter Prozeduren immer noch angegriffen wird. Wählen Sie außerdem * aus Nachrichten aus, bei denen newstype=@newstype nicht gespleißt wird, sodass kein unvermeidlicher Zusammenhang zwischen gespleißten SQL-Abfragezeichenfolgen und SQL-Injection-Angriffen besteht. Gespeicherte Prozeduren können möglicherweise nicht vor Injektionsangriffen schützen.
Wie schreibt man es also, ohne von der SQL-Injection angegriffen zu werden? Im Folgenden werde ich eine ultimative Methode vorstellen, die sehr einfach und primitiv ist: die Datentypüberprüfung und das Ersetzen von einfachen Anführungszeichen. Unabhängig davon, ob es sich um Oracle, SQL Server, MySQL, Access oder andere relationale Datenbanken handelt, können Feldtypen grob in zwei Kategorien unterteilt werden: numerische Typen (z. B. int, float usw.) und Zeichentypen (z. B. char, varchar usw.). ). Die entsprechenden SQL-Anweisungen unterscheiden sich je nach Feldtyp geringfügig, z. B.:
Das Feld „Newstype“ in „Select * from news“, wobei „newstype=1“ ein numerisches Feld sein muss.
Wählen Sie * aus Nachrichten aus, wobei newstype='social news' das Newstype-Feld ein Zeichenfeld sein muss.
Bei numerischen Feldern müssen wir den Datentyp des Parameters überprüfen. Wenn wir beispielsweise eine Abfrageanweisung mit „select * from news“ erstellen, wobei „newstype=+v_newstype“ ist, müssen wir den Datentyp der Variablen „v_newstype“ überprüfen ist mindestens Es muss eine Zahl sein, die eine Ganzzahl oder eine Gleitkommazahl sein kann. Wenn eine solche Prüfung durchgeführt wird, wird „select * from news where newstype=+v_newstype“ niemals etwas Ähnliches wie „select * from news where newstype=1“ konstruieren ;fallen Aussagen wie Tischnachrichten. Der Grund, warum ASP anfälliger für Angriffe ist als ASP.Net, JSP usw., liegt darin, dass Variablen in ASP nicht deklariert werden müssen und der Variablentyp unklar ist.
Für Zeichenfelder müssen wir einfache Anführungszeichen (') verarbeiten. Die Verarbeitungsmethode besteht darin, ein einzelnes Anführungszeichen durch zwei einfache Anführungszeichen ('') zu ersetzen Wenn newstype='+v_newstype+' zum Erstellen der Abfrageanweisung verwendet wird, muss das einfache Anführungszeichen in v_newstype durch zwei einfache Anführungszeichen ersetzt werden, da in SQL der von zwei einfachen Anführungszeichen eingeschlossene Teil eine Zeichenfolge und zwei aufeinanderfolgende A-Anführungszeichen darstellt quote stellt ein einfaches Anführungszeichen dar. Nach dieser Verarbeitung betrachten wir die Konstruktionsmethode von select * from news, wobei newstype='+v_newstype+' ist.
Social News';Drop-Table-News--
Nach dem Ersetzen eines einfachen Anführungszeichens durch zwei einfache Anführungszeichen wird der Wert von v_newstype zu:
Soziale Nachrichten'';Drop-Table-News--
Die konstruierte SQL-Anweisung wird zu:
select * from news where newstype='social news'';drop table news—'
Das Ergebnis der Abfrage ist die Rückgabe von Datensätzen, deren Wert des Feldes „newstype“ in der News-Tabelle „Social News“ ist, ohne dass die News-Tabelle wie zuvor gelöscht wird.
Darüber hinaus muss nicht nur die Select-Anweisung verarbeitet werden, einschließlich Einfügen, Aktualisieren, Löschen, Ausführen usw., Sie können sich auch die folgenden Injektionsmethoden ansehen:
In der Struktur in news(title) Werte('+v_title+') einfügen,
Wenn v_title=123';Tabellennachrichten löschen--';
Wenn beim Update-News-Set /> v_title=123'-- oder v_id=1;drop-Table-News--, ist es nicht nur ein Problem mit der Select-Anweisung, sondern es können auch andere Anweisungen Probleme haben. Konzentrieren Sie sich nicht nur auf Select
Kurz gesagt, nach der Überprüfung des Datentyps und der Verarbeitung der einfachen Anführungszeichen kann es meinem Tathagata nicht aus der Handfläche fliegen, selbst wenn es über alle Fähigkeiten verfügt.