• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

htaccess - gesamten Query in URL umschreiben

Ich glaube das einfachste ist, wenn du einfach alles an ein proxy-Skript umleitest, das dann das ganze Zeugs in $_GET reinschreibt und dann dan eigentliche Skript aufruft.
Aber dann habe ich es ja so, dass in der URL der Query wieder ganz normal angezeigt wird...
 
Du hast mich falsch verstanden.

Im Browser steht das, was du haben willst. Über mod_rewrite leitest du aber alle Anfragen an dein Proxyskript. Das zerlegt den Pfad in seine Bestandteile, baut das $_GET auf und ruft dann das eigentliche Skript über include() oder require() auf.
 
Du hast mich falsch verstanden.

Im Browser steht das, was du haben willst. Über mod_rewrite leitest du aber alle Anfragen an dein Proxyskript. Das zerlegt den Pfad in seine Bestandteile, baut das $_GET auf und ruft dann das eigentliche Skript über include() oder require() auf.
Ahhh, okay...
 
Ausgehend vom Beispiel:

Code:
"http://example.com/path/index.php?get=parameter&second=value"
"http://example.com/path/index.php/get/parameter/second/value"

Code:
RewriteCond %{QUERY_STRING} (.+)=(.+)
Würde ich nicht unbedingt so machen, weil dann in %1 get enthalten sein dürfte und in %2 parameter&second=value, somit der gesamte Rest. Da hätte ich dann schon wieder Bedenken, dass jemand versuchen könnte in %2 parameter&second=value&teste=schwachstellen anzuhängen.

Wenn die Parameter feststehen, so halte ich es für sicherer ^get=(.+)&second=(.+)$ zu verwenden. Wenn auch noch die Werte nur Ziffern oder Buchstaben oder bestimmte Zeichen enthalten, dann auch statt(.+) lieber

Code:
^get=([a-z_-]+)&second=([0-9]+)$
und Du bist Dir sicherer, was in "/index.php/get/%1/second/%2" enthalten. Stattdessen dann lieber ein paar Konditionen und Regeln mehr notieren.
 
Danke, Melewo, aber eigentlich ging es darum, dass eben nicht mit ein "paar Regeln mehr" zu bewerkstelligen, sondern universal bei allem...
Würde ich nicht unbedingt so machen, weil dann in %1 get enthalten sein dürfte und in %2 parameter&second=value, somit der gesamte Rest. Da hätte ich dann schon wieder Bedenken, dass jemand versuchen könnte in %2 parameter&second=value&teste=schwachstellen anzuhängen.
Ich versteh das nicht so ganz. Was meinst du mit "Schwachstellen"?
 
Normalerweise werden Parameter-Werte ja mit einer preg_ Funktion geprüft. Du kannst die aber schon in der htaccess filtern, so dass die gar nicht mehr ein Script erreichen, zumindest aber nur die Parameter annehmen, die auch bekannt sind und alles andere gleich mit Forbidden abweisen.

Ich kann Dir gewiss nicht sagen, wie Hacker im Einzelnen vorgehen, soviel weiß ich aber, dass da die kleinsten Lücken ausgenutzt werden. Würde mal grob schätzen, dass der größte Teil dabei nicht über eine gut geschützte Login-Seite eindringt, sondern eben auch über unzureichend gefilterte GET und POST Parameter-Werte.

Was CMS oder ein Proxy-Script anbelangt, nun gut, kenne eigentlich nur ein System von den großen und dann mein kleines, doch es ist ja nicht so, dass da dann alles mit ein paar Regeln geprüft würde, da übernimmt ja dann das Script die Prüfung und jeder einzelne Parameter wird dann mit den Parametern in der Datenbank abgeglichen, sowie der Name der Seite usw..
 
Stimmt: mehrere Parameter werden da nicht richtig behandelt. Aber in %1 steht dann "get=parameter&second" drin... ein Sicherheitsloch würde ich darin nicht sehen. Man muss ja immer im Skript prüfen.

Um mehrere Parameter richtig handzuhaben könnte man das so machen:
Code:
RewriteCond %{QUERY_STRING} (.*?)=([^&]*)(?:&?(.*))
RewriteRule ^(.+?)\.(php|html?|aspx)(.*?)/?$ $1.$2$3/%1/%2/?%3 [L,NC,R=301]
 
Dito - ich kann ja immer in GET reinschreiben, was ich will.
Ja, vor allem codierte Codes und sich dann darauf verlassen, dass PHP die schon erkennen wird, weil das eigene Script bestens dagegen abgesichert ist. Doch lassen wir das, es gibt ja letztendlich auch keine Hacker, die über GET oder POST ihren Schadcode einschleusen würden. Da ich neu in diesem Forum bin, ziehe ich mich zurück.
 
Ja, vor allem codierte Codes und sich dann darauf verlassen, dass PHP die schon erkennen wird, weil das eigene Script bestens dagegen abgesichert ist. Doch lassen wir das, es gibt ja letztendlich auch keine Hacker, die über GET oder POST ihren Schadcode einschleusen würden.
Habe ich das behauptet? Und natürlich kann ich da XSS einschleußen - aber das kann ich auch, ohne dass man die Parameter wie von dir angesprochen aufteilt. Das ist völlig wurscht. Wie kkapsner bereits sagte: da besteht kein Unterschied, man muss sein Skript so und so absichern.

Da ich neu in diesem Forum bin, ziehe ich mich zurück.
Warum das? Nur weil ich nicht deiner Meinung bin? Macht doch nix, deswegen gibt es doch ein Forum, dass jeder aus seiner Sicht über etwas diskutieren kann...
 
Warum das?

Weil es mir so vorkommt, als würdest Du auf Kontra gehen, nur um des Kontra willens. So auch bei dieser Antwort:

Habe ich das behauptet? Und natürlich kann ich da XSS einschleußen - aber das kann ich auch, ohne dass man die Parameter wie von dir angesprochen aufteilt. Das ist völlig wurscht.
Eben hierbei kannst Du nichts mehr über einen Seitenaufruf einschleusen, weil kein Platz mehr vorhanden ist für irgendwelche andere Zeichen, außer Ziffern, Buchstaben, Bindestrich und Unterstrich und der ^Anfang und das Ende$ klar begrenzt werden:

Code:
^get=([a-z_-]+)&second=([0-9]+)$
Und da kann man noch einen drauf legen, so mache ich es zumindest bei meinem eigenen Script. Zugegeben, die Anzahl an Kategorien ist überschaubar, so dass ebenfalls die Anzahl an Regeln überschaubar ist und jede Kategorie Regeln nach diesem Muster erhält. Verzeichnis ist das Verzeichnis, in dem das Script liegt.

Aufrufen mit:
"www.example.com/kategorie/name-der-seite-344.html"
Verarbeiten mit:
"www.example.com/verzeichnis/beitrag.php?ident=344&name=name-der-seite"

In der htaccess:
Code:
RewriteCond %{QUERY_STRING} !^.*schleife=no$
RewriteCond %{QUERY_STRING} ^ident=([0-9]+)&name=([a-z-]+)$
RewriteRule ^verzeichnis/beitrag\.php             /kategorie/%2-%1.html? [L,R=301]
RewriteRule ^kategorie/([a-z-]+)-([0-9]+)\.html$  /verzeichnis/beitrag.php?ident=$2&name=$1&schleife=no [QSA,L]

Im Einzelnen:

Falls jemand versucht eine Seite so aufzufen

"www.example.com/verzeichnis/beitrag.php?ident=344&name=name-der-seite"

erfolgt eine Weiterleitung auf

"www.example.com/kategorie/name-der-seite-344.html"

mit

Code:
RewriteRule ^verzeichnis/beitrag\.php             /kategorie/%2-%1.html? [L,R=301]

und damit daraus keine Endlosschleife wird, so wird bei der eigentlichen Auslösung in

Code:
RewriteRule ^kategorie/([a-z-]+)-([0-9]+)\.html$  /verzeichnis/beitrag.php?ident=$2&name=$1&schleife=no [QSA,L]

zusätlich schleife=no angehängt und in

Code:
RewriteCond %{QUERY_STRING} !^.*schleife=no$

gesperrt. Im Script erfolgt dann neben einer allgemeinen Filterung mit preg_replace eine Prüfung, ob die Kategorie und der Seitenname in der Datenbank gespeichert sind und mit der Id übereinstimmen.

Und wenn Du Dir diese Arbeit in der htaccess ersparen möchtest, dann hast Du die in PHP mehr, wie hier ein Beispiel aus WP, was auch von mir ist:

PHP:
add_action("init", "oldies_evergreens_rewrite_regel");

function oldies_evergreens_rewrite_regel() {

    global $wp_rewrite;
    add_rewrite_rule(

        '^oldies/([a-zA-Z0-9]+?)/([a-zA-Z0-9-]+?)/?$',
        'index.php?name=$matches[1]-aus-den-$matches[2]n',
        'top'
        );
}
 
Zuletzt bearbeitet:
Eben hierbei kannst Du nichts mehr über einen Seitenaufruf einschleusen, weil kein Platz mehr vorhanden ist für irgendwelche andere Zeichen, außer Ziffern, Buchstaben, Bindestrich und Unterstrich und der ^Anfang und das Ende$ klar begrenzt werden:
Ah, jetzt versteh ich, was du sagen willst. Aber das kann ich ja auch bei dem String aus der am Anfang genannten Variante anwenden und so eine XSS-Injection verhindern...

Warum das?
Weil es mir so vorkommt, als würdest Du auf Kontra gehen, nur um des Kontra willens.
Kann ich nicht nachvollziehen, warum. War auch nicht meine Absicht. :)
 
Ah, jetzt versteh ich, was du sagen willst. Aber das kann ich ja auch bei dem String aus der am Anfang genannten Variante anwenden und so eine XSS-Injection verhindern...
Ja, klar kannst Du das, was mir an meiner Variante gefällt ist, dass meine Parameter gar keiner erst zu sehen bekommt, weil entweder gleich eine Weiterleitung auf die gewünschte Seite erfolgt oder einer Weiterleitung auf eine Fehlerseite. Und wer die Namen der Parameter nicht kennt, der weiß auch schlechter wo er ansetzen soll. Womit ich nicht sagen möchte, dass es nicht möglich wäre.

Kann ich nicht nachvollziehen, warum. War auch nicht meine Absicht. :)
Ich sehe schon, wir werden noch Freunde. Von jQuery habe ich immer noch keine richtige Ahnung, zumindest von außen, von innen habe ich schon etwas in der kommentierten Version gesehen und versucht nachzuvollziehen.
Nur von diesen htaccess-Geschichten, da habe ich mal in einem anderen Forum längere Zeit alle Fragen beantwortet, bis ich es dann selbst konnte. Soll nicht heißen, dass ich den ersten falsche Antworten gegeben hätte, nur habe ich dann die Beispiele von Fragestellern immer durchprobiert, bis es funktionierte und dabei gelernt. Einer war noch da, der hatte auch sehr viel Erfahrung.
 
@Melewo: Wenn aber jemand "www.example.com/verzeichnis/beitrag.php?ident=344&name=alert('XSS')" abfragt, feuert die Umleitung nicht und die Parameter werden direkt an dein Skript weitergegeben. Außer du hast noch irgendeine andere Regel, die dir alles andere abfängt...

Trotzdem bin ich der Meinung, dass man auf der Skriptseite, die die Parameter weiterverarbeitet, viel einfacher und sicherer Eingaben prüfen kann. Dann hat man auch nicht das Problem, dass man die komplette htaccess umschreiben muss, wenn man einen weiteren Parameter hinzufügen will oder den Wertebereich eines Parameters erweitern muss - ist einfach viel wartungsfreundlicher.

Und so wie ich Julian verstanden habe, will er mit der RewriteRule auch nur Altlasten beseitigen.

PS: warum holst du dir die globale Variable $wp_rewrite in den Scope der Funktion, wenn du sie gar nicht benutzt?
PPS: das "schleife=no" ist komplett überflüssig, da mod_rewrite nicht rekursiv arbeitet. Und wenn man es bräuchte, wäre die explizite RewriteRule dafür unnötig, da die zweite RewriteRule das nicht durchlassen würde.
PPPS: wenn eine Weiterleitung erfolgt, heißt das noch lange nicht, dass niemand die Parameter zu Gesicht bekommt...
 
Trotzdem bin ich der Meinung, dass man auf der Skriptseite, die die Parameter weiterverarbeitet, viel einfacher und sicherer Eingaben prüfen kann. Dann hat man auch nicht das Problem, dass man die komplette htaccess umschreiben muss, wenn man einen weiteren Parameter hinzufügen will oder den Wertebereich eines Parameters erweitern muss - ist einfach viel wartungsfreundlicher.

Und so wie ich Julian verstanden habe, will er mit der RewriteRule auch nur Altlasten beseitigen.
Richtig, auf genau die zwei Punkte wollte ich hinaus. Ansonsten bin ich wie du der Meinung, dass man auf Skriptseite die Eingaben sowieso prüfen sollte.
 
Wenn aber jemand "www.example.com/verzeichnis/beitrag.php?ident=344&name=alert('XSS')" abfragt, feuert die Umleitung nicht und die Parameter werden direkt an dein Skript weitergegeben.
Ist ja nicht so, dass ich alles der htaccess überlassen würde. Würde PHP im ersten Schritt schon nicht ausliefern, sondern in $var_name= "alertXSS" verwandeln.

PHP:
if (isset($_GET["ident"]) and $_GET["ident"] > 0 and isset($_GET["name"]) and !empty($_GET["name"])) {

    $var_ident = $_GET["ident"];
    $var_ident = preg_replace("/[^0-9]/", "", $var_ident);

    $var_name = $_GET["name"];
    $var_name = preg_replace("/[^a-z-]/", "", $var_name);
    }
    else {header("HTTP/1.1 301 Moved Permanently");
          header("Location: http://www.example.com/einstieg/web.php");
          exit;
}
Im zweiten Schritt erst recht, da ja im SQL-Query gefragt wird, ob der Name der Seite und die Id vorhanden sind und übereinstimmen. Und da dieser Seitenname "alert('XSS')" und dieser "alertXSS" in der DB nicht vorhanden sind, würde PHP nichts ausliefern.

PS: warum holst du dir die globale Variable $wp_rewrite in den Scope der Funktion, wenn du sie gar nicht benutzt?
Begründete Frage, komme aber gerade selbst ins Schleudern und zu wenig kopiert. Um beim Testen mit

PHP:
$wp_rewrite->flush_rules();
ein internes Cachen zu verhindern und mit

PHP:
print_r($wp_rewrite->rules);
zu arbeiten. Nur die Beispiele und die Beschreibung habe ich immer noch nicht fertig, weil ich da den einen oder anderen Punkt noch nicht richtig verstanden hatte. Aber im Zusammenhang wird daraus dann eher ein Schuh erst werden:

Die WP Rewrite API: Eine kleine Einführung | Coder-Welten.com

PPS: das "schleife=no" ist komplett überflüssig, da mod_rewrite nicht rekursiv arbeitet.
Einfacheres Beispiel,

"www.example.com/themen-34.html"

soll im Hintergrund auslösen, nicht weiterleiten

"www.example.com/themen.php?thema=$1"

mit

Code:
RewriteRule ^themen-([0-9]+)\.html$ /themen.php?thema=$1 [L]

Aufrufen lässt sich aber nun

"www.example.com/themen-34.html"
und
"www.example.com/themen.php?thema=34"

Damit sich diese

"www.example.com/themen.php?thema=34"

nicht aufrufen lässt, erfolgt bei Eingabe dieser URL eine Weiterleitung auf

"www.example.com/themen-34.html"

doch diese Weiterleitung erfolgt nur wenn im QueryString kein anderer oder zusätzlicher Parameter enthalten ist:

Code:
RewriteCond %{QUERY_STRING} ^thema=([0-9]+)$
RewriteRule ^themen\.php$ /themen-%1.html? [L,R=301]

Was herauskommt wäre eine Endlosschleife, diese sorgt erst dafür,

Code:
RewriteRule ^themen-([0-9]+)\.html$ /themen.php?thema=$1&nur=so [QSA,L]

das sich die einmal ausgelöste

"www.example.com/themen.php?thema=34"

nicht noch einmal weiterleiten lässt, da mit nur=so die Regel mit ^thema=([0-9]+)$ nicht mehr passt.

Alles zusammen sieht dann so aus:

Code:
RewriteCond %{QUERY_STRING} ^thema=([0-9]+)$
RewriteRule ^themen\.php$ /themen-%1.html? [L,R=301]
RewriteRule ^themen-([0-9]+)\.html$ /themen.php?thema=$1&nur=so [QSA,L]

Eine erste Bedingung mit

Code:
RewriteCond %{QUERY_STRING} !^.*nur=so$
wäre nicht unbedingt mehr erforderlich, schadet jedoch auch nicht.

Gelernt hatte ich das von dieser Seite aus den Beispielen "Dynamische URL umleiten Variante 5 und 6", wobei die Variante 5 übersichtlicher ist als meine:

Tipps und Tricks mit mod_rewrite - praktische Beispiele - Suchmaschinenoptimierung sterreich suchmaschinentricks.at
 
Ist ja nicht so, dass ich alles der htaccess überlassen würde. Würde PHP im ersten Schritt schon nicht ausliefern, sondern in $var_name= "alertXSS" verwandeln.
[...]
Im zweiten Schritt erst recht, da ja im SQL-Query gefragt wird, ob der Name der Seite und die Id vorhanden sind und übereinstimmen. Und da dieser Seitenname "alert('XSS')" und dieser "alertXSS" in der DB nicht vorhanden sind, würde PHP nichts ausliefern.
Dann kannst du aber auf das Sicherheitsfeature in der htaccess, das das Ganze nur weniger wartungsfreundlich macht, verzichten...

"www.example.com/themen-34.html"

doch diese Weiterleitung erfolgt nur wenn im QueryString kein anderer oder zusätzlicher Parameter enthalten ist:

Code:
RewriteCond %{QUERY_STRING} ^thema=([0-9]+)$
RewriteRule ^themen\.php$ /themen-%1.html? [L,R=301]

Was herauskommt wäre eine Endlosschleife,
Und genau das ist falsch, denn die Regel, die den Query-String für das Skript wieder zusammenbaut hat keine R-Flag (und darf auch keinen haben). Deswegen bekommt der Browser davon gar nichts mit und intern wird das Ergebniss der mod_rewrite nicht nocheinmal durch alle Regeln gejagt.

Probier's aus:
Code:
RewriteCond %{QUERY_STRING} (.*?)=([^&]*)(?:&?(.*))
RewriteRule ^(.+?)\.(php|html?|aspx)(.*?)/?$ $1.$2$3/%1/%2/?%3 [L,NC,R=301]

RewriteCond %{REQUEST_URI} index\.php/*(.*?)/(.*?)/?$
RewriteRule (.*?)index\.php/*(.*) index.php?%1=%2 [L,NC]
und dann www.example.org/index.php?a=b aufrufst, wird der Browser auf www.example.org/index.php/a/b/ weitergeleitet, aber im Skript kommt alles richtig an. Keine Gefahr der Endlosschleife.
 
Und genau das ist falsch,
Du gehst denke ich nur von einer Richtung aus. Du brauchst doch beide Richtungen, sonst wäre doch themen.php?thema=2 aufrufbar. Nicht der Browser, der Server überprüft die auszuliefernde noch einmal.

Habe nun heute Morgen extra noch einmal einen schnellen Test gemacht.

Angelegt: "http://localhost/themen.php"

Code:
RewriteEngine on

RewriteCond %{QUERY_STRING} ^thema=([0-9]+)$
RewriteRule ^themen\.php$ /themen-%1.html? [L,R=301]
RewriteRule ^themen-([0-9]+)\.html$ /themen.php?thema=$1 [L]
Aufgerufen: "http://localhost/themen-2.html"
Mitteilung vom Browser:

Fehler: Umleitungsfehler

Die aufgerufene Website leitet die Anfrage so um, dass sie nie beendet werden kann.
Aufgerufen: "http://localhost/themen.php?thema=2"
Mitteilung vom Browser:

Fehler: Umleitungsfehler

Die aufgerufene Website leitet die Anfrage so um, dass sie nie beendet werden kann.
Geändert mit &nur=so:
Code:
RewriteCond %{QUERY_STRING} ^thema=([0-9]+)$
RewriteRule ^themen\.php$ /themen-%1.html? [L,R=301]
RewriteRule ^themen-([0-9]+)\.html$ /themen.php?thema=$1&nur=so [QSA,L]
Aufgerufen: "http://localhost/themen-2.html" und "http://localhost/themen.php?thema=2"

Alles top, bei beiden Aufrufen wird nur "http://localhost/themen-2.html" angezeigt.


Code:
RewriteRule ^(.+?)\.(php|html?|aspx)(.*?)/?$ $1.$2$3/%1/%2/?%3 [L,NC,R=301]
Könnte den Zweck nicht erfüllen, weil ja mit (.*?) erlaubt wird, dass hinter der Endung noch etwas folgen darf.

Code:
RewriteRule ^(.+?)\.(php|html?|aspx)[COLOR="#FF0000"](.*?)[/COLOR]/?$
Es könnte jetzt aber auch daran liegen, dass Du davon ausgehst, dass "www.example.org/index.php/a/b/" ausgeliefert wird und ich eher von "www.example.org/index-a-b.html", das habe ich jetzt nicht getestet. Je länger ich mir Dein Beispiel betrachte, um so mehr denke ich, das es sich auch so verhält. Du überprüfst mit zwei Konditionen, einmal den QUERY_STRING und einmal die REQUEST_URI und gehst davon aus, dass die index.php erhalten bleibt. Ich überprüfe nur mit einer Kondition, davon ausgehend, dass die index.php verschwinden soll, denn wie die sich nennt, soll ja im Browser nicht sichtbar werden. Hätte die jetzt auch so benennen können:

Code:
RewriteCond %{QUERY_STRING} ^thema=([0-9]+)$
RewriteRule ^themen\.php$ /sichtbar-%1.html? [L,R=301]
RewriteRule ^sichtbar-([0-9]+)\.html$ /themen.php?thema=$1 [L]
 
Zuletzt bearbeitet:
Zurück
Oben