Closed jantheofel closed 12 years ago
Natürlich braucht es auch noch zwei Einträge in den Languagefiles, die ich oben vergessen habe:
system/modules/backend/languages/en/tl_settings.php:
$GLOBALS['TL_LANG']['tl_settings']['refererWhiteList'] = array('Disable referer check for these domains', 'Do not check the referer host address for these domains when a form is submitted. Enter as comma seperated list. Choosing this option is a potential security risk
![](');
system/modules/backend/languages/de/tl_settings.php:
$GLOBALS['TL_LANG']['tl_settings']['refererWhiteList'] = array('Referer-Prüfung für diese Domains deaktivieren', 'Die Referer-Adresse wird für diese Domains beim Absenden eines Formulars nicht geprüft. Eingabe als kommaseparierte Liste. Warnung: potentielles Sicherheitsrisiko)');
--- Originally created on June 14th, 2011, at 02:23pm
Das würde den Sicherheitsmechanismus aushebeln, denn den Referer kann man beliebig manipulieren. Will heißen, ich sende einfach den Referer "facebook.com" mit und schon habe ich uneingeschränkt Zugriff! Genau deswegen wurde die Referer-Prüfung ja gegen ein Request-Token-System ausgetauscht. Insofern ist das keine Option.
Trotzdem sollten wir überlegen, wie wir das Problem "Kommunikation mit PayPal" oder "Kommunikation mit Facebook" lösen.
--- Originally created on June 14th, 2011, at 05:45pm
Zu Paypal kann ich nichts sagen. Für Facebook habe ich den Code gerade fertig, der in einem Modul prüft ob der Request dort her kommt. (In dem Fall werden einige Post-Daten mit Signatur übergeben.) Allerdings ist die Frage ob der Core das abfangen soll oder die Module die eh dahinter kommen müssen und mit Facebook, Paypal, etc. interagieren an diesen Stellen die Prüfung übernehmen.
--- Originally created on June 14th, 2011, at 06:34pm
IMO beides, der Core sollte die Tokens selbst checken, wenn dies nicht erfolgreich war, dann kommt ein HOOK ins Spiel, welcher weitere POST-Tests machen kann (wie die von Jan angesprochene Signatur checken - OAuth etc.).
Wenn also eines der registrierten Verfahren den POST als valide anerkennt, ist alles in Ordnung.
--- Originally created by xtra on July 7th, 2011, at 05:18pm
--- Originally closed on August 23rd, 2011, at 06:09pm
@leofeyer was ist besser: Eine "optionale Lücke", die man möglicherweise ausnutzen kann, wenn diese 1. offen ist und 2. man genau herausgefunden hat wie man diese Lücke ausnutzt (so einfach ist das in diesem Fall nämlich nicht). Oder aber, das vollständige Abschalten der Tokens, das muss man nämlich aktuell machen und wird man auch in 2.11 machen müssen.
Was bezweckst Du mit der Frage? Wieso muss man die Tokens in der 2.11 deaktivieren?
Wenn ich Tristan richtig verstehe will er damit sagen, dass es besser einen Hook einzubauen, der dann zum Beispiel für Facebook eine alternative Prüfung vorsieht als die Referrer-Prüfung komplett abzuschalten. Was sonst die einzige Alternative ist wenn man z.B. eine Contao-Seite in eine Facebook-Fanseite integrieren will.
Was ist denn mit der Konstante BYPASS_TOKEN_CHECK
? Diese kann man in einem eigenen Entry-Skript (z.B. facebook.php
) setzen und dann seine eigene Prüfung einbauen.
@leofeyer ich wollte genau das sagen, was @jantheofel interpretiert hat. Ich werde bei einem zukünftigen Projekt vor dem gleichen Problem stehen. Und da muss ich dann die Tokens für das ganze System deaktivieren. D.h. auch für alle nicht-FB Seiten innerhalb der Contao Installation.
Mh, weil man dann die Seitenstruktur nicht mehr dafür nutzen kann oder nur noch, in dem man das noch virtueller macht? Es geht ja nicht darum, irgendwelche Daten aus einer Extension an Facebook zu übergeben, sondern man will eine Seite aus Contao in Facebook anzeigen. Eventuell sogar mehrere. Man könnte das natürlich auch über ein Entry Script machen, aber wo ist der Sicherheitsgewinn dann? Dann kannst du auch /facebook_entry.php/acme.html anstelle von /acme.html aufrufen und immer noch alles machen. Im schlimmsten Fall könntest du dann sogar noch mehr "schindluder" damit treiben, wenn die facebook_entry.php nicht ordentlich gebaut ist.
Was wäre denn, wenn man die von @jantheofel vorgeschlagene Whitelist nicht nur auf Referer, sondern auch für lokale Pages beschränkt?
Alternativ, wir wollten schon immer einen systemInitialisationHook haben - der Hook sollte nach der Initialisierung des Systems (laden der Config) und der Initialisierungslogik (setzen von PHP Settings, prüfen von Referer etc.) aufgerufen werden -, ich glaube Andreas Schempp wollte/hat dazu auch ein Ticket gemacht. Wenn wir solch einen Hook hätten, könnten wir das eventuell auch als Extension machen.
Ich verstehe das Problem immer noch nicht. Wenn eine Contao-Seite in Facebook eingebunden wird, läuft Contao doch in einem iFrame. Und wo ist der Unterschied zwischen einer Whitelist und einem Entry-Skript? In beiden Fällen kann der Zugriff auf eine bestimmte Domain limitiert werden und beide Varianten haben dann dieselben Schwachstellen.
Wo ist dann der Praktische Unterschied, außer einer anderen URL? Ich finde persönlich das das Entry Script leichter ausnutzbar ist, als die Whitelist.
Eigentlich besteht nur die Problematik dass Contao afaik die Apache MultiView doch gar nicht mehr unterstützt? Also würde /facebook_entry.php/acme.html sowieso nicht funktionieren. (zumindest funktioniert /index.php/acme.html nicht mehr, sobald das URL Rewrite aktiviert ist).
Und ich habe von Leuten gehört, die nur Unterverzeichnisse oder Domains aber keine PHP-Dateien verlinken konnten. Also auf Facebook.php/xyz.html ging bei denen nicht...
Wie gerade auf der #ck2012 besprochen hier noch mal ein Ping, damit du da einen Hook einbaust, mit dem Extensions externe Post-Daten verifizieren und annehmen können, beispielsweise die von Facebook. Das umgeht die Whitelist und erfordert keine komplexeren URLs oder andere Lösungen. Danke!
Ne Idee wann das ganze umgesetzt ist? Weil aktuell muss der Token-Prüfung ja noch komplett abgeschaltet werden...
Ich habe die Funktion in c967dd5fc94f0c716c7ddbc55ff50471dc32fa18 (Branch "token-whitelist") hinzugefügt. Allerdings habe ich noch immer Sicherheitsbedenken, denn wenn Du z.B. http://www.facebook.com
auf die Whitelist setzt, muss ich einfach nur jedem Request den Referer-Header http://www.facebook.com
mitsenden und umgehe so die Token-Prüfung – auch wenn der Request gar nicht von Facebook kommt und etwas ganz anderes macht.
Im Prinzip müsste jeder, der die Whitelist nutzt, gleichzeitig eine Prüfungsroutine mitliefern, die Anfragen mit dem Request-Header http://www.facebook.com
anhand weiterer Kriterien prüft und jede ungültige Anfrage ablehnt. Andernfalls kann man die Token-Prüfung auch gleich ausschalten.
Problem hier: Die Whitelist ist im Backend konfigurierbar, dort kann man aber keine Prüfungsroutine hinzufügen. Ich wäre daher dafür, die Whitelist nicht im Backend zu befüllen, sondern in der config.php
der Erweiterungen, die das Feature nutzen. Auf diese Weise verschiebt sich die Verantwortung vom Anwender zum Entwickler, der mit etwas Glück eine entsprechende Prüfungsroutine mitliefert.
@jantheofel und @contao/workgroup-core: Wie seht ihr das?
Gefällt mir gar nicht! HTTP_REFERER
spoofing ist zu trivial und facebook.com
zu offensichtlich.
Sind denn die HTTP_POST
Daten von Facebook interessant? Gibt es noch andere Anwendungsfälle außer Facebook?
Ich würde das nicht als Whitelist machen, schon gar nicht für den User konfigurierbar. Lieber einen Hook, in den sich Module einklinken können und dort z.B. die POST-Daten, di von Facebook kommen, prüfen und das dann freigeben.
@jantheofel aber möchtest du nicht eine beliebige Seite auf Facebook darstellen? Irgendwie kann ich den Anwendungsfall gar nicht korrekt erfassen.
Für ein Modul haben wir die BYPASS_TOKE_CHECK
Konstante!
Ich möchte beliebig viele Seiten dort darstellen können. Und dafür nicht manuell eine index-fb.php bauen, die Bypass macht und irgendwelche verrückten URLs und/oder extra .htaccess-Regeln braucht. Und es soll ja auch nicht einfach ein simpler Bypass sein sondern es soll ja auf jeden Fall die Sicherheitsprüfung kommen - nur eben eine andere!
Ich würde das nicht als Whitelist machen, schon gar nicht für den User konfigurierbar
Hm, genau so hast Du es aber oben vorgeschlagen und deswegen habe ich es so programmiert :)
Für ein Modul haben wir die BYPASS_TOKE_CHECK Konstante
Die fiele im Zuge der Whitelist bzw. des Hooks weg.
Oh, stimmt, das war meine ursprüngliche Anfrage. Ich hätte dazu schreiben sollen, dass es da wohl noch einen besseren Weg gibt nachdem der ja berechtigter Weise kritisiert worden ist. :-(
Halb so wild, Hauptsache wir finden jetzt noch gemeinsam eine gute Lösung.
Nächster Versuch: 8675d07f91e4ac3324c49c011f8f107b3378aed5
Sprich dann soll ich jetzt den Hook testen? ;-)
Klaro mach mal ;)
Denk dran den richtigen Branch auszu-checkout
en
Wie wäre es mit einer Reverse-IP Prüfung? Die Request IP zu spoofen ist schon deutlich schwerer als den Referer.
Valid Domain: facebook.com (per config.php)
Request IP: 69.171.224.37 Reverse IP: 37.224.171.69.in-addr.arpa -> www-slb-10-01-prn1.facebook.com.
www-slb-10-01-prn1.facebook.com ist subdomain von facebook.com und damit zulässig.
Wäre das ein Lösungsansatz?
Nur ein kleines Experiment das euch vielleicht weiter hilft. :-)
<?php
// whitelist
$GLOBALS['TL_CONFIG']['whitelistDomains'] = array(
// 'd1-online.com'
);
// blacklist
$GLOBALS['TL_CONFIG']['blacklistDomains'] = array(
// 'customers.d1-online.com'
);
class AccessCheck // extends System
{
function checkHost()
{
// get current hostname by remote address
$hostname = gethostbyaddr($_SERVER['REMOTE_ADDR']);
// check blacklist
foreach ($GLOBALS['TL_CONFIG']['blacklistDomains'] as $blacklistDomain) {
if (preg_match('#\.' . preg_quote($blacklistDomain) . '$#', $hostname)) {
// $this->log('The request hostname ' . $hostname . ' is blacklisted.', 'AccessCheck', TL_ERROR);
return false;
}
}
// check whitelist
foreach ($GLOBALS['TL_CONFIG']['whitelistDomains'] as $whitelistDomain) {
if (preg_match('#\.' . preg_quote($whitelistDomain) . '$#', $hostname)) {
// $this->log('The request hostname ' . $hostname . ' is whitelisted.', 'AccessCheck', TL_ERROR);
return true;
}
}
return false;
}
}
$access = new AccessCheck();
var_dump($access->checkHost());
?>
Finde ich super. @jantheofel kommst Du damit auch ans Ziel?
Diese Funktion könnte man dann über eine Erweiterung und dem Hook bereitstellen. Die Idee an sich gut!
Ich fände es auch gut, wenn die Prüfung direkt im Core wäre. Dann könnte man nämlich wirklich in den BE-Einstellungen die Whitelist komfortabel pflegen.
Ja, wenn wir die Prüfung wie von Tristan vorgeschlagen einbauen sollte das auch für Facebook funktionieren und wäre im Core denke ich besser aufgehoben. Allerdings würde ich dennoch keine manuelle Whitelist anlegen, sondern diese nur von Erweiterungen befüllen lassen.
So in der Art: $GLOBALS['TL_CONFIG']['whitelistDomains'][] = 'facebook.com';
Denn wenn eine Domain POST-Daten sendet, dann wird es wohl auch immer eine Erweiterung geben, die diese ausliest und auswertet. Den User mit einer weiteren Einstellung, die doch eher erklärungsbedürftig ist, zu verwirren, halte ich nicht für sinnvoll. Im Zweifelsfall sollte jeder, der so was wirklich braucht, in der Lage sein, ein paar Zeilen PHP dafür zu bemühen...
Im Zweifelsfall sollte jeder, der so was wirklich braucht, in der Lage sein, ein paar Zeilen PHP dafür zu bemühen...
Dem stimme ich zu, und wenn es ein $GLOBALS['TL_CONFIG']['whitelistDomains'][] = 'facebook.com';
innerhalb der localconfig ist, das man von Hand rein schreibt.
PS: mir fällt gerade auf, dass die Prüfung eigentlich noch ergänzt werden müsste:
<?php
...
if ($blacklistDomain == $hostname ||
preg_match('#\.' . preg_quote($blacklistDomain) . '$#', $hostname)) {
...
if ($whitelistDomain == $hostname ||
preg_match('#\.' . preg_quote($whitelistDomain) . '$#', $hostname)) {
...
Das wird zwar Facebook nicht betreffen, da die mehrere Server haben, aber vielleicht benötigt man das auch mal in einer Umgebung, wo die Domain equivalent ist.
Ich habe die Änderungen in 537196f6fe99acf926df9a9e8297177ea0f2a809 eingebaut. Bitte noch mal prüfen und dann eine Rückmeldung geben, damit ich den Branch mergen kann.
Ich habe es gerade lokal getestet, funktioniert auch mit localhost :-)
Implementiert in ee2a3f3e5663b53dd2eff347852af9ec082526a2.
Hi, ich habe die Änderung in 2.11 übertragen. Leider funktioniert es nicht so wie gedacht. $_SERVER['REMOTE_ADDR'] - hat immer meine IP zurückgegeben, getestet gestern in einer Facebook App. Also musste ich noch einen Umweg gehen. ...
foreach ($GLOBALS['TL_CONFIG']['requestTokenWhitelist'] as $strDomain)
{
$ip = gethostbyname($strDomain);
$strHostname = gethostbyaddr($ip);
if ($strDomain == $strHostname ||
preg_match('/\.' . preg_quote($strDomain, '/') . '$/', $strHostname))
{
return true;
}
}
...
Wenn man generell die Referer-Prüfung (was ja in 2.10 eigentlich zur Token-Prüfung wird) generell nutzen möchte, wäre es sehr hilfreich einzelne Domains von der Prüfung ausnehmen zu können. Zwei Anwendungsbeispiele:
Dazu schlage ich eine kommasperatierte Liste in den Einstellungen und dazu folgende Implementierung vor:
system/config/config.php respektive system/config/localconfig.php ergänzen:
system/modules/backend/dca/tl_settings.php Palatte ergänzen:
und ergänzen:
Die Anfrage erfolgt in system/initialize.php:
--- Originally created on June 14th, 2011, at 02:19pm (ID 3164)