zurück zur Startseite
  


Zurück XHTMLforum > Webentwicklung (außer XHTML und CSS) > Serveradministration und serverseitige Scripte
Seite neu laden Pay-For-Download System

Antwort
 
LinkBack Themen-Optionen Ansicht
  #1 (permalink)  
Alt 01.12.2009, 13:17
Benutzer
neuer user
Thread-Ersteller
 
Registriert seit: 26.09.2008
Beiträge: 36
False Mirror befindet sich auf einem aufstrebenden Ast
Standard Pay-For-Download System

Hallo.
Ich bitte euch mein Pay-For-Download System in punkto Security, Usability und Effizienz zu beurteilen:

Ein User kann eine herunterzuladende Ware wie gewöhnliche Produkte in meinem (einfach gestrickten) Online-Shop kaufen. Ich verzichte auf eine direkte Bezahlmöglichkeit wie die Paypal API - grösstenteils aus Sicherheitsbedenken.
Bis vor einigen Jahren wurden die übertragenen Variablen ohne Verifikation an Paypal übertragen, das heisst man konnte mittels "Tamper Data" & Co Werte beliebig ändern. Ich hatte damals Paypal und einige Shops die dieses System benutzten darauf aufmerksam gemacht, von Paypal habe ich nie eine Antwort erhalten, aber inzwischen werden die Daten immerhin tamperproof übertragen. Dennoch bin ich bei Paypal in Punkto Security einfach skeptisch und biete es dem User deshalb nur an, direkt die Summe zu überweisen.
Nach dem Eingang des Geldes bekommt der User eine URL der Form:

.../dl.php?file=$file&id=$id&token=$token
Wobei $file der URL-encoded Dateiname des zu herunterladenden Files ist. $id ist die ID (aufsteigende Zahl) und $token ein SHA-256 HMAC über ID und Dateiname.

Beispiel:
http://www.falsemirror.de/dl.php?fil...e64dfbb0508d71
Dieser Token ist einen Monat lang gültig (zum Testen).

Umgesetzt ist das ganze in PHP (auch wenn ich die Sprache absolut hässlich finde ist man manchmal einfach drauf angewiesen).

Die Vorgehensweise ist wie folgt:
1. Einlesen der Parameter, urldecode() auf $file.
2. Überprüfen, ob alle Parameter vorhanden.
3. Überprüfen, ob die Länge aller Parameter stimmt (mittels strlen()).
4. Überprüfen, ob alle Parameter entsprechenden regulären Ausdrücken entsprechen.
5. Verifikation des HMACs.
6. Existenzprüfung der Datei.
7. Prüfen ob in der DB ein entsprechender Eintrag vorhanden ist.
8. Prüfen ob die Zeitdauer des Tokens gültig ist.
9. Falls bis dahin alle Tests erfolgreich: Ausliefern der Datei mittels readfile(). Die Datei befindet sich in einem mittels .htaccess geschützten Verzeichnis.

Schritt 7. und 8 sind in einer SQL-Query zusammengefasst um die Anzahl von DB-Anfragen zu minimieren.


Einige mögliche denkbare Angriffe:

Erzeugen eines gültigen Tokens zu einer bekannten Datei:
Aufgrund der Sicherheit der SHA-2 Hashes nicht effizient möglich.
Möglicher Schaden: gering, da ja auch ein gültiger DB-Eintrag vorhanden sein müsste.

SQL-Injection beim Zusammensetzen der Query:
Mittels Regex-Checks und der Verwendung von mysql_real_escape_string() relativ abgesichert, dennoch nie vollkommen auszuschliessen.
Möglicher Schaden: groß, Verlust der DB

Buffer Overflow bei strlen(), urldecode() und den regexp funktionen:
Wäre fatal wenn hier Buffer Overflows möglich wären, auszuschliessen ist es natürlich nie.

User gibt URL weiter:
Schaden wäre dass andere User den Download unberechtigterweise durchführen können. Allerdings ist der Zeitraum des Schadens zeitlich begrenzt (auf die Gültigkeit des Tokens). Mögliche Abhilfe wäre die Anzahl der Downloads zu begrenzen (im Optimalfall auf 1), was ich jedoch bislang aus Usability Gründen nicht tue.

Eavesdropping der ungesichert per E-Mail übertragenen URL:
Ist natürlich immer möglich, der Schaden ist jedoch nicht grösser als wenn der User die URL weitergibt.

Ausspähen des Inhalts des gesicherten Verzeichnis.
Ist ohne den HMAC check zu umgehen nicht möglich, da der Datei-Existenzcheck erst nach der HMAC Validierung durchgeführt wird.
Mit Zitat antworten
Sponsored Links
  #2 (permalink)  
Alt 01.12.2009, 14:03
Benutzerbild von mantiz
Erfahrener Benutzer
XHTMLforum-Kenner
 
Registriert seit: 25.02.2007
Beiträge: 2.843
mantiz kann auf vieles stolz seinmantiz kann auf vieles stolz seinmantiz kann auf vieles stolz seinmantiz kann auf vieles stolz seinmantiz kann auf vieles stolz seinmantiz kann auf vieles stolz seinmantiz kann auf vieles stolz seinmantiz kann auf vieles stolz sein
Standard

Warum bietest Du den Usern nicht einfach ein Portal, wo sie sich einloggen und die Dateien, die sich gekauft haben runterladen können.

Vorteil wäre, dass die Benutzer die E-Mails mit den Download-Links nicht speichern müssen, einen Link merken können diese sich eh nicht, da die Tokens einfach zu kompliziert sind, also müssen diese immer in ihren Mails nach dem Link suchen, das wäre doch einfacher, wenn sie sich einfach bei Dir einloggen könnten.

So könntest Du Dir das komplette Token-Handlich sparen, Du musst einfach nur noch auf die Session prüfen, welche Du ja durchaus durch eine eigene evtl. längere kryptischere SessionID ändern kannst. Weiterhin könnte sämtliche Kommunikation ab dem Login via https laufen und wäre somit verschlüsselt und nicht so einfach auszuspähen, wodruch schonmal 2 Angriffsszenarien wegfallen würden.

Dann wäre nur die Frage, ob Du Benutzern erlauben möchtest Ihre gekauften Dateien weiterzugeben, was durch Deine Link-Lösung ja möglich wäre, alternativ könnte man für diesen speziellen Fall aber auch ein Token und/oder Login generieren, der dann weitergegeben werden kann, anstelle des Links.

Aber das sind nur so spontane Ideen dazu.
Mit Zitat antworten
Sponsored Links
  #3 (permalink)  
Alt 01.12.2009, 15:33
Benutzer
neuer user
Thread-Ersteller
 
Registriert seit: 26.09.2008
Beiträge: 36
False Mirror befindet sich auf einem aufstrebenden Ast
Standard

Vielen Dank für die Antwort.

Zitat:
Zitat von mantiz Beitrag anzeigen
Warum bietest Du den Usern nicht einfach ein Portal, wo sie sich einloggen und die Dateien, die sich gekauft haben runterladen können.
Hätte klar einige Vorteile, hätte aber einen ungleich höheren Verwaltungsaufwand (Benutzer/Session-Verwaltung, sicheres Login-System,zusätzliches User-Interface, etc) und ist in meinem Fall (kleiner Shop, wenig Kunden, wenig Artikel) definitiv nicht nötig.
Die Sicherheit wäre auch nur bedingt erhöht. Klar würde SSL mir verschlüsselte Kommunikation zwischen User/Server ermöglichen und die Unsicherheit von E-Mail beheben, allerdings müsste ich dann im Optimalfall auch ein Zertifikat besitzen das von einer Root-CA signiert wurde, ansonsten wären SSL-Man-In-The-Middle Angriffe eine Leichtigkeit (falsches Zert ausstellen, in Kommunikation einklinken, Daten abfangen).
Der Login und die User-DB würde eine weitere mögliche Schwachstelle darstellen.

Weitergabe der URLs ist i.d.R. nicht erwünscht, siehe oben.

Geändert von False Mirror (01.12.2009 um 15:48 Uhr)
Mit Zitat antworten
  #4 (permalink)  
Alt 01.12.2009, 16:06
Benutzerbild von Scheppertreiber
Chaot und Nonkonformist.
XHTMLforum-Kenner
 
Registriert seit: 13.03.2007
Ort: Steinmark im Spessart
Beiträge: 7.458
Scheppertreiber ist ein LichtblickScheppertreiber ist ein LichtblickScheppertreiber ist ein LichtblickScheppertreiber ist ein LichtblickScheppertreiber ist ein Lichtblick
Standard

Zitat:
7. Prüfen ob in der DB ein entsprechender Eintrag vorhanden ist.
wäre das einzige Einfallstor für eine SQL-Injection (Schritt 8 kann genausogut
über einen timestamp in der URI erfolgen). Ich vermute, Du schaust in der
Datenbank nach ob der Hashwert ok ist. Dann kann man den Wert aber recht
einfach überprüfen (Du weißt ja, welche Zeichen im Hashwert vorkommen
dürfen).

In der Datenbank reicht es eigentlich, dort den Zahlungseingang einzutragen
(das ist aber ein rein interner Vorgang). Der Zahlungseingang gibt dann die
Übertragung frei.
__________________
Grüße aus dem Spessart, Joe

{ table-layout: biertischistbesser; }
Der Mausinator
Mit Zitat antworten
  #5 (permalink)  
Alt 01.12.2009, 17:36
Benutzer
neuer user
Thread-Ersteller
 
Registriert seit: 26.09.2008
Beiträge: 36
False Mirror befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von Scheppertreiber Beitrag anzeigen
wäre das einzige Einfallstor für eine SQL-Injection (Schritt 8 kann genausogut
über einen timestamp in der URI erfolgen). Ich vermute, Du schaust in der
Datenbank nach ob der Hashwert ok ist. Dann kann man den Wert aber recht
einfach überprüfen (Du weißt ja, welche Zeichen im Hashwert vorkommen
dürfen).

In der Datenbank reicht es eigentlich, dort den Zahlungseingang einzutragen
(das ist aber ein rein interner Vorgang). Der Zahlungseingang gibt dann die
Übertragung frei.

Thx.
Ich wollte die Timestamps aus der URL raushalten damit
1. die URLs kürzer bleiben.
2. Ich die Zeit bei Bedarf noch ändern kann.

Die query sieht so aus:
"SELECT count(id) FROM downloadtokens WHERE id='".mysql_real_escape_string($id)."' AND token='".mysql_real_escape_string($token)."' AND file='".mysql_real_escape_string($filename)."' AND ((leasehours='0') OR (requesttime + 3600 * leasehours >= ".time()." ))";

Alle Werte werden gegen Regex Patterns gematcht:
filename: [a-zA-Z0-9_-]+
id: [0-9]+
token: [a-f0-9]+

Die mysql_real_escape_string sind im Grunde deshalb auch überflüssig, stellen aber einfach nochmal ne Sicherheitsstufe ggü. SQL-Injections dar.

Den Hashwert prüfe ich im Grunde 2mal.
1. Bei der HMAC Berechnung/Abgleich mit dem Token
2. Beim Eintrag in der Datenbank.

Zweiteres ist im Grunde auch nur eine zusätzliche Sicherheitsstufe, da der DB-Eintrag ja schon über die ID aufgefunden werden kann. Aufgrund der Kollisionsunwahrscheinlichkeit (zwei gleiche Hashes) hätte ich statt der IDs auch direkt die Hashes verwenden können und die Zeit in die URL und somit auch in den HMAC packen können.
Hat natürlich beides seine Vor- und Nachteile.


Zahlungseingang & Co werden übrigens an ganz anderer Stelle verwaltet und haben nichts mit dem Token-Download-System zu tun.


Edit: Habe time() noch mit einem mysql_real_escape_string übergeben, schliesslich könnte es theoretisch möglich sein, dass jemand den time() Funktionsaufruf umbiegt und somit eine Injection generiert - unwahrscheinlich, aber theoretisch möglich.

Geändert von False Mirror (01.12.2009 um 20:25 Uhr)
Mit Zitat antworten
  #6 (permalink)  
Alt 01.12.2009, 20:23
Benutzerbild von Scheppertreiber
Chaot und Nonkonformist.
XHTMLforum-Kenner
 
Registriert seit: 13.03.2007
Ort: Steinmark im Spessart
Beiträge: 7.458
Scheppertreiber ist ein LichtblickScheppertreiber ist ein LichtblickScheppertreiber ist ein LichtblickScheppertreiber ist ein LichtblickScheppertreiber ist ein Lichtblick
Standard

Sorry, ich kenne PHP nur sehr rudimentär (dh ich weiß wie man es schreibt ).

Bei meinem Archiv arbeite ich mit einem timestamp (es sind gerade mal 8 Byte time()
als Hexzahl). Bei der Überprüfung des timestamps vergleiche ich den Aufruf mit der
aktuellen Zeit. Weicht die zu stark ab oder ist älter als die letzte Aktion, fliegt
der User raus (dadurch funktionieren auch keine herauskopierten Links).

Im Grunde recht ähnlich ...

Teilweise verwende ich auch SQL (SQLite), bei relevanten Sachen hacke ich den String
sobald ein ";" auftaucht ab ... Alles ist über einen MD5 "verhasht.
Es würde mit ziemlicher Sicherheit auffallen.

Bei der Prüfung der CGI-Parameter verwerfe ich die Anfrage wenn einer der
Parameter eine bestimmte Länge überschreitet, komplett. Auch wenn nicht
vorgesehen Namen von CGI-Variablen auftauchen.

Seit den 5 Jahren wo das Archiv Online ist, ist noch keiner durchgekommen.
Einige Versuche gab es schon

Mir fehlt noch das Grundvertrauen in SQL. Mal sehen, das mit SQLite läuft
erst seit einem Jahr.
__________________
Grüße aus dem Spessart, Joe

{ table-layout: biertischistbesser; }
Der Mausinator
Mit Zitat antworten
  #7 (permalink)  
Alt 01.12.2009, 20:30
Benutzer
neuer user
Thread-Ersteller
 
Registriert seit: 26.09.2008
Beiträge: 36
False Mirror befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von Scheppertreiber Beitrag anzeigen
Alles ist über einen MD5 "verhasht.
MD5 ist nicht mehr als stark kollisionsresistent zu betrachten.
MD5 - Wikipedia, the free encyclopedia

Ich würde stattdessen zu einer Hashfunktion aus der SHA-2 Familie greifen (SHA-1 ist inzwischen ebenfalls unsicher).
Mit Zitat antworten
  #8 (permalink)  
Alt 01.12.2009, 20:37
Benutzerbild von Scheppertreiber
Chaot und Nonkonformist.
XHTMLforum-Kenner
 
Registriert seit: 13.03.2007
Ort: Steinmark im Spessart
Beiträge: 7.458
Scheppertreiber ist ein LichtblickScheppertreiber ist ein LichtblickScheppertreiber ist ein LichtblickScheppertreiber ist ein LichtblickScheppertreiber ist ein Lichtblick
Standard

Ja, Danke. Ist geplant. Im Moment plage ich mich mit anderen Sachen

(bin halt der einzige, der entwickelt) *ächz*
__________________
Grüße aus dem Spessart, Joe

{ table-layout: biertischistbesser; }
Der Mausinator
Mit Zitat antworten
  #9 (permalink)  
Alt 09.12.2009, 11:05
Erfahrener Benutzer
XHTMLforum-Kenner
 
Registriert seit: 29.07.2005
Beiträge: 1.073
xm22 befindet sich auf einem aufstrebenden Ast
Standard

Numerische Werte kannst Du doch einfach mit (int) casten, statt darauf Regexp und escapen anzuwenden. Ansonsten ist der Query sicher.
__________________
... Meine Meinung
Mit Zitat antworten
Sponsored Links
  #10 (permalink)  
Alt 09.12.2009, 19:14
Benutzer
neuer user
Thread-Ersteller
 
Registriert seit: 26.09.2008
Beiträge: 36
False Mirror befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von xm22 Beitrag anzeigen
Numerische Werte kannst Du doch einfach mit (int) casten, statt darauf Regexp und escapen anzuwenden. Ansonsten ist der Query sicher.
Thx. Wenn ich lediglich auf int casten würde wäre, allerdings negative Werte noch möglich, deshalb der regex check.
Alternativ könnte ich natürlich noch den Betrag nehmen o.ä., aber indem ich generell alle Werte auf RegEx Patterns abgleiche ist es auch einfacher wenn ich mal ein Format ändern sollte, z.B. hexadezimale IDs o.ä.
Mit Zitat antworten
Sponsored Links
Antwort

Stichwörter
download, shop, token


Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
960 Grid System - Problem ceville CSS 1 17.09.2009 11:18
Schriftart welche auf jedem System vertreten ist? Korasu CSS 4 05.10.2008 15:19
Ändert sich die Breite von System zu System? Steakfred CSS 3 26.11.2007 21:37
Hängung bei verschachtelten Listen mit Nummerierung im System "1.1.1" AndreasB CSS 2 05.11.2006 00:33
Nicht valieder Code von Map24 sveniboy (X)HTML 7 06.11.2005 19:19


Alle Zeitangaben in WEZ +2. Es ist jetzt 13:29 Uhr.