{"id":55001070,"date":"2017-02-01T00:00:00","date_gmt":"2020-05-14T13:40:53","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1070"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Sichere_Filterausdruecke","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/","title":{"rendered":"Sichere Filterausdr&uuml;cke"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg09.met.vgwort.de\/na\/9a18bd1271b6443a88076e7b622e90ed\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Filterausdr&uuml;cke k&ouml;nnen schnell gef&auml;hrlich werden, zumindest wenn Sie nicht aufpassen. Daf&uuml;r sorgt die sogenannte SQL-Injection, bei der davon ausgegangen wird, dass der Benutzer einen Ausdruck in die Benutzeroberfl&auml;che eingibt, die dann als Teil eines SQL-Ausdrucks verwendet wird und Schaden anrichten k&ouml;nnte. Dieser Beitrag erl&auml;utert, was SQL-Injection eigentlich ist und wie Sie sich dagegen wappnen k&ouml;nnen.<\/b><\/p>\n<p>Die SQL-Injection ist eine Methode, aus eigentlich harmlosen SQL-Anweisungen sch&auml;dliche SQL-Anweisungen zu machen &#8211; oder damit an Informationen zu gelangen, die der Benutzer normalerweise nicht erhalten sollte. Dabei ist die Voraussetzung immer ein Eingabefeld in einer Webseite oder, in diesem Falle, in einem Access-Formular, in das der Benutzer beispielsweise einen Vergleichswert f&uuml;r einen Vergleichsausdruck eingeben soll &#8211; im einfachsten Fall etwa die ID eines Kunden.<\/p>\n<h2>Beispielformular<\/h2>\n<p>Als Spielwiese f&uuml;r die folgenden Beispiele verwenden wir ein einfaches Access-Formular namens <b>frmKunden <\/b>samt Unterformular <b>sfmKunden<\/b>, wobei das Unterformular die Daten der Tabelle <b>tblKunden <\/b>anzeigt und das Hauptformular ein Eingabefeld f&uuml;r einen Suchbegriff liefert, der zun&auml;chst die Suche nach Werten im Feld <b>KundeID <\/b>erm&ouml;glicht (s. Bild 1).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_01\/pic_1070_001.png\" alt=\"Beispielformular in der Entwurfsansicht\" width=\"424,7115\" height=\"429,1744\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Beispielformular in der Entwurfsansicht<\/span><\/b><\/p>\n<p>F&uuml;r das Textfeld <b>txtKundenID <\/b>legen wir die folgende Ereignisprozedur an:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>txtKundenID_AfterUpdate()\r\n     <span style=\"color:blue;\">Dim <\/span>strSQL<span style=\"color:blue;\"> As String<\/span>\r\n     strSQL = \"SELECT * FROM tblKunden WHERE KundeID = \"  & Me!txtKundenID\r\n     Me!sfmKunden.Form.RecordSource = strSQL\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Diese sorgt daf&uuml;r, dass eine neue SQL-Anweisung zusammengestellt wird, die den Datensatz der Tabelle <b>tblKunden <\/b>mit einem bestimmten Wert im Feld <b>KundeID <\/b>liefert und diesen der Eigenschaft <b>RecordSource <\/b>des Unterformular zuweist. Dies gelingt auch reibungslos, wenn der Benutzer einfach nur einen Zahlenwert eingibt (s. Bild 2).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_01\/pic_1070_002.png\" alt=\"Filtern nach dem Wert 1 im Feld KundeID\" width=\"424,7115\" height=\"141,3289\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Filtern nach dem Wert 1 im Feld KundeID<\/span><\/b><\/p>\n<h2>Ergebnismenge mit UNION erweitern<\/h2>\n<p>Was an unserer Methode soll also gef&auml;hrlich sein &#8211; schlie&szlig;lich kann man doch nur Zahlenwerte eingeben und erh&auml;lt das gew&uuml;nschte Ergebnis Mitnichten: Schon die Kenntnis der Datenstruktur (oder ein wenig experimentelle Arbeit) erlauben es, ein ganz anderes Ergebnis zu erhalten als geplant. Geben Sie beispielsweise einmal den folgenden Ausdruck in das Suchfeld ein:<\/p>\n<pre>1 UNION SELECT * FROM tblKunden WHERE KundeID = 10<\/pre>\n<p>Das Ergebnis ist &uuml;berraschend: Es gibt keinen Fehler, sondern es erscheinen zwei Datens&auml;tze (s. Bild 3)! Allzu verwunderlich ist dies jedoch gar nicht, denn der resultierende Ausdruck in der Variablen <b>strSQL<\/b>, den Sie sich einfach im Debugbereich ausgeben lassen k&ouml;nnen, sieht wie folgt aus:<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_01\/pic_1070_003.png\" alt=\"Erweiterung des Ergebnisses per UNION\" width=\"424,7115\" height=\"169,5871\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Erweiterung des Ergebnisses per UNION<\/span><\/b><\/p>\n<pre>SELECT * FROM tblKunden WHERE KundeID = 1 \r\nUNION \r\nSELECT * FROM tblKunden WHERE KundeID = 11<\/pre>\n<p>Gut, der Schaden ist gering, denn wir greifen so nur auf Datens&auml;tze zu, die wir auch anderweitig h&auml;tten lesen k&ouml;nnen. Aber wenn wir keine Bedingung angeben, liefert der resultierende SQL-Ausdruck uns sogar wieder alle Datens&auml;tze:<\/p>\n<pre>SELECT * FROM tblKunden WHERE KundeID = 1 \r\nUNION \r\nSELECT * FROM tblKunden<\/pre>\n<p>Dies k&ouml;nnte interessant werden, wenn der eigentliche Filterausdruck noch daf&uuml;r sorgt, dass beispielsweise nur die Kunden des aktuell angemeldeten Mitarbeiters angezeigt werden sollen.<\/p>\n<h2>Daten anderer Tabellen auslesen<\/h2>\n<p>Noch spannender wird es, wenn Sie hinter dem <b>UNION <\/b>-Schl&uuml;sselwort nicht auf die gleiche, sondern direkt auf eine andere Tabelle zugreifen, die unter Umst&auml;nden kritische Daten enth&auml;lt. Im Beispiel wollen wir einfach einmal probieren, Daten aus der Tabelle <b>tblArtikel<\/b> zus&auml;tzlich auszugeben, und testen den folgenden Suchausdruck:<\/p>\n<pre>1 UNION SELECT ArtikelID as KundeID, Artikelname as Kundencode FROM tblArtikel<\/pre>\n<p>Dies liefert im ersten Anlauf noch den Fehler aus Bild 4, weil der zweite Teil der <b>UNION<\/b>-Abfrage nicht die gleiche Anzahl Felder wie der erste Teil zur&uuml;ckliefert. Aber was geschieht, wenn wir einfach ein paar fixe Werte entsprechend der Anzahl der Felder des ersten Teils der Abfrage hinzuf&uuml;gen &#8211; und so notfalls durch Experimentieren auf die richtige Anzahl Felder kommen So ergibt sich nach kurzem Test der folgende Ausdruck:<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_01\/pic_1070_004.png\" alt=\"Fehler, wenn nicht alle Seiten der UNION-Abfrage die gleiche Anzahl Felder enthalten\" width=\"424,7115\" height=\"241,078\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Fehler, wenn nicht alle Seiten der UNION-Abfrage die gleiche Anzahl Felder enthalten<\/span><\/b><\/p>\n<pre>1 UNION SELECT ArtikelID as KundeID, Artikelname as Kundencode, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 FROM tblArtikel<\/pre>\n<p>Das Ergebnis ist einigerma&szlig;en erschreckend: Wir gelangen so tats&auml;chlich an die Informationen der Tabelle <b>tblArtikel<\/b>, die eigentlich gar nicht zur Datenherkunft des Unterformulars geh&ouml;rt (s. Bild 5). Und nat&uuml;rlich k&ouml;nnten wir diese Tabelle auch durch eine Tabelle mit wirklich sensiblen Daten wie etwa der Benutzertabelle ersetzen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_01\/pic_1070_005.png\" alt=\"Ermitteln der Daten einer anderen Tabelle\" width=\"424,7115\" height=\"300,045\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Ermitteln der Daten einer anderen Tabelle<\/span><\/b><\/p>\n<p>So lassen sich auch leicht die Tabellen einer Datenbank ausgeben &#8211; und zwar mit diesem Suchbegriff:<\/p>\n<pre>1 UNION SELECT Name, Type , 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 FROM MSysObjects WHERE Type = 1<\/pre>\n<h2>Gef&auml;hrliche Strings<\/h2>\n<p>Gibt es ebenfalls Probleme, wenn man ein Suchfeld f&uuml;r die Eingabe einer Zeichenkette verwendet Ja. Dazu f&uuml;gen wir dem Formular ein Textfeld namens <b>txtFirma <\/b>hinzu, das nach dem Aktualisieren die folgende Ereignisprozedur ausl&ouml;st:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>txtFirma_AfterUpdate()\r\n     <span style=\"color:blue;\">Dim <\/span>strSQL<span style=\"color:blue;\"> As String<\/span>\r\n     strSQL = \"SELECT * FROM tblKunden  WHERE Firma LIKE ''\" & Me!txtFirma & \"''\"\r\n     <span style=\"color:blue;\">Debug.Print<\/span> strSQL\r\n     Me!sfmKunden.Form.RecordSource = strSQL\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><!--30percent--><\/p>\n<p>Geben Sie hier etwa <b>A* <\/b>ein, liefert dies alle Eintr&auml;ge der Tabelle <b>tblKunden<\/b>, deren Feld <b>Firma<\/b> einen Wert enth&auml;lt, der mit <b>A <\/b>beginnt. Wie k&ouml;nnen wir hier beispielsweise mit dem <b>UNION<\/b>-Schl&uuml;sselwort auf die Daten einer zweiten Tabelle wie etwa <b>MSysObjects <\/b>zugreifen Dazu f&uuml;gen wir einfach hinter dem Vergleichswert ein schlie&szlig;endes Hochkomma ein und h&auml;ngen die <b>UNION<\/b>-Klausel hinten an:<\/p>\n<pre>A*'' UNION SELECT Name, Type, 3,4,5,6,7,8,9,10,11,12 FROM MSysObjects<\/pre>\n<p>Dies liefert uns, wie in Bild 6 zu erkennen, wie gew&uuml;nscht alle Tabellennamen der Datenbank. Der resultierende SQL-Ausdruck endet nun zwar mit einem unerw&uuml;nschten Hochkomma, doch das hindert Access nicht an seiner Interpretation:<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_01\/pic_1070_006.png\" alt=\"Ermitteln der Daten einer anderen Tabelle, hier die Tabellennamen\" width=\"424,7115\" height=\"260,5997\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Ermitteln der Daten einer anderen Tabelle, hier die Tabellennamen<\/span><\/b><\/p>\n<pre>SELECT * FROM tblKunden WHERE Firma LIKE ''A*''\r\nUNION\r\nSELECT Name, Type, 3,4,5,6,7,8,9,10,11,12 \r\nFROM MSysObjects''<\/pre>\n<p>W&uuml;rde der SQL-Ausdruck wie folgt zusammengesetzt, also mit einem Sternchen am Ende, w&uuml;rde dies allerdings einen Fehler ausl&ouml;sen:<\/p>\n<pre>strSQL = \"SELECT * FROM tblKunden WHERE Firma LIKE ''\"  & Me!txtFirma & \"*''\"<\/pre>\n<p>Der resultierende SQL-Ausdruck w&uuml;rde n&auml;mlich dann wie folgt aussehen:<\/p>\n<pre>SELECT * FROM tblKunden WHERE Firma LIKE '''' UNION SELECT Name, Type, 3,4,5,6,7,8,9,10,11,12 FROM MSysObjects*''<\/pre>\n<p>Auch dies k&ouml;nnen wir jedoch umgehen, wenn wir folgenden Suchausdruck eingeben:<\/p>\n<pre>'' UNION SELECT Name, Type, 3,4,5,6,7,8,9,10,11,12 FROM MSysObjects WHERE ''<\/pre>\n<p>Das Ergebnis sieht dann so aus:<\/p>\n<pre>SELECT * FROM tblKunden WHERE Firma LIKE '''' \r\nUNION \r\nSELECT Name, Type, 3,4,5,6,7,8,9,10,11,12 \r\nFROM MSysObjects WHERE ''*''<\/pre>\n<h2>Fehler durch unerwartete Eingaben<\/h2>\n<p>Die Einsatz eines einfachen Hochkommas muss gar nicht unbedingt in b&ouml;ser Absicht erfolgen, denn nicht immer dient dies dem Manipulieren einer SQL-Anweisung. Manchmal m&ouml;chte der Benutzer einfach nach einem Namen wie <b>Paul&#8220;s Boutique <\/b>suchen. Das Ergebnis unserer ungesicherten Variante k&ouml;nnen Sie in Bild 7 begutachten &#8211;  Access meldet einen Syntaxfehler. Kein Wunder: Es denkt, das zweite Hochkomma hinter <b>Paul <\/b>im folgenden Ausdruck w&uuml;rde den Vergleichsausdruck der Bedingung beenden. Mit den danach folgenden Zeichen <b>s Boutique <\/b>kann es dann nichts mehr anfangen und meldet einen Fehler:<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_01\/pic_1070_007.png\" alt=\"Fehler durch ein Hochkomma\" width=\"499,6607\" height=\"373,4488\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 7: Fehler durch ein Hochkomma<\/span><\/b><\/p>\n<pre>SELECT * FROM tblKunden \r\nWHERE Firma LIKE ''Paul''s Boutique*''<\/pre>\n<h2>Noch mehr M&ouml;glichkeiten auf dem SQL Server<\/h2>\n<p>Wenn Sie mit Auswahl- oder auch Aktionsabfragen auf die Daten eines SQL Servers zugreifen, die einen beispielsweise wie in diesem Fall per Textfeld eingegebenen Vergleichswert enthalten, kann der Benutzer damit noch viel gr&ouml;&szlig;eren Schaden anrichten. Der SQL Server erlaubt n&auml;mlich im Gegensatz zu Access die Angabe mehrerer durch Semikolon getrennter Anweisungen. So lie&szlig;en sich sogar Anweisungen einbauen, mit denen Daten (oder gar komplette Tabellen) aus der Datenbank gel&ouml;scht oder ge&auml;ndert oder Skripte auf dem Server ausgef&uuml;hrt werden. Wir wollen hier nicht ins Detail gehen, was die M&ouml;glichkeiten angeht, sondern uns lieber darum k&uuml;mmern, wie Sie solche Aktionen verhindern k&ouml;nnen.<\/p>\n<h2>Verhindern von Fehlern und Manipulationen<\/h2>\n<p>Es gibt verschiedene M&ouml;glichkeiten, die Wirkung der oben genannten Eingaben zu verhindern. Der Grundtenor lautet: F&uuml;gen Sie die Eingaben des Benutzers nicht ungepr&uuml;ft in den SQL-Code ein. Die verschiedenen Varianten schauen wir uns nun an.<\/p>\n<h2>Hochkommata escapen<\/h2>\n<p>Wer mit Textfeldern als Vergleichskriterium arbeitet, wei&szlig;, dass es mit der Eingabe von Hochkommata zu Problemen kommen kann. Die L&ouml;sung ist denkbar einfach: Sie m&uuml;ssen die Hochkommata einfach &#8222;verdoppeln&#8220;, indem Sie zu jedem Hochkomma noch ein weiteres hinzuf&uuml;gen. Dies gelingt ganz schnell mit der <b>Replace<\/b>-Funktion.<\/p>\n<p>In unserem Beispiel des Textfeldes <b>txtFirma<\/b> sieht das wie in Listing 1 aus. Wir haben den Inhalt dieses Textfeldes zun&auml;chst in die Variable <b>strVergleichswert <\/b>geschrieben, damit die Vorgehensweise &uuml;bersichtlicher wird. In der folgenden Anweisung haben wir den Inhalt von <b>strVergleichswert <\/b>mit der <b>Replace<\/b>-Anweisung bearbeitet, und zwar so, dass jedes Auftreten eines Hochkommas durch zwei Hochkommata ersetzt wurde. Wenn der Benutzer also <b>Paul&#8220;s Boutique <\/b>eingeben w&uuml;rde, enthielte <b>strVergleichswert <\/b>anschlie&szlig;end den Wert <b>Paul&#8220;&#8220;s Boutique<\/b>. Aber was gewinnen wir nun dadurch Ganz einfach:  Access-SQL interpretiert die doppelten Hochkommata nun wie ein einfaches Zeichen und nicht mehr als Steuerzeichen, wie es das &ouml;ffnende und schlie&szlig;ende Zeichen einer Zeichenkette ist:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>txtFirma_AfterUpdate()\r\n     <span style=\"color:blue;\">Dim <\/span>strSQL<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strVergleichswert<span style=\"color:blue;\"> As String<\/span>\r\n     strVergleichswert = Me!txtFirma\r\n     strVergleichswert = <span style=\"color:blue;\">Replace<\/span>(strVergleichswert, \"''\", \"''''\")\r\n     strSQL = \"SELECT * FROM tblKunden WHERE Firma LIKE ''\" & strVergleichswert & \"*''\"\r\n     <span style=\"color:blue;\">Debug.Print<\/span> strSQL\r\n     Me!sfmKunden.Form.RecordSource = strSQL\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Entsch&auml;rfen von Hochkommata durch &#8222;Verdoppeln&#8220;<\/span><\/b><\/p>\n<pre>SELECT * FROM tblKunden \r\nWHERE Firma LIKE ''Paul''''s Boutique*''<\/pre>\n<p>Die Zeile zum Zusammenstellen der SQL-Anweisung h&auml;tten wir nat&uuml;rlich auch gleich wie folgt umgestalten k&ouml;nnen:<\/p>\n<pre>strSQL = \"SELECT * FROM tblKunden WHERE Firma LIKE \"\"\" & strVergleichswert & \"*\"\"\"<\/pre>\n<p>Hier haben wir nun das &ouml;ffnende und schlie&szlig;ende Hochkomma f&uuml;r das als Vergleichswert angegebene Literal durch doppelte Anf&uuml;hrungszeichen ersetzt. Der resultierende SQL-Ausdruck sieht nun so aus (die <b>Replace<\/b>-Funktion zum Verdoppeln des Hochkommas haben wir hier nicht ben&ouml;tigt):<\/p>\n<pre>SELECT * FROM tblKunden \r\nWHERE Firma LIKE \"Paul''s Boutique*\"<\/pre>\n<p>In diesem Fall k&ouml;nnte uns der Benutzer aber wieder einen Strich durch die Rechnung machen, indem er ein Anf&uuml;hrungszeichen in den Suchbegriff integriert. Dies w&uuml;rde in folgender SQL-Anweisung resultieren, die wiederum den Teil hinter dem zweiten Anf&uuml;hrungszeichen nicht interpretieren k&ouml;nnte:<\/p>\n<pre>SELECT * FROM tblKunden \r\nWHERE Firma LIKE \"Paul\"s Boutique*\"<\/pre>\n<p>Wenn Sie also mit doppelten Anf&uuml;hrungszeichen zur Markierung des Vergleichsausdrucks arbeiten, sollten Sie die Anf&uuml;hrungszeichen im Suchbegriff verdoppeln &#8211; also wie zuvor die Hochkommata. Dies sieht mit <b>Replace <\/b>dann so aus:<\/p>\n<pre>strVergleichswert = <span style=\"color:blue;\">Replace<\/span>(strVergleichswert, \"\"\"\", \"\"\"\"\"\")<\/pre>\n<p>Dies w&auml;re dann der SQL-Ausdruck mit unserem Beispielvergleichswert:<\/p>\n<pre>SELECT * FROM tblKunden \r\nWHERE Firma LIKE \"Paul\"\"s Boutique*\"<\/pre>\n<h2>UNION-Abfragen entsch&auml;rfen<\/h2>\n<p>Wenn Sie, wie weiter oben gezeigt, einem Textvergleichswert per UNION eine weitere Abfrage hinzuf&uuml;gen wollen, um Werte anderer Tabellen zu ermitteln, reicht das Verdoppeln der Hochkommata als Vorbeugung bereits aus. Der Wert im Suchfeld sieht wie folgt aus:<\/p>\n<pre>A*'' UNION SELECT Name, Type, 3,4,5,6,7,8,9,10,11,12 FROM MSysObjects<\/pre>\n<p>Dann erhalten wir mit Verdoppeln des Hochkommas die folgende SQL-Abfrage:<\/p>\n<pre>SELECT * FROM tblKunden WHERE Firma LIKE ''A*'''' \r\nUNION \r\nSELECT Name, Type, 3,4,5,6,7,8,9,10,11,12 \r\nFROM MSysObjects''<\/pre>\n<p>Nun endet der Vergleichswert mit dem Feld <b>Firma <\/b>nicht hinter <b>A*<\/b>, sondern das Verdoppeln des Hochkommas sorgt daf&uuml;r, dass dieses als Teil des Vergleichswertes interpretiert wird. Das Ergebnis der Abfrage ist nun leer, es sei denn, das Feld <b>Firma <\/b>enthielte den Wert <b>A*&#8220;&#8220; UNION SELECT Name, Type, 3,4,5,6,7,8,9,10,11,12 FROM MSysObjects<\/b>, was nicht der Fall sein d&uuml;rfte.<\/p>\n<h2>Zahlenwerte sichern<\/h2>\n<p>Weiter oben hatten wir ja auch die M&ouml;glichkeit aufgezeigt, in Access-SQL-Abfragen einfach mit <b>UNION<\/b> weitere Abfragen an eine bestehende Abfrage anzuh&auml;ngen, die einen Zahlenwert als Vergleichswert nutzt. Hier ist das Verdoppeln von Hochkommata oder Anf&uuml;hrungszeichen im Vergleichsausdruck wie etwa im obigen Beispiel nutzlos, denn der Vergleichsausdruck enth&auml;lt ja keine solchen. Hier k&ouml;nnten Sie bereits bei der Eingabe pr&uuml;fen, ob der angegebene Wert ein Zahlenwert ist. Falls nicht, geben Sie einfach eine entsprechende Meldung aus. Dies realisieren Sie am einfachsten auf folgende Art und Weise:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>txtKundenID_AfterUpdate()\r\n     <span style=\"color:blue;\">Dim <\/span>strSQL<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">If <\/span>IsNumeric(Me!txtKundenID)<span style=\"color:blue;\"> Then<\/span>\r\n         strSQL = \"SELECT * FROM tblKunden  WHERE KundeID = \" & Me!txtKundenID\r\n         <span style=\"color:blue;\">Debug.Print<\/span> strSQL\r\n         Me!sfmKunden.Form.RecordSource = strSQL\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Bitte geben Sie einen Zahlenwert ein.\"\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Mit Parametern arbeiten<\/h2>\n<p>Sollten Sie auf Nummer sicher gehen wollen, k&ouml;nnen Sie mit Parameterabfragen arbeiten. Eine solche Abfrage m&uuml;ssen Sie entsprechend vorbereiten, was aber auch den sch&ouml;nen Nebeneffekt von Performancegewinnen mit sich bringen kann.<\/p>\n<p>Die Abfrage f&uuml;r das Unterformular unseres Beispiels s&auml;he etwa wie in Bild 8 aus. Sie soll alle Felder der Tabelle <b>tblKunden <\/b>zur&uuml;ckliefern, aber nur f&uuml;r solche Datens&auml;tze, deren Feld <b>Firma <\/b>mit dem Wert des mit <b>[prmFirma] <\/b>gekennzeichneten Parameters &uuml;bereinstimmt.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_01\/pic_1070_008.png\" alt=\"Abfrage mit Parameter\" width=\"424,7115\" height=\"332,6281\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 8: Abfrage mit Parameter<\/span><\/b><\/p>\n<p>Die Filterfunktion, welche diese Abfrage (und ein weiteres Textfeld namens <b>txtFirmaParameter<\/b>, siehe Beispieldatenbank) als Basis nutzt, sieht wie folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>txtFirmaParameter_AfterUpdate()\r\n     <span style=\"color:blue;\">Dim <\/span>qdf<span style=\"color:blue;\"> As <\/span>DAO.QueryDef\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     <span style=\"color:blue;\">Set<\/span> qdf = db.QueryDefs(\"qryKundenNachFirma\")\r\n     qdf.Parameters(\"prmFirma\") = Me!txtFirmaParameter\r\n     <span style=\"color:blue;\">Set<\/span> rst = qdf.OpenRecordset\r\n     <span style=\"color:blue;\">Set<\/span> Me!sfmKunden.Form.Recordset = rst\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Sie setzt den Vergleichswert einfach als Wert des betreffenden Elements der <b>Parameters<\/b>-Auflistung des entsprechenden <b>QueryDef<\/b>-Objekts ein. Dieses wird gar nicht interpretiert, sondern direkt als Vergleichswert genutzt. Der Benutzer kann hier also beliebige Ausdr&uuml;cke eingeben, diese werden auf keinen Fall ausgef&uuml;hrt. Diese Variante setzt nat&uuml;rlich voraus, dass das Ergebnis als Recordset zugewiesen kann.<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>SichereFilterausdruecke.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/83C8F2E9-F777-4680-82E3-4B21671D09E7\/aiu_1070.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Filterausdr&uuml;cke k&ouml;nnen schnell gef&auml;hrlich werden, zumindest wenn Sie nicht aufpassen. Daf&uuml;r sorgt die so genannte SQL-Injection, bei der davon ausgegangen wird, dass der Benutzer einen Ausdruck in die Benutzeroberfl&auml;che eingibt, die dann als Teil eines SQL-Ausdrucks verwendet wird und Schaden anrichten k&ouml;nnte. Dieser Beitrag erl&auml;utert, was SQL-Injection eigentlich ist und wie Sie sich dagegen wappnen k&ouml;nnen.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[66012017,662017,44000029],"tags":[],"class_list":["post-55001070","post","type-post","status-publish","format-standard","hentry","category-66012017","category-662017","category-Abfragetechnik_und_SQL"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Sichere Filterausdr&uuml;cke - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Sichere Filterausdr&uuml;cke\" \/>\n<meta property=\"og:description\" content=\"Filterausdr&uuml;cke k&ouml;nnen schnell gef&auml;hrlich werden, zumindest wenn Sie nicht aufpassen. Daf&uuml;r sorgt die so genannte SQL-Injection, bei der davon ausgegangen wird, dass der Benutzer einen Ausdruck in die Benutzeroberfl&auml;che eingibt, die dann als Teil eines SQL-Ausdrucks verwendet wird und Schaden anrichten k&ouml;nnte. Dieser Beitrag erl&auml;utert, was SQL-Injection eigentlich ist und wie Sie sich dagegen wappnen k&ouml;nnen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-14T13:40:53+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg09.met.vgwort.de\/na\/9a18bd1271b6443a88076e7b622e90ed\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"11\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Sichere_Filterausdruecke\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Sichere_Filterausdruecke\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Sichere Filterausdr&uuml;cke\",\"datePublished\":\"2020-05-14T13:40:53+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Sichere_Filterausdruecke\\\/\"},\"wordCount\":1904,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Sichere_Filterausdruecke\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/9a18bd1271b6443a88076e7b622e90ed\",\"articleSection\":[\"1\\\/2017\",\"2017\",\"Abfragetechnik und SQL\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Sichere_Filterausdruecke\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Sichere_Filterausdruecke\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Sichere_Filterausdruecke\\\/\",\"name\":\"Sichere Filterausdr&uuml;cke - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Sichere_Filterausdruecke\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Sichere_Filterausdruecke\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/9a18bd1271b6443a88076e7b622e90ed\",\"datePublished\":\"2020-05-14T13:40:53+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Sichere_Filterausdruecke\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Sichere_Filterausdruecke\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Sichere_Filterausdruecke\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/9a18bd1271b6443a88076e7b622e90ed\",\"contentUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/9a18bd1271b6443a88076e7b622e90ed\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Sichere_Filterausdruecke\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Sichere Filterausdr&uuml;cke\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Sichere Filterausdr&uuml;cke - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/","og_locale":"de_DE","og_type":"article","og_title":"Sichere Filterausdr&uuml;cke","og_description":"Filterausdr&uuml;cke k&ouml;nnen schnell gef&auml;hrlich werden, zumindest wenn Sie nicht aufpassen. Daf&uuml;r sorgt die so genannte SQL-Injection, bei der davon ausgegangen wird, dass der Benutzer einen Ausdruck in die Benutzeroberfl&auml;che eingibt, die dann als Teil eines SQL-Ausdrucks verwendet wird und Schaden anrichten k&ouml;nnte. Dieser Beitrag erl&auml;utert, was SQL-Injection eigentlich ist und wie Sie sich dagegen wappnen k&ouml;nnen.","og_url":"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-14T13:40:53+00:00","og_image":[{"url":"http:\/\/vg09.met.vgwort.de\/na\/9a18bd1271b6443a88076e7b622e90ed","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"11\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Sichere Filterausdr&uuml;cke","datePublished":"2020-05-14T13:40:53+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/"},"wordCount":1904,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/#primaryimage"},"thumbnailUrl":"http:\/\/vg09.met.vgwort.de\/na\/9a18bd1271b6443a88076e7b622e90ed","articleSection":["1\/2017","2017","Abfragetechnik und SQL"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/","url":"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/","name":"Sichere Filterausdr&uuml;cke - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/#primaryimage"},"thumbnailUrl":"http:\/\/vg09.met.vgwort.de\/na\/9a18bd1271b6443a88076e7b622e90ed","datePublished":"2020-05-14T13:40:53+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/#primaryimage","url":"http:\/\/vg09.met.vgwort.de\/na\/9a18bd1271b6443a88076e7b622e90ed","contentUrl":"http:\/\/vg09.met.vgwort.de\/na\/9a18bd1271b6443a88076e7b622e90ed"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Sichere_Filterausdruecke\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Sichere Filterausdr&uuml;cke"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001070","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55001070"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001070\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001070"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001070"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001070"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}