# String zwischen zwei bestimmten Zeichen ausgeben



## schleckerbeck (23. Oktober 2007)

Hallo,

ich möchte aus einer SQL Abfrage die ungefähr so lautet

```
Select id, name, titel from artikel where id='1' and category='test'
```
alles zwischen den beiden ' ' (oder alternativ auch " ") herausfilter, um diese Werte zu überprüfen.
Hat jemand ne Idee, wie man das lösen könnte? Kenn mich mit RegExp nicht so richtig aus, und auch sonst hab ich noch keine Funktionen gefunden, die mir weiterhelfen könnten.

Danke,
sc.


----------



## PatrickStr (23. Oktober 2007)

Hallo,
explode("* ' *", $var);


Thats it


----------



## schleckerbeck (24. Oktober 2007)

Danke für die Antwort, auf explode bin ich auch schon gestoßen.
Aber was ist, wenn in den Werten, also id='1', auch Anführungszeichen, oder Hochkommata sind? Wie z.B. id='1';DROP DATABASE test'.
Will damit SQL Injections verhindern. Ich bräuchte einfach den Wert, der der Spalte id übergeben wird, also nur 1';DROP DATABASE test
Das ganze sollte auch genauso mit Anführungszeichen funktionieren.

Hat wer ne Idee?

Danke,
sc.


----------



## Michael Engel (24. Oktober 2007)

Es ist sinniger Funktionen wie "mysql_real_escape()" auf die Variablen anzuwenden mit denen du die Query zusammenbaust.


----------



## schleckerbeck (24. Oktober 2007)

Die Funktion mysql_real_escape_string will ich auch anwenden. Bloß wird der SQL Funktion die Abfrage "am Stück" übermittelt, also ungefähr so:
checksql("Select * from test where id='".$_GET['test']."');
und in der checksql funktion will ich dann den Teil rausfiltern, der in der GET Variable (oder Post o.ä.) steht, und per mysql_real_escape_string maskieren.
Weil wenn ich mysql_real_escape_string auf die komplette Abfrage anwenden, maskiert er mir ja auch die beiden Hochkomma bei id=' ', was er nicht tun soll.

Also muss ich den String doch irgendwie zerlegen, sodass ich an die Werte von GET in der Abfrage ran komme.
Es sollte auch funktionieren, dass z.B. bei Insert oder Update, wo mehrere Werte übergeben werden, auch alle anderen überprüft werden (also name='$_GET[name]', titel='$_GET[titel]' usw.)

Danke,
sc.


----------



## PatrickStr (24. Oktober 2007)

Hallo,

wenn Du so vorgehen möchtest musst Du das Ganze mit Javascript vor dem Submitten machen . So zum Beispiel:

```
if(isFinite(document.getElementById(Element).value))
											{
												 chknum=document.getElementById(Element).value;
												var find= /\W/;
											 	 if(chknum.search(find)==-1){mybool=true;}
											  	else {
											  	filled=window.prompt('This field "'+Element+'" is an integer one !\r\nPlease fill in a number without fragmental parts of number',document.getElementById(Element).value);
													document.getElementById(Element).value=filled;
													}
											 
											 }else {
											  	filled=window.prompt('This field "'+Element+'" is an integer one !\r\nPlease fill in a number without fragmental parts of number',document.getElementById(Element).value);
													document.getElementById(Element).value=filled;
													}
```

Viele Grüße


----------



## Michael Engel (24. Oktober 2007)

Wie währe es damit:


```
$sql = "Select * from test where id='".mysql_real_escape_string($_GET['test'])."';"
```

Aber generell könntest du es so in etwa machen:


```
function checksql($str){

        return preg_replace_callback("%'(.*)'%Us",    create_function(
      '$treffer',
      'return mysql_real_escape_string($treffer[1]);'
    ),$str);

}
```


----------



## schleckerbeck (24. Oktober 2007)

Danke,
also die erste Variante kommt leider nicht in Frage. Wär natürlich die einfachste.

Die zweite Variante find ich ganz interessant. Hätte bloß noch ne Bitte, ob du mir die ganze Funktion ein wenig erklären könntest, da ich mit RegExp nicht so viel am Hut hab.

Danke,
sc.


----------



## PatrickStr (24. Oktober 2007)

Hier ein Link der Hilft
http://www.regenechsen.de/phpwcms/index.php?regex_allg_beispiel
Alles recht gut erklärt!


----------



## schleckerbeck (24. Oktober 2007)

Danke für den Link, aber so richtig helfen tut er mir nicht.
Naja, werd mich dann mal in die RegExp reinlesen. Vielleicht kapier ich's dann.
Außer natürlich jemand erklärt mir den Ausdruck. 

Danke,
sc.


----------



## Michael Engel (24. Oktober 2007)

Also Die Funktion generell enhält 2 wichtige teile.. als erstes eine RegEx und das 2. ist eine funktion die auf die gefunden Elemente angewand wird.


```
"%'(.*)'%Us"
```

% sind die Begrenzer der Expression
'    sind die Anfürhungszeichen nach denen er sucht.
.*  Punkt ist ein beliebiges Zeichen, Stern beliebig oft... also alles was zwischen zwei ' steht.
die () braucht man nur für das callback das eben dieser String zurückgeliefert wird

Im Endeffekt macht es "Wende die Funktion auf alles an was zwischen 2 Anführungszeichen steht"

Allerdings kommt mir gerade das du das warscheinlich vergessen kannst, da man nicht sicher sagen kann ob das ' nun das Ende deiner zuweisung ist, oder der Anfang der SQL-Injektion. Die SQL Abfrage hinterher zu prüfen ist meiner Meinung nach wie vor ein schlechter weg. mit Type-Casting und die Werte ggf. zu escapen ist auf jeden Fall der sichere Weg.

Edit: Darf man fragen waum das nicht in Frage kommt?


----------



## schleckerbeck (25. Oktober 2007)

Es kommt deshalb nicht in Frage, weil ich eben schon einige Skripte habe, die diese Klasse verwenden, und da wird nur die komplette SQL Abfrage übergeben.
Aber das ganze vorher schon zu Filtern wär sicher am besten.

Da muss ich mir nochmal was überlegen...

Danke,
sc.


----------



## schleckerbeck (25. Oktober 2007)

So,
nun schreib ich den Beitrag schon zum zweiten mal (schei** Firefox).
Also, hab mich jetzt doch relative schnell durchgerungen die ganzen Variablen die SQL übergeben werden, schon im Vorfeld zu überprüfen.
Dazu hab ich mir eine Funktion geschrieben:

```
function sqlGET($arg) {
        return mysql_real_escape_string($_GET[$arg]);
    }
```
Doch wenn ich jetzt mal eine Injection simuliere,

```
index.php?test=';Select * from test
```
und mir die Ausgabe der Funktion anschaue, macht er bei mir drei \\\ hin, statt nur eins.

```
\\\';Select * from test
```
An was könnte das liegen? Oder ist das Sinn der Sache?

Desweiteren hab ich mir die gleiche Funktion nochmal für POST umgebastelt, da ja auch User auf meiner Seite per Post etwa Beiträge des GB in die Datenbank schreiben. Die Daten kommen dabei aus einem WYSIWYG Editor. Wenn ich das ganze jetzt aber per mysql_real_escape_string maskiere, und der Benutzer in seinem Beitrag auch desöfteren ein ' oder " verwendet (oder gar SQL Abfragen veröffentlichen will), dann werden doch auch die ' oder " mit maskiert, was wieder zu unschönen Darstellungen im Browser führt. (Bsp.: Hallo das ist ein Blindtext der auch \"blindtext\" heißt)
Jetzt meine Frage: Wie könnte man das ganze umgehen?

Danke,
sc.


----------



## Suursjoghurtli (25. Oktober 2007)

Probier mal den folgenden Code um die Variable, welche den GB Eitnrag ausgibt:


```
$gbeintrag = stripslashes(htmlspecialchars($variable));
```
 
Damit werden die Slashes entfernt und die HTML Tags, falls die jemand eingeben will nicht umgewandelt sondern nur angezeigt.
Ist nur so eine Vermutung, also keine Gewähr auf Sicherheit und Funktionstüchtigkeit!  

edit: Achso hab grad gemerkt, dass du ja über einen editor die Einträge formatieren lässt, ich nehme also an, dass du da auch HTML Code mitgeben wirst, dann ist meine Antwort also für die Katz.


----------



## Michael Engel (25. Oktober 2007)

Warscheinlich ist auf deinem server magic-quotes aktiviert. Und er Maskiert automatisch alles was per _GET oder _POST reinkommt.


----------



## schleckerbeck (25. Oktober 2007)

Ah ja, magic quotes ist aktiviert. Funktioniert!

Ja, dort auch HTML Werte übermittelt. Noch ne Idee?

Danke,
sc.


----------

