security on rails: darstellung von sicherheitskonzepten in ruby on rails 3.0 anwendungen
DESCRIPTION
Ruby on Rails, Web Engineering, Security, Rails Security, Rails 3.0, Web-Application Security, Security-EngineeringTRANSCRIPT
Security on Rails: Darstellung von Sicherheitskonzepten
in Ruby on Rails 3.0 Anwendungen
Christoph Böhm
Universität Bamberg, Lehrstuhl für Wirtschaftsinformatik insb. Industr. Anwendungssysteme
Feldkirchenstraße 21, 96045 Bamberg, Deutschland
Abstract. Der Schutz von Webanwendungen vor Angriffen ist als impliziter
Bestandteil der Webentwicklung zu verstehen. Für die Realisierung einer siche-
ren Anwendungsplattform eignet sich das Web Framework Ruby on Rails 3.
Dabei ergibt sich die Sicherheit eines jeden Webframeworks aus dem Zusam-
menspiel der Systemebene, der eingesetzten Technologien sowie der Qualität
der Implementierung. Jede einzelne Ebene bietet spezifische Herausforderun-
gen, für dessen Lösung Ruby on Rails vordefinierte, teilweise auch implizite
Lösungen anbietet. Vor allem die Einhaltung dieser Programmierschemata un-
terstützt die schnelle und sichere Umsetzung von webbasierten IT-Verfahren
mit Hilfe von Rails 3.0.
Stichworte: Ruby on Rails, Web Engineering, Security, Rails Security, Rails
3.0, Web-Application Security, Security-Engineering
1 Einführung
1.1 Motivation
Oft liegt der Hauptfokus bei der Entwicklung von Webanwendungen auf der Funktio-
nalität sowie einer einfach zu bedienenden, interaktiven Benutzeroberfläche. Ziel ist
es, mit Webanwendungen möglichst schnell Netzwerkeffekte zu nutzen und daraus
folgend viele Kunden für den eigenen Dienst zu gewinnen.
Zu kurz kommt dabei häufig der Aspekt der Sicherheit [1, S. 121]. Unzureichend
geschützte Webanwendungen stellen jedoch eine große Gefahr für jedes im Internet
tätige Unternehmen dar. So stellt Kaspersky im Cyberthreat Forecast for 2012 fest,
das Webseitenbetreiber im Internet mittlerweile eine wahre Sammelwut bei der Erfas-
sung von Kundendaten entwickelt haben, diese aber nur unzureichend gegenüber
Angriffen schützen können [2, S. 3]. Prominentester Fall im Jahr 2011 war der Dieb-
stahl von Kunden- sowie Kreditkarteninformationen von Sonys Playstation Network,
was einen großen Image- und Vertrauensverlust für diese Plattform bedeutete [3, S.
22]. Diese Problematik wiegt umso kritischer, da das prägende Trendthema im Web,
das Cloud-Computing, zu großen Teilen von dem Vertrauen der Kunden in die Anbie-
ter und deren Fähigkeiten, die Nutzerdaten vor unberechtigten Zugriff zu schützen,
abhängt [2, S. 3]. Moderne Angriffsformen wie Cross-Site Scripting oder SQL-
Injection, also Angriffsformen, die direkt auf eine fehlerhafte Implementierung von
Webanwendungen abzielen, zählen dabei mittlerweile zu den häufigsten Einfallstoren
in Unternehmensnetzwerke [4].
Rails als Framework für die Entwicklung und dem Betrieb webbasierter Applikati-
onen unterstützt bei der Implementierung sicherer Webanwendung, um den Heraus-
forderungen im Web gerecht zu werden. Dabei gilt aber, dass Webframeworks wie
Ruby on Rails nicht per se sicher sind, sondern der Entwickler beziehungsweise Be-
treiber diesen Aspekt implizit während des gesamten Lebenszyklus einer Webanwen-
dung beachten muss. Aufgrund dieser Tatsache ist es Ziel der Ausarbeitung, Gefah-
ren- und Risiken beim Einsatz von Ruby on Rails 3 aufzuzeigen und darauf aufbau-
end Lösungsansätze für spezifische Problemstellungen darzustellen.
1.2 Aufbau der Arbeit
Die vorliegende Projektarbeit gliedert sich in sechs Kapitel. Neben dem einleitenden
ersten Kapitel befasst sich Kapitel Zwei mit der generellen Darstellung der für die
Sicherheit einer Webanwendung relevanten Inhalte und Prozesse. Hierbei wird ein
vom Bundesamt für Sicherheit in der Informationstechnik veröffentlichtes Ebenen-
modell zur Absicherung von Webanwendungen vorgestellt, dass als Grundlage für die
Entwicklung sicherer Ruby on Rails Anwendungen dienen soll. Die für die Entwick-
lung und Bereitstellung von Rails Applikationen relevanten Ebenen werden in Kapitel
Drei, Vier sowie Fünf detailliert dargestellt. Hierbei wird auf die Implementierung,
die eingesetzten Technologien sowie die Systemebene detailliert eingegangen. Die
Schlussbetrachtung vervollständigt die vorliegende Projektarbeit.
2 Grundlagen der sicheren Anwendungsentwicklung
2.1 Web Application Security
Bevor konkret dargestellt werden soll, wie sichere Webanwendungen mit Ruby on
Rails entwickelt und bereitgestellt werden können, ist für ein gemeinsames Verständ-
nis der Begriff Web Application Security näher zu definieren.
Der Begriff IT-Sicherheit an sich wird in verschiedenen Zusammenhängen und
Bedeutungen benutzt. Eine einheitliche Definition des Begriffs gibt es daher in der
Literatur nicht [5, S. 265]. Für die Projektarbeit sollen zwei Definitionen des Institute
of Electrical and Electronics Engineers gelten, die sich auf die Sicherheit von IT-
Anwendungen beziehen. ISO/IEC 25010 sowie ISO/IEC 15026 definieren Sicherheit
als „the protection of system items from accidental or malicious access, use, modifi-
cation, destruction, or disclosure“[6, S. 218]. Im Mittelpunkt der Betrachtung der
Sicherheit steht damit der Schutz von Anwendungssystemen vor beabsichtigten oder
unbeabsichtigten Zugriff, Modifikation, Zerstörung sowie Veröffentlichung. Ebenfalls
definiert ISO/IEC 25010 in diesem Zusammenhang, dass der Begriff Sicherheit in die
Charakteristiken Authentizität, Anonymität, Integrität, Verbindlichkeit, Verfügbarkeit
sowie Vertraulichkeit unterteilt werden kann. Für eine genaue Beschreibung dieser
Teilaspekte sei jedoch auf die einschlägige Literatur verwiesen (vergleiche hierzu [5]
sowie [6, S. 218]).
Im Gegensatz zur traditionellen IT-Sicherheit spezialisiert sich das Themengebiet
Web Application Security auf Anwendungen, welche auf den Technologien des
W3Cs basieren und über einen Webbrowser abgerufen werden können [5, S. 2]. Im
Vergleich zur traditionellen Application Security erwähnt Kappel, dass die Heraus-
forderungen auf Grund der Charakteristik von Webanwendungen als verteilte Syste-
me in einem weltweit verfügbaren Netz sich von den traditionellen Anwendungen
klar unterscheiden. So kommt als zu schützender Bereich nicht nur das eigene IT-
Verfahren in Betracht. Vielmehr wird ein Ende-zu-Ende-Schutz angestrebt, bei dem
der Endanwender, der Diensteanbieter sowie die sichere Kommunikation zwischen
beiden Kommunikationspartnern [5, S. 266f] umfassend analysiert werden.
Besondere Herausforderung des Web Application Securities ist dessen Vernetzung
mit zahlreichen, ebenfalls wichtigen Eigenschaften von Webanwendung [7, S. 4]. So
wird die Benutzerfreundlichkeit eingeschränkt, indem die Webanwendung sich nach
einer bestimmten Zeit ohne Benutzerinteraktion automatisch beendet oder doppelte
Passworteingaben notwendig sind. Auch die Performance wird negativ beeinflusst, da
beispielsweise Verschlüsselungsalgorithmen die Datenübertragung verlangsamen.
Entsprechend ist zu schlussfolgern, dass Grundlage einer systematischen Absicherung
von Webanwendungen immer auch eine Abwägung der Vor- und Nachteile sowie
eine dazugehörende systematische Risikoeinschätzung sein muss [7, S. 4][1, S. 120].
2.2 Security Engineering im Software Entwicklungszyklus
Die Praxis zeigt jedoch, dass Termin- und Kostendruck es häufig nicht zuzulassen,
eine fundierte Sicherheitsstrategie zu entwerfen [1, S. 121]. Der Penetrationstest kurz
vor Inbetriebnahme als einzige sicherheitsgebende Maßnahme ist nicht ausreichend.
Auch ein Big-Bang-Ansatz, bei dem mit massivem Aufwand am Ende der Software-
entwicklung auf einen Schlag all das, was bei der eigentlichen Implementierung ver-
säumt wurde, aufgeholt werden soll, ist meist nicht erfolgreich [8, S. 16f].
Ziel des Security Engineering ist es daher, das alle am Entwicklungsprozess betei-
ligten Personen die Kriterien der sicheren Anwendungsentwicklung als inhärenten
Bestandteilen des Lebenszyklus einer Webanwendung verstehen [8, S. 17]. Je früher
im Entwicklungsprozess klare Zielsetzungen und Vorgehensmodelle für die Sicher-
heit definiert und kommuniziert werden, desto nachhaltiger und günstiger können
sichere Anwendungen realisiert werden [1, S. 121]. Jede Phase des Softwareentwick-
lungszyklus weist dabei Ansatzpunkte für die Validierung sowie Steigerung der Si-
cherheit auf [9, S. 17]. Die folgende Darstellung gibt einen Überblick über Maßnah-
men zur Sicherheitsdefinition:
Abbildung 1. Tätigkeiten im Security-Engineering je Entwicklungsphase
(in Anlehnung an [1] sowie [9])
Definition DesignImplement-
ierungTest Betrieb ReaktionTraining
· Schutzbedarfs-feststellung
· Missbrauchs-szenarienerstellen
Fachabteilung / Business Analyse
Entwicklung Anwendungs-betrieb
· SystematischeSchulung allerProzessbe-beteiligten
· Risiko-analyse
· Security bydesign
· Code-Review
· Toolunter-stützung
· Penetrationstest
· Fuzzy-Testing
· Erstellung vonNotfallplänen
· Monitoring
· regelmäßige Systemupdates
· Ausführung vonNotfallplänen
Die Fähigkeit aller am Prozess der Anwendungsentwicklung beteiligten Personen
Sicherheitsrisiken einzuschätzen und geeignete Maßnahmen zu ergreifen, soll durch
regelmäßige Schulungen gewährleistet werden. Für die einzelnen Rollen in einem
Web-Projekt müssen entsprechend spezifische Schulungen vorgesehen sein [9, S. 7].
Bereits in der Definitionsphase des Projekts müssen dann Einsatz- als auch Miss-
brauchsszenarien definieren werden. Je klarer bereits in dieser Phase das Bild des
potenziellen Missbrauchs ist, desto besser kann der Entwickler im grundlegenden
Entwurf der Anwendung darauf reagieren. Zusammen mit den Informationen aus
Schutzbedarfs und Risikoanalyse ergibt sich daraus Sicherheit auf Grundlage des
Anwendungsdesigns. Später im Projektverlauf stattfindende Sicherheitsreviews ge-
währleisten, dass die so definierten Richtlinien auch eingehalten werden [1, S. 122].
Die Entwicklungsphase können Werkzeuge begleiten, die neben der Qualität auch
die Sicherheit erhöhen. Grundlage für die Entwicklung bilden Secure Coding Guide-
lines [1, S. 122]. Ein Beispiel, wie toolgestützt die Einhaltung dieser Richtlinien for-
ciert werden kann, zeigt Microsoft. Jedes Dokument durchläuft dabei einen Validie-
rungsprozess, der verhindert, dass Quellcode, welcher gegen die Designrichtlinien
verstößt, eingecheckt werden kann [9, S. 8]. Ein Code Review wäre für kleinere oder
nicht so schutzbedürftige Anwendungen sicher über das Ziel hinausgeschossen [9, S.
12], aber die stichprobenartige oder auf einige neuralgische Punkte beschränkte ge-
zielte Inspektion von Code-Teilen, zu nennen ist hier insbesondere der Bereich der
Datenvalidierung, kann auf effiziente Weise potenzielle Sicherheitslöcher frühzeitig
ans Licht bringen [1, S. 122].
Penetrationstests sowie Fuzzy-Tests vor der Produktivschaltung schließlich runden
diese Maßnahmen ab. Da niemals die hundertprozentige Sicherheit erreicht werden
kann, macht es Sinn, in der Testphase Notfallpläne zu erstellen. Klare Anweisungen
und Verfahrensweisen sollen Regeln, was passiert, wenn tatsächlich Sicherheitslü-
cken entdeckt beziehungsweise bereits ausgenutzt wurden. Der Lösungsprozess soll
damit wesentlich beschleunigt werden [9, S. 11].
Für den Betrieb wichtig ist eine systematische Systemüberwachung. Intrusion De-
tection Systeme können hier wertvolle Dienste erweisen. Zusätzlich muss auch si-
chergestellt werden, dass eingesetzte Software immer aktuell bleibt und regelmäßig
Updates eingespielt werden. Wichtig können auch Sicherheitshinweise von außen
sein. Von Benutzern gefundene Schwachstellen müssen direkt zur Sicherheitsabtei-
lung gelangen [1, S. 122].
2.3 Ebenen der Sicherheit von webbasierten IT-Verfahren
Eine ganzheitliche Betrachtung der Sicherheitsaspekte einer Webanwendung lässt
sich auf unterschiedliche Ebenen durchführen [10, S. 10]. Eine Unterteilung macht
Sinn, da die Anforderungen an die Sicherheitskonzeption sowie Realisierung sich
fachlich sowie organisationstechnisch auf den einzelnen Ebenen unterscheidet. Im
Hinblick auf eine systematische Herangehensweise veröffentlicht das Bundesamt für
Sicherheit in der Informationstechnik ein Ebenenmodell [10, S. 10], welches der Aus-
gangspunkt der Überlegungen für eine effektive Absicherung von Rails Applikationen
darstellen soll. Insgesamt unterscheidet das Ebenenmodell sechs verschiedene Teil-
ebenen.
Tabelle 2. Klassifizierung von Schwachpunkten von Webanwendungen in Ebenen [10, S. 9]
Ebene Inhalt und Beispiele
5 Semantik Schutz vor Täuschung und Betrug:
─ Informationen ermöglichen Social Engineering-Angriffe
─ Gebrauch von Popups erleichtern Phishing-Angriffe
─ Keine Absicherung für den Fall der Fälschung der Website
4 Logik Absicherung von Prozessen und Workflows als Ganzes:
─ Verwendung unsicherer Email in einem gesicherten Workflow
─ Angreifbarkeit des Passworts durch nachlässig gestaltete
"Passwort vergessen"-Funktionen
─ Die Verwendung sicherer Passworte wird nicht erzwungen
3 Implement-
ierung
Vermeiden von Programmierfehlern:
─ Cross-Site Scripting
─ SQL-Injection
─ Session Riding
2 Technologie Richtige Wahl und sicherer Einsatz von Technologie:
─ unverschlüsselte Übertragung sensitiver Daten
─ Dem Schutzbedarf angemessene Authentifizierungsverfahren
─ Ungenügende Randomness von Token
1 System Absicherung der auf der Systemplattform eingesetzten Software:
─ Fehler in der Konfiguration des Applikationsservers
─ Bekannte Fehler in den eingesetzte Softwareprodukten
─ Mangelnder Zugriffsschutz in der Datenbank
0 Netzwerk
und Host
Absicherung von Host und Netzwerk
Die semantische Ebene umfasst dabei alle inhalts- und kommunikationsbezogene
Aspekte. Sie stellt den Vertrauenskontext für die Interaktion mit einem Benutzer her.
Wird in diesem Bereich nicht ein hohes Maß an Sorgfalt aufgewendet, so kann eine
Webanwendung von Dritten missbraucht werden, um einen Benutzer zu täuschen.
Dieser Bereich kann selten auf eine einzelne Anwendung beschränkt bleiben. Viel-
mehr ist eine Webseiten- oder unternehmensübergreifende Betrachtung notwendig.
Zuständig für die Sicherheitsdefinition in diesem Bereich sind die Fachabteilungen
sowie die Geschäftszentrale. Meist wird durch ein Corporate Design für die Entwick-
lung bereits ein klarer Rahmen vorgegeben [10, S. 10].
Die vierte Ebene betrifft sowohl die Logik der Abläufe innerhalb einer Weban-
wendung als auch die Interaktion mit dem Benutzer. Ist eine zu zweckorientierte De-
finition vorgenommen worden, kann dies von Angreifer ausgenutzt werden. Wird
etwa zur Verhinderung von Brute-Force Angriffen nach dem fünften fehlerhaften
Login-Versuch die entsprechende Benutzerkennung gesperrt, so sind Angriffe denk-
bar, bei denen Dritte Benutzer gezielt aussperren. Ziel muss es sein, dass in der Pla-
nungs- und Konzeptionierungsphase die definierten Prozesse systematisch auf Miss-
brauchsszenarien untersucht werden [10, S. 10].
Die Bedeutung der logischen und semantischen Ebene wird vielfach nur unzu-
reichend wahrgenommen. Dennoch haben diese beiden Ebenen eine hohe Bedeutung,
wenn man unter der Sicherheit einer Webanwendungen nicht alleine nur den Schutz
der auf einem Server bereitgestellten Rails Applikation versteht, sondern wie in Kapi-
tel 2.1 dargestellt, auch den Schutz aller Beteiligten. Auf der Ebene der Logik und der
Semantik kommt dieser Aspekt ganz besonders zum Tragen.
Die Implementierungsebene umfasst den Bereich der unbeabsichtigten Program-
mierfehler, aber auch nicht vorhandene oder ungenügende Prüfung von Eingabedaten.
Diese Ebene beinhaltet ferner ungenügende Testverfahren und die Vernachlässigung
der Qualitätssicherung zugunsten der Einhaltung von Meilensteinen beziehungsweise
des Projektbudgets. Verantwortlich für die Herstellung der notwendigen Qualität in
diesem Bereich ist der einzelne Entwickler [10, S. 10].
Die vorletzte Ebene betrifft die Verwendung der für den jeweiligen Einsatzzweck
und Schutzbedarf richtigen Technologie, sowie deren korrekte Nutzung. So zum Bei-
spiel setzt eine Webanwendung, die sensible Daten unverschlüsselt über das Internet
transferiert, nicht die richtige Technologie ein. Eine Webanwendung, die Passworte
zwar verschlüsselt, dafür aber einen zu kurzen Schlüssel verwendet, setzt die richtige
Technologie falsch ein [10, S. 10].
Die nächste Ebene, auch Systemebene, betrachtet all jene Programme, die für das
Funktionieren der gesamten Webanwendung benötigt werden. Dazu gehören der
Webserver und der Applikationsserver, aber auch Datenbank- und Backend-Systeme.
Diese Komponenten müssen bei der Sicherheitskonzeption einer Webanwendung mit
einbezogen werden [10, S. 10].
Die Ebene von Netzwerk, Server-Hardware und darauf laufendem Betriebssystem
wird hemäß dem Bundesamt für Sicherheit in der Informationstechnik nicht direkt der
Sicherheit der Webanwendung zugeordnet. Diese Ebene schließt sich vielmehr nach
unten an. Die Umsetzung grundlegender Sicherheitsmaßnahmen auf dieser Ebene
wird gleichwohl als zwingende Voraussetzung für sichere Webanwendungen betrach-
tet [10, S. 10].
Im Mittelpunkt dieser Projektarbeit stehen die Ebenen zwei, drei und vier des
Klassifizierungsschemas des BSI. Detailliert dargestellt werden nur diese Phasen, da
diese abhängig von der eingesetzten Technologie beziehungsweise den eingesetzten
Entwicklungsframework darstellbar sind. Selbstverständlich müssen bei Webprojek-
ten im Rahmen eines vollständigen Security Engineering Ansatzes die restlichen Ebe-
nen auch betrachtet werden, jedoch können diese generisch und unabhängig von Ruby
on Rails umgesetzt werden.
3 Sicherung der Systemebene
3.1 Konfiguration des Webservers
Bevor die sichere Implementierung einer Webanwendung betrachtet wird, ist die zu-
grundeliegende Infrastruktur vor beabsichtigten sowie unbeabsichtigten Angriffen
abzusichern. Im Rahmen des dritten Kapitels wird dieser Bereich insofern detailliert
betrachtet, dass die Spezifika von Rails Anwendungen herausgearbeitet werden.
Der Webserver nimmt als Kontaktpunkt mit dem Benutzer hierbei eine wichtige
Rolle ein. Zum Entwickeln und Testen bietet sich der zum Ruby-Paket gehörende
Webserver WEBrick als Applikationsserver an. Für den produktiven Einsatz wird
hingegen abgeraten, diesen einzusetzen, bietet er doch eine zu schlechte Performance
sowie nur geringe Konfigurationsmöglichkeiten. Empfohlen wird für den Einsatz in
Produktivumgebungen ein mächtiger Server wie der Apache HTTP Server, NGINX
oder Lighttpd. Voraussetzung zur Anbindung eines Webservers an Ruby on Rail ist
die Unterstützung von FastCGI oder traditionelles CGI. Eine relativ moderne Form,
die in den Foren immer weitere Popularität erfährt, ist Phusion Passenger. Dies auch
als mod_rails bezeichnete, eine proprietäre Schnittstellentechnologie die vor allem
das Deployment von Webseiten wesentlich vereinfacht.
Grundsätzlich ist jeder der oben genannten Webserver immer in Bezug auf Benut-
zerkennung, Zugriffsrechte auf Prozesse, Verzeichnisse und Dateien, Fehlerausgaben
und Protokollierung sicher zu konfigurieren. Folgende Tabelle kann eine sehr gute
Übersicht über die durchzuführenden Rechte haben [10, S. 9]:
Tabelle 3. Berechtigungskonfiguration des Webservers am Beispiel Apache HTTP [11, S. 25]
Zu schützendes Objekt Besitzer (user:group) Rechte
Binärverzeichnisse des Servers root:root 755 (rwxr-xr-x)
Binärdateien, beispielsweise httpd root:root 511 (r-x--x--x)
Konfigurationsverzeichnisse-/dateien root:root 755 (rwxr-xr-x)
Logverzeichnisse-/dateien root:root 700 (rwx------)
Verzeichnis der Rails Applikations,
normalerweise in /var/www/
apache:apache 500 (r-x------)
Rails Log- und Temporäre Verzeich-
nisse und Dateien
apache:apache 700 (rwx------)
Wie in der Tabelle herausgestellt wird, sollen als Besitzer der allgemeinen System-
verzeichnisse der Root-User verantwortlich sein. Jedoch ist für die Ausführung des
Webservers ein eigener Benutzer zu definieren. Dieser soll nur die zwingend für die
Ausführung der Webapplikation notwendigen Rechte aufweisen, so dass eine Sicher-
heitslücke im Kontext der Webanwendung anschließend nur geringe Auswirkungen
auf das Gesamtsystem hat.
3.2 Konfiguration der Datenbank
Die meisten Webanwendungen haben die Anforderung, eine Vielzahl an Daten anzu-
zeigen, zu erfassen, zu verarbeiten und je nach Anforderung auch zu löschen. Daten-
banken, die für diesen Zweck eingesetzt werden, können in Ruby on Rails genau zu
diesem Zweck mit Hilfe des objektrelationalen Mapper ActiveRecord angesprochen
werden. Das Release 3.0 von Ruby on Rails ermöglicht zudem, alternative objektrela-
tionale Mapper wie Sequel oder DataMapper zu nutzen [12]. Jeder einzelne Objektre-
lationale Mapper bietet darüber hinausgehend wiederum Unterstützung für eine Viel-
zahl an Datenbanksysteme wie MySQL, IBM DB2, CouchDB und viele mehr an.
Beispielhaft soll auf die weit verbreitetste Kombination in Ruby on Rails, ActiveRe-
cord in Kombination mit MySQL, näher eingegangen werden.
Eine sichere Konfiguration von Datenbanken erfordert laut dem Bundesamt für Si-
cherheit in der Informationstechnik, dass einerseits die generellen Regelungen zur
Ausführung von Diensten eingehalten werden müssen. Zusätzlich sollen speziell für
Datenbanken „Benutzerkennungen sowie Zugriffsrechte auf Datenbanken, Tabellen,
Stored Procedures sowie Tabelleninhalte sicher konfiguriert werden“ [10, S. 87].
Diensteeinrichtung. Verzeichnisse und Dateien des Datenbankservers MySQL müssen so eingerichtet
sein, dass nur autorisierte Benutzer Zugriff auf das System haben. Zu empfehlen ist
hierbei, dass pro eingerichteten Dienst auf einem Computer jeweils ein eigener Be-
nutzer inklusive Zugriffsgruppe konfiguriert wird. Dies verhindert, dass ein Sicher-
heitsproblem in einer Anwendung Auswirkungen auf andere ebenfalls auf dem Sys-
tem laufende Dienste hat [10, S. 75]. Idealerweise ist es daher so, dass für die Ausfüh-
rung der Datenbank ein Benutzer, beispielsweise mit der Bezeichnung MySQL inklu-
sive der Benutzergruppe MySQL eingerichtet wird.
Nach Installation von MySQL sollen die Berechtigungen für Verzeichnisse inklu-
sive Konfigurationsdateien so vergeben werden, dass nur Benutzer der Gruppe
MySQL lesen sowie schreibend zugreifen können. Ein sicheres Passwort für den Be-
nutzer MySQL versteht sich dort selbstverständlich. MySQL sollte anschließend über
das Konfigurationsskript als Dienst eingerichtet werden, und in einem weiteren
Schritt so konfiguriert sein, dass er vom Benutzer MySQL ausgeführt wird.
Benutzerkennungen und Zugriffsrechte. Nach der Installation von MySQL sind mehrere potentiell unsichere Einstellungen zu
bereinigen. Dies kann automatisiert mit Hilfe des Skripts mysql_secure_installation.pl
im Verzeichnis ./bin/ erfolgen [13]. Dieses Skript löscht einerseits die standardmäßig
vorhandene Testdatenbank. Zusätzlich werden alle Datenbankzugänge entfernt, die
ein anonymes Einloggen ermöglichen würden. Für den Root-Zugang muss zusätzlich
ein Passwort bestimmt werden.
Zusätzlich weißt Webers darauf hin, dass der Benutzer Root umbenannt werden
sollte, um Brute-Forcing Angriffe zu verhindern [11, S. 47]. Mit Hilfe des Befehls:
Update user SET user="dbadmin" WHERE user="root";
Anschließend ist für die Anbindung der auf Rails basierenden Webapplikation ein
eigener Rails-User mit eingeschränkten Zugriffsrechten aufzusetzen. Anstelle der
Berechtigung, uneingeschränkt auf die Datenbank zuzugreifen, werden nur die Rechte
dem Benutzer zugestanden, die üblicherweise bei der Verarbeitung von Webanwen-
dungen benötigt werden [11, S. 47]. Folgender Befehl setzt die korrekten Werte:
CREATE USER 'Rails'@'localhost' IDENTIFIED BY '%QW83XZ';
GRANT DELETE, INSERT, SELECT, UPDATE ON RAILS_DEV.* TO
'rail'@'localhost';
Wird Rake für die Ausführung von Migrationsskripten verwendet, kann ein entspre-
chend zweiter User konfiguriert werden, der Rechte für die Erzeugung, Löschung und
Änderung von Datenbanktabellen hat.
3.3 Einsatz von Anwendungsfirewalls
Neben der Tatsache, dass auch bei der Weiterentwicklung der Anwendung eine inhä-
rente Sicherheitsstrategie verfolgt werden muss, ist es meistens technisch sowie fi-
nanziell bei bestehenden Anwendungen schwer möglich, diese sicherheitstechnisch
auf dem aktuellen Stand zu bringen. Einen möglichen Ausweg aus diesem Konflikt
bieten häufig so genannte Web Application Firewalls [14, S. 52]. Diese wird auf dem
Server zwischen der Kommunikation des Browsers mit der Webanwendung geschal-
tet und ist damit für die Webanwendung vollkommen transparent [14, S. 52].
Idee dieser Firewalls ist es, direkt auf dem HTTP-Datenstrom zugreifen zu können,
um schadhafte Inhalte und Muster zu erkennen und diese entsprechend herauszufil-
tern. Fortgeschrittene Produkte gehen hierbei noch einen Schritt weiter und immuni-
sieren HTTP-Anfragen und -Antworten durch Verschlüsselung sensibler Inhalte oder
durch das Hinzufügen von Sicherheitsmerkmalen [14, S. 52].
Das für den Apache-Server und damit ebenfalls für Ruby on Rails Anwendungen
relativ verbreitete Modul mod_security greift zu diesem Zweck auf eine Rules-Engine
zurück, die neben vordefinierten, frei zugänglichen Algorithmen auch das Hinzufügen
von neuen Beschränkungen erlaubt. Die Definition von Regeln mit mod_security wird
dabei immer nach folgendem Prinzip durchgeführt:
SecFilter AUSDRUCK [AKTION]
Sollte ein bestimmter Filter zutreffen, werden die zugehörigen Aktionen zur Ausfüh-
rung gebracht. Aktionen reichen dabei von der Ablehnung der Benutzeranfrage über
Programmaufrufe bis hin zu umfangreichen Fluss-Aktionen, welche die weitere Prü-
fung der einzelnen Filter beeinflussen können [15, S. 2].
Wichtig beim Einsatz von Web Application Firewalls ist die Tatsache, dass Sie ei-
nen zusätzlichen Schutz für Webanwendungen bieten können, jedoch auf keinen Fall
einen Ersatz für die sichere Anwendungsentwicklung, wie Sie beispielsweise in Kapi-
tel 5 beschrieben ist [10, S. 13]. Für alle Bereiche, die sich jedoch verallgemeinern
und auslagern lassen, bieten Web Application Firewalls eine sinnvolle Möglichkeit,
um Entwicklungsdauer und -kosten, auch bei neu zu entwickelnden Anwendungen
[10, S. 13], positiv zu beeinflussen [14, S. 52].
4 Sicherung der Technologieebene
4.1 Verschlüsselung der HTTP-Kommunikation
Secure Sockets Layer ist ein Protokoll zur sicheren Kommunikation zwischen Client
und Server. Es ermöglicht eine hybride Verschlüsselung der Verbindungsinhalte,
gewährleistet die Vollständigkeit und Korrektheit der übertragenen Daten und bietet
darüber hinaus auch die Möglichkeit der Identitätsprüfung aller beteiligten Parteien
durch Verwendung von Zertifikaten [16, S. 3546]. SSL setzt für den Zugriff auf das
TCP-Protokoll auf und kann daher für eine Reihe von Anwendungsprotokollen ge-
nutzt werden. Für die Einrichtung von SSL zur Absicherung des HTTP-Protokolls
sind folgende Schritte durchzuführen [16, S. 3546]:
1. Erzeugung eines privaten Schlüssels für die Zertifikatsgenerierung
2. Erzeugung eines Certificate Signing Requests
3. Beantragung eines Zertifikats bei einer Certificate Authority
4. Konfiguration des Webservers zur Kommunikation via SSL
5. Anpassung der Rails Applikation für die Nutzung von SSL
Für die zur Zertifikatserstellung notwendigen Schritte eins bis drei sei an dieser Stelle
auf die einschlägige Literatur verwiesen (siehe hierzu beispielsweise [17]). Diese
Schritte können unabhängig von dem genutzten Anwendungsframework und damit
Ruby on Rails vorgenommen werden.
Auch die Konfiguration des eingesetzten Webservers ist nicht generell für Ruby on
Rails darstellbar, wichtige Grundlage jedoch für die Anbindung von Rails. Da bereits
in Kapitel 3.1 die sichere Konfiguration des Webservers Apache vorgestellt wurde,
wird an diesem Anwendungsfall angeknüpft. Für die Nutzung von SSL in einem
Apache Server kann das Modul mod_ssl in Kombination mit der Bibliothek OpenSSL
genutzt werden. Im Standard hört der Apache Webserver auf den Port 80, um einge-
hende HTTP-Verbindungen zu ermitteln. HTTPS verwendet jedoch Port 443, so dass
eine Erweiterung der Konfigurationsdatei httpd.conf durchgeführt werden muss [17]:
<VirtualHost *:443>
Include conf/apps/domainname.conf.common
SSLEngine On
SSLCipherSuite RSA:!EXP:!NULL:+HIGH:+MEDIUM:-LOW
SSLCertificateFile conf/domainname.com.crt
SSLCertificateKeyFile conf/domainname.key
RequestHeader set HTTP_X_FORWARDED_PROTO 'https'
</VirtualHost>
Hierbei wird ein zusätzlicher VirtualHost aufgenommen. Durch die Angabe von
*:443 wird definiert, dass unabhängig der Ziel IP-Adresse alle Anfragen auf dem Port
443 im Rahmen dieses Hosts verarbeitet werden sollen. Im obigen Beispiel wurde
durch eine Include-Anweisung die Konfiguration des Webservers, das heißt bei-
spielsweise die Anbindung von Phusion Passenger sowie optionale mod_rewrite Re-
geln, ausgelagert. Dies macht bei einem Parallelbetrieb von HTTPS sowie HTTP
Sinn, da die gleiche Konfigurationsdatei dann auch im Virtuellen Host Eintrag von
HTTP verwendet werden kann. Anschließend erfolgt die Konfiguration von SSL.
Neben der Definition, dass die SSLEngine für diesen Eintrag genutzt werden soll,
werden auch die zu verwendenden Verschlüsselungsalgorithmen definiert. Zusätzlich
ist mit Hilfe von SSLCertificateFile sowie SSLCertificateKeyFile der Ablageort des
Zertifikats sowie der private Schlüssel festzulegen [17].
Der letzte Konfigurationsparameter ist von besonderer Bedeutung. Mit Hilfe von
RequestHeader set HTTP_X_FORWARDED_PROTO 'https' wird jedem HTTP-
Request ein zusätzlicher Parameter hinzugefügt, so dass die Information, ob die An-
frage per HTTP oder HTTPS gestellt wurde, in Ruby on Rails ausgewertet werden
kann. Dies ist besonders dann sinnvoll, wenn nicht die gesamte Webanwendung per
HTTPS bereitgestellt werden soll, sondern nur die Bestandteile, die wirklich schüt-
zenwert sind. Klar ist, dass die Ver- und Entschlüsselung sowie das komplizierte
Handshacking die Webanwendung insgesamt verlangsamt [18].
Mit der Version 3.1 von Ruby on Rails ist implizit die Middleware-Komponente
Rack::SSL zur Anbindung von HTTPS integriert. Alternativ kann für Applikationen
basierend auf Ruby on Rails kleiner als 3.1 dieses Plug-in manuell eingebunden wer-
den [19]. Unter Nutzung dieser Komponente ist es möglich, aufbauend auf den im
Apache vorgenommenen Konfigurationen, die Verwendung von SSL durch den Cli-
ent vorauszusetzen. Eine solche Konfiguration kann einerseits in der Datei con-
fig/application.rb stattfinden, so dass anschließend Anfragen alleinig per SSL ermög-
licht werden. Soll der Einsatz von SSL jedoch granularer geschehen, so ist es zusätz-
lich möglich, auch auf Ebene der einzelnen Controller beziehungsweiße Aktionen
eine Definition durchzuführen [19].
# Erweiterung der Datei config/application.rb
config.force_ssl = false
# Anpassung der einzelnen Actions
class ForceSSLController < ActionController::Base
force_ssl :except => :index
def index
...
end
Ergebnis der Konfiguration ist, dass Anfragen, falls nicht per HTTPS gestellt, umge-
leitet werden. Bei der Verwendung von SSL ist herauszustellen, dass wie bei jeder
größeren Änderung der Serverkonfiguration ein umfangreicher Applikationstest not-
wendig wird. So sind Seiteneffekte, beispielsweise bei der Einbindung von externen
Inhalten zu erwarten. So warnt beispielsweise der Internet-Explorer davor, wenn
nicht-geschützter Inhalt in eine HTTPS Seite eingebunden wird. Ebenso sind AJAX-
basierte Komponenten nicht nutzbar, wenn sie nicht ebenfalls über HTTPS zur Ver-
fügung stehen [17].
4.2 Verschlüsselung bei Nutzung einer Datenbank
Wie in Kapitel 3.2 dargestellt können Maßnahmen auf Systemebene ergriffen werden,
um Datenbanken vor unberechtigten Zugriffen zu schützen. Die hundertprozentige
Sicherheit, dass Unberechtigte den Zugriff auf die Datenbank nicht doch erhalten,
kann jedoch nie ausgeschlossen werden. Aus diesem Grund macht es Sinn, Daten, die
einen zusätzlichen Schutz bedürfen, zusätzlich verschlüsselt zu speichern. So schreibt
beispielsweise der ein von vielen Kreditkarteninstituten unterstützte PCI DSS Stan-
dard klare Regelungen vor, wie Kreditkarteninformationen zu verarbeiten sind [20].
Eine verschlüsselte Ablage dieser sensiblen Informationen wird explizit gefordert.
Generell kann bei der Verschlüsselung von Datenbankzugriffen unterschieden
werden zwischen der Verschlüsselung der in einer Datenbank gespeicherten Informa-
tionen sowie der Verschlüsselung von Daten während der Übertragung zwischen
Datenbank und Applikationsserver.
Verschlüsselung von Datenbankinhalten.
Für die Verschlüsselung einzelner Feldinhalte auf Datenbankebene ist eine beson-
ders elegante Methode das GEM attr_encrypted. Anstelle selbstständig die Ver- und
Entschlüsselung in eigenen Funktionen bereitzustellen, wird nach Installation dieses
GEM die Möglichkeit gegeben, direkt im Model der Anwendung durchgängig zu
definieren, welche Spalten verschlüsselt werden. Dies wird über attr_accessors gere-
gelt [21]. Folgende Definition würde zur Verschlüsselung von Kreditkartendaten in
der Datenbank führen:
class CreditCar < ActiveRecord::Base
attr_accessible :creditcardnumber, :limit
attr_encrypted :creditcardnumber :key => 'SECURE_KEY'
end
Alle Datenbankzugriffe auf die Spalte creditcardnumber erfolgen nun verschlüsselt.
Selbst wenn der Anwender Zugriff auf die Datenbank hätte, würde er damit keine
Möglichkeit besitzen, an die geschützten Inhalte zu gelangen. Für die Verschlüsse-
lung der Feldinhalte setzt attr_encrypted auf OpenSSL auf und unterstützt damit eine
große Anzahl von Verschlüsselungsalgorithmen. In der Vorkonfiguration ist dies AES
256 [21].
Wesentlicher Vorteil von attr_encrypted ist die Transparenz für den Anwendungs-
entwickler. In der Programmierung unterscheiden sich geschützte Feldinhalte nicht
von ungeschützten Feldinhalten. Mit den Standard Accessor wird der Klartext zu-
rückgegeben, erst mit Verwendung von encrypted_password kann auch der verschlüs-
selte Feldinhalt abgefragt werden. Damit ist auch die Grundlage geschaffen, beste-
hende Applikationen hierdurch zu schützen.
Verschlüsselung der Datenübertragung. Der zweite Aspekt, nämlich die verschlüsselte Datenübertragung zwischen Datenbank
und Applikationsserver, ist mit Hilfe von Rails im Standard ebenfalls möglich. Vo-
raussetzung hierfür ist, dass sowohl die Datenbank wie auch der eingesetzte Daten-
bankadapter die Verschlüsselung unterstützt. Beides ist bei der Verwendung von
MySQL und ActiveRecord gegeben. Weiter ist festzustellen, dass eine Verschlüsse-
lung der Datenkommunikation zwischen Applikationsserver und Datenbankserver nur
dann sinnvoll ist, wenn die Kommunikation über öffentliche Netzwerke erfolgt. Sollte
der Datenbankserver sowie die Applikationsserver in einem gemeinsamen geschütz-
ten Rechennetz sich befinden beziehungsweise auf einen gemeinsamen Server betrie-
ben werden, so ist auch kein weiterer Schutz notwendig.
Für die Verschlüsselung der Datenkommunikation wird das in Kapitel 4.1 bereits
vorgestellte SSL Protokoll eingesetzt. Um SSL zu nutzen muss einerseits der Daten-
bankserver für die Kommunikation via SSL vorbereitet werden, andererseits aber
auch die Rails-Applikation erweitert werden. Für die Anpassung der Rails-
Applikation müssen die Konfigurationseinstellungen zum Zugriff auf die Datenban-
ken in der Datei ./config/Database.yml erweitert werden [22].
sslca: /path/to/rails/app/db/cacert.pem
sslkey: /path/to/rails/app/db/mysql-client-key.pem
sslcert: /path/to/rails/app/db/mysql-client-cert.pem
Hierdurch wird den Datenbankadapter einerseits mitgeteilt, was der öffentliche
Schlüssel der MySQL Datenbank ist sowie die Zertifikate für die Certification Autho-
rity sowie das Zertifikat des Clients bekannt gegeben. Für die Anpassung des Daten-
bankservers MySQL zur Unterstützung von SSL sei auf die einschlägige Literatur
verwiesen (vergleiche beispielsweise [23]). Ein weiterer wesentlicher Vorteil dieser
Konfiguration ist, dass Angreifer ohne Kenntnis der Verschlüsselungsparameter nicht
in der Lage sind, eine erfolgreiche Verbindung aufzubauen. Ein zusätzlicher Schutz
vor Kompromittierung eines Datenbankservers ist damit erzielbar.
4.3 Usermanagement
In nahezu jedem Projekt ist es notwendig, ein Benutzer- und Rechtekonzept zu pfle-
gen und zu warten. Da unterschiedlichste Anforderungen hinsichtlich Umfang sowie
Komplexität dieses Themenbereichs existieren, kann keine Einheitslösung vorgestellt
werden. Eine Vielzahl an Plug-Ins wie das sehr bekannte Authorization_Plugin
(https://github.com/DocSavage/rails-authorization-plugin/) aber können im Internet
gefunden und je nach Projektanforderung genutzt werden.
Nichts desto trotz bietet Rails und hier vor allem Versionen größer als 3.1 ebenfalls
Möglichkeiten, dieses Thema bereits im Standard effektiv anzugehen. Die einfachste
Möglichkeit einen Schutz einzelner Programmbestandteile sicherzustellen wird in
Rails durch die Methode http_basic_authenticate_with geboten. Diese kann im Kopf
eines jeden Controllers eingesetzt werden, und fordert bei Aufruf dem Benutzer dazu
auf, sich entsprechend am System zu authentifizieren [24]:
http_basic_authenticate_with :name => "User", :Password => "Po“
Als Grundlage für die Authentifizierung wird dabei das im RFC 2617 spezifizierte
Basic- und Digest-Authentifizierungsverfahren verwendet [24, 25].
Eine weit elegantere Möglichkeit, die neu in Rails 3.1 hinzugekommen ist, stellt
die Methode has_secure_password dar, die in Klassen abgeleitet vom Typ ActiveRe-
cord::Base bereitsteht [26]. Voraussetzung für die Verwendung ist, dass ein Model
erstellt wird, dass eine Spalte mit der Bezeichnung password_digest aufweist. Fol-
gender Befehl erstellt eine Tabelle für Benutzer:
Rails g model user email:string password_digest:string
Im so erzeugten Model kann anschließend definiert werden, dass in dem entsprechen-
den Feld ein geschütztes Passwort abgespeichert wird:
class User < ActiveRecord::Base
has_secure_password
validates :password, :presence => { :on => :create }
end
Die Auswirkungen dieser Änderung sind umfassend. Konkret wird durch diese Defi-
nition folgende Elemente festgelegt [26]:
1. Neuer Attr_Accessor :password
2. Confirmation Validator auf dem Attribut :password
3. Presence Validator auf dem Attribut :password
4. Automatische Verschlüsselung des Attributs :password durch Nutzung von bcrypt-
ruby falls :password gesetzt wird
5. Neue Methode authenticate, welche eine Überprüfung des unverschlüsselten Pass-
worts ermöglicht.
Anschließend kann im Controller über Anfrage von u-
ser.authenticate(params[:password]) die Korrektheit der Benutzereingabe überprüft
werden. Durch diese neu geschaffenen Möglichkeiten lassen sich Authentifizierungs-
konzepte auch ohne die Einbindung von Drittsoftware relativ einfach umsetzen.
4.4 Schutz von Cookie-Informationen
Mit einem Cookie kann man auf dem System des Web-Browsers Informationen in
Form von Strings als Schlüssel-Wert-Paaren speichern, die der Webserver vorher an
diesen Browser geschickt hat. Die Informationen werden später im Hypertext-
Transfer-Protocol-Header wieder vom Browser an den Server geschickt [5]. Der Zu-
griff auf Cookies erfolgt in Rails mit der Klasse ActionController#cookies [27].
Cookies sind grundsätzlich als nicht vertrauenswürdig und damit als unsicher ein-
zustufen. Ein Benutzer ist in der Lage, die auf dem Client gespeicherten Informatio-
nen nach seinen Wünschen zu manipulieren, und damit dem Server falsche Informati-
onen vorzutäuschen. Rails bietet genau für diese Problematiken ab Version 3.0 die
Möglichkeit von signierten und verschlüsselten Cookies, welche in diesem Kapitel
näher betrachtet werden.
Grundsätzlich wird bei Nutzung der Cookies-Variable ein Session-Cookie ange-
legt, das auch nur solange verfügbar ist, wie der Browser geöffnet ist [27]. Mit Been-
digung der Session sind damit alle im Cookie gespeicherten Informationen verloren.
In Rails 3 wird der Prozess der Erstellung dauerhafter Cookies beziehungsweise sig-
nierter Cookies vereinfacht. Folgendes Code-Beispiel stellt die entsprechende Ver-
wendung dar:
# Setzen von Cookies mit einer Laufzeit von 20 Jahren
Cookies.permanent[:last_product_id] = @product.id
# Setzen signierter Cookies
Cookies.signed[:last_product_id] = @product.id
Der Vorteil von signierten Cookies ist, dass eine Manipulation der Cookies durch die
Anwender weitestgehend ausgeschlossen ist, da eine implizite Prüfung auf Korrekt-
heit der Signatur angewandt wird. Zur Verschlüsselung wird auf die Konfigurations-
datei config/initializers/secret_token.rb zugegriffen. Diese Datei wird inklusive des
Geheimnisses Initial bei der Erstellung eines Rails-Projekts generiert. Die Methode
signed kann auch für permanente Cookies genutzt werden [27].
5 Sicherung der Implementierungsebene
5.1 Session Management
Session Management in Ruby on Rails.
Wie das BSI feststellte, ist das Session-Management eine der wichtigsten und prob-
lematischsten Stellen der Sicherheit von Webanwendungen [10, S. 40]. Grundsätzlich
wird dieses bei Webanwendungen notwendig, um seitenübergreifend den Zustand
eines Benutzers nachverfolgen zu können. Anwendungsgebiete für das seitenübergrei-
fende Speichern von Inhalten sind vielfältig, beginnend bei einem Benutzernamen bis
hin zu bei eShops eingesetzte Warenkörbe.
Idee des Session-Managements ist es, dass mit der ersten Anfrage des Clients an
die Webapplikation ein Sitzungsschlüssel erzeugt wird. Dieser wird bei jedem neuen
Kontaktversuch mit dem Server ebenfalls übertragen, so dass eine eindeutige Zuord-
nung einer Anfrage zu einem Benutzer sowie dessen Datenkontext möglich ist. HTTP
als zustandsloses Protokoll wird mit Hilfe des Session-Managements so zu einem
zustandsbasierten Verfahren [5, S. 114]. Die folgende Darstellung zeigt die Initialisie-
rung von Sessions durch Clients:
Abbildung 4. Zuweisung von Sessions zu Clients
:Client :Server
Initiale Serveranfrage
Erzeuge Session
mit Id = H9KYPghAntwort mit Session Id = H9KYPgh
Übertragung Session Id = H9KYPgh
bei jeder weiteren Anfrage
Ein positiver Seiteneffekt der Generierung des Session-Konzepts ist die Tatsache,
dass es sehr einfach dadurch ist, die Authentifizierung des Benutzers am System fest-
zustellen. Anstelle der bei jeder Seitenanfrage neuen Eingabe der Benutzerinformati-
onen, dient die zu einem Client zugewiesene Session-Id implizit auch als Authentifi-
zierungstoken [5, S. 114].
Rails 3.0 übernimmt in der Standardkonfiguration das Session-Management voll-
ständig und für den Anwendungsentwickler weitgehend transparent. Hierfür generiert
Rails einen so genannten Session Identifier, der sowohl am Server wie auch am Client
als Cookie mit der Bezeichnung _session_id gespeichert wird. Der von Rails generier-
te Session Identifier setzt sich zusammen aus einem 32 Byte langen MD5 Hash des
aktuellen Datums sowie der aktuellen Zeit, einem konstanten Wert, der Prozess Id des
Interpreters sowie einem zufällig gewählten Wert zwischen 0 und 1 [11, S. 9].
Zum Zeitpunkt der Erstellung der Projektarbeit kann die von Rails vergebene Ses-
sion Id als sicher angesehen werden. Der MD5 Hashwert ist grundsätzlich mittlerwei-
le als unsicher einzustufen [28, S. 1ff], da die Kollisionsresistenz des Algorithmus
nicht mehr gegeben ist. Diese Schwäche hat jedoch keine Auswirkung auf die Sicher-
heit des in Ruby on Rails verwendeten Session-Konzepts, da die Kollisionsresistenz
bei der Erzeugung eines eindeutigen Authentifizierungstoken nicht relevant ist [11, S.
9].
Für den komfortablen Zugriff auf die zu einer Session zugeordneten Inhalte hält
Rails die Session-Variable bereit. In Ruby on Rails kann mit folgenden Befehlen auf
den Session-Kontext zugegriffen werden:
# Speicherung der eindeutigen Id des Benutzers
session[:userid] = user.id
# Ermittle den Userdatensatz ausgehend von der
# in der Sessionvariablen gespeicherten User Id
@user = User.find(session[:userid])
Die Session-Variable kann grundsätzlich alle Arten von Objekte aufnehmen. Inhalte
der Session-Variable werden in Ruby on Rails in einem so genannten Session Storage
gespeichert. Die Auswahl des Session Storage hat Auswirkungen auf die maximal
abspeicherbare Datengröße, auf das Speicherungsverfahren sowie auf die Sicherheit
der Webanwendung. Zur Verfügung dienen standardmäßig die Klassen ActiveRe-
cord::SessionStore, ActionDispatch::Session::CookieStore [11, S. 11] sowie Action-
Dispatch::Session::CacheStore. Die Einstellung, welche Art von Session-Store ge-
nutzt wird, kann in der Datei config/initializers/session_store.rb definiert werden.
Hierfür sind folgende Einstellungen vorzunehmen:
# Use the database for sessions instead of the cookie-
# based default, which shouldn’t be used to store highly
# configdential information (create the session table
# with “script/rails g session_migration”)
App::Application.config.session_store :active_record_store
Wie bereits der Kommentar innerhalb der Datei session_store.rb andeutet, sollte bei
der Nutzung des Cookie Stores sichergestellt werden, dass vertrauliche Informationen
nicht innerhalb des Session-Objekts abgespeichert werden. Da bei diesem Verfahren
alle Inhalte der Session-Variable unverschlüsselt in einem Cookie auf dem Client
gespeichert werden [11, S. 11], sind Inhalte von Angreifern auslesbar. Bei der Nut-
zung des CacheStores hingegen werden die Inhalte der Session-Variable nicht auf
dem Clientsystem gespeichert, sondern im Cache des Servers. Bei der Nutzung des
Active_Record_Store werden die Inhalte in der Anwendungsdatenbank gespeichert
[29].
Session Hijacking. Die implizite Verwendung der Session-Id zur Authentifizierung eines Benutzers am
System ist sicherheitstechnisch kritisch. Hat ein Angreifer Kenntnis einer aktuell von
einem Benutzer verwendeten Session-Id, so erhält dieser implizit auch Zugang zu
einer Webanwendung inklusive der mit dem Benutzerkontext einhergehenden Rechte
[11, S. 9].
Zur Erlangung der Session-Id eines Benutzers gibt es eine große Anzahl an An-
griffsformen. Eine erste Möglichkeit stellt das Abhören des Netzwerkverkehrs zwi-
schen Client und Server dar. Wird eine Kommunikation zwischen Client und Server
unverschlüsselt vorgenommen, können auch übertragene Session-Ids ausgelesen wer-
den und für einen Angriff genutzt werden. Um diese Möglichkeiten zu vermeiden,
können wie bereits in Kapitel 4.1 dargestellt, eine Verschlüsselung der Datenkommu-
nikation eingeführt werden. Um weitergehend sicherzustellen, dass die Session-Id
immer verschlüsselt übertragen wird, können in der Datei conig/environment.rb fol-
gende Anpassung vorgenommen werden [30]:
# Session-Austausch nur über HTTPS erlauben
ActionController::Base.session_options[:session_secure]=
true
Neben dem sicheren Austausch der Session-Id an sich bietet die Verknüpfung dieser
mit weiteren Merkmalen, wie beispielsweise der IP-Adresse des Systems eine Mög-
lichkeit zur Sicherung der Session [11, S. 9f]. Anfragen eines Rechners mit nicht zur
Session zugeordneten Adressen können so erkannt und abgelehnt werden. Problema-
tisch bei diesen Vorgehen ist jedoch, dass viele Anwender beispielsweise geschützt
durch Proxy-Server auf die Webanwendung zugreifen, so dass möglicherweise einige
Anwender gar nicht oder nur eingeschränkt die Webanwendung nutzen können.
Eine weitere Möglichkeit zur Erlangung einer gültigen Session-Id besteht darin, al-
le möglichen Kombinationen systematisch auszuprobieren, bis eine aktuell aktive
Session-Id gefunden wird [11, S. 9]. Diese in der Praxis auch als Brute-Forcing be-
zeichnete Angriffsform hat in der Praxis jedoch keine Relevanz. Die Anzahl der mög-
lichen Kombinationen an Session-Ids ist zu groß, um einen effektiven Angriff über
das Anwendungsprotokoll HTTP zu erlauben. Für die Generierung des Session Keys
verwendet wie bereits oben dargestellt Ruby on Rails eine Kombination aus mehreren
Werten. Während dieser Session-Key je nach verwendeter Systemeinstellung vor der
Verschlüsselung mit MD5 77 bis 85 Bytes umfasst, stellen nur 24-32 Bytes wirklich
generische Werte dar. Die generischen Bestandteile wie die Uhrzeit, die Zufallszahl
sowie die Prozess-Id sind weitergehend nur Nummern, so dass auch hier der Ergeb-
nisraum weiter eingeschränkt werden muss. Somit ist die Anzahl an möglichen Wer-
ten für einen Angreifer zwischen 1024
– 1032
im Rahmen eines Brute-Forcing Angriffs
zu prüfen [31, S. 53]. Zusammenfassend lässt sich feststellen, dass der Ergebnisraum,
auch unter Beachtung der Schwächen von MD5 sowie der verwendeten Generie-
rungsalgorithmen, aktuell ausreichend ist, um Bruteforcing zu verhindern.
Session Fixation. Anstelle die Session-Id eines Benutzers zu ermitteln, versucht der Angriff der Sessi-
on-Fixation den Sessionschlüssel vor der Anmeldung am System den Benutzer vor-
zugeben [11, S. 13]. Hierzu lässt sich der Angreifer im ersten Schritt von der anzu-
greifenden Webanwendung eine gültige Session-Id zuweisen. Dies geschieht wie
oben beschrieben mit dem ersten Aufruf einer Rails-basierten Webanwendung. An-
schließend versucht der Angreifer die so erhaltene Session-Id dem Opfer zuzuweisen.
Die Zuweisung erfolgt auf dem Client-Rechner zumeist mit JavaScript. Möglichkei-
ten, dem Anzugreifenden eine solchen Java-Script Code unterzuschieben, können mit
Cross-Site-Scripting oder anderen Angriffsformen erfolgen.
<script>
document.cookie="session_id=167832d6206b60f22a03c8d9";
</script>
Gelingt es dem Angreifer, die oben dargestellte Code-Zeile auf dem Client-Rechner
zur Ausführung zu bringen, benutzen sowohl Angreifer wie auch Opfer den gleichen
Session-Kontext. Sollte sich der Anwender nun an die Anwendung anmelden, gehen
auf dem Angreifer alle Rechte des Angemeldeten über. Der Angriff war damit erfolg-
reich.
Eine einfache Möglichkeit um das Problem der Session Fixation zu lösen, kann er-
folgen in dem wie bereits im vorgehenden Kapitel dargestellt in einer Session selbst
weitergehende userspezifische Inhalte wie die IP-Adresse des Aufrufenden zu spei-
chern und diese dann bei jeder Serveranfrage zu validieren. Auch hier ist wiederum
mit Zugriffsproblemen bei Anwender zu rechnen, die Proxy-Server für den Zugriff-
nutzen. Zusätzlich würde das Problem entstehen, dass regulären Anwendern in dem
Moment der Zugriff auf die Anwendung verwehrt wird [11, S. 14].
Die zweite und weit elegantere Möglichkeit Session Fixation zu vermeiden ist nach
der Anmeldung durch den Benutzer diesen automatisiert eine neue Session Id zuzu-
weisen [11, S. 14]. Dies kann durch die Anweisung reset_session, durchgeführt nach
der erfolgreichen Authentifizierung des Benutzers am System, erfolgen. Gefälschte
Sessions werden damit ungültig, der Angreifer hat niemals die Möglichkeit an die
Benutzerrechte des regulären Angreifers zu kommen, da die Zuweisung einer Sessi-
on-Id per JavaScript nach Anmeldung zerstört wird.
Session Expiry.
Ein wichtiges Thema, dass übergreifend für das Session-Management betrachtet wer-
den muss, ist der Verfall von Sessions. Je länger Sessions gültig bleiben, desto größer
ist auch die Gefahr eines erfolgreichen Angriffs. Ziel muss es sein, bei der Verfalls-
zeit von Sessions einen Kompromiss zwischen Sicherheit aber natürlich auch Benut-
zerfreundlichkeit zu erreichen.
Eine erste Möglichkeit, automatisiert Sessions zu beenden, ist das Setzen von ei-
nem Verfallsdatum des Session-Cookies. Dies ist jedoch als problematisch anzusehen,
da auch hier die Möglichkeit der Manipulation durch den Benutzer besteht [31, S. 52].
Besser ist, Sessions auf dem Server zu beenden [31, S. 52]. Da Ruby on Rails keinen
standardisierten Mechanismus hierfür bietet, sind je nach eingesetzten SessionStora-
ge-Verfahren unterschiedliche Vorgehensweisen vorstellbar. Bei Nutzung der Klasse
ActiveRecordStore für die Speicherung von Session-Inhalten, macht es Sinn ein Mo-
del Session zu definieren, dass folgende Methode beinhaltet:
class Session < ActiveRecord::Base
def self.sweep
self.destroy_all(:coditions => ["updated_at < ?",
30.minutes.ago]
end
end
Über einen Task kann dann regelmäßig der Befehl ruby script/runner "Session.sweep"
aufgerufen werden, der alle Sessions, die innerhalb der letzten 30 Sekunden nicht
aktualisiert wurden, löscht. Um weitergehend auch Angriffe durch Session-Fixation
zu verhindern, kann die oben dargestellte Bedingung zum Löschen so erweitert wer-
den, dass ebenfalls Sessions, die vor einem bestimmten Zeitraum erstellt wurden,
ebenfalls gelöscht werden [11, S. 15].
Bei Nutzung andersartiger Speicherverfahren kann ähnlich vorgegangen werden
und eine regelmäßige Löschung der Dateien per Skript erfolgen.
5.2 SQL Injection-Angriffe
Die Injection-Angriffe subsummieren eine Angriffsform, die auf das Einschleusen
von Schadcode in nicht oder nicht ausreichend geprüften Eingaben abzielt. Hierdurch
können Angreifer erreichen, dass der eigene Quellcode im Sicherheitskontext der
Webanwendung ausgeführt wird um Anwendungsfehler auszulösen, Schadcode in-
nerhalb der Anwendung oder auf dem Client auszuführen oder den Anwender auf
fremde Webseiten zu leiten [11, S. 30].
Ein erstes Beispiel für Injection Angriffe zielen auf Sicherheitslücken ab, die aus
dem Zusammenspiel zwischen Anwendung und SQL-Datenbank entstehen. Nahezu
alle Anwendungen nutzen SQL als Abfragesprache für Datenbanken. Die Interaktivi-
tät von Webanwendungen wird erreicht, in dem vorgegebene SQL-Fragmente mit
Benutzereingaben komplettiert werden [14, S. 50]. Durch mangelnde Maskierung
oder Überprüfung von Metazeichen in Benutzereingaben erhält der Angreifer jedoch
die Möglichkeit, über die Anwendung Datenbankbefehle einzuschleusen. Dieses Ein-
schleusen von Code wird als SQL-Injection bezeichnet [5, S. 287 f].
Auch auf Ruby on Rails basierende Webanwendungen machen sich Datenbanken
zu nutzen. Jedoch erfolgt die Kommunikation zwischen Datenbank und Anwendung
zumeist nicht wie gewöhnlich über SQL-Anweisungen direkt, sondern vielmehr er-
folgt die Implementierung von Datenbankabfragen zumeist mit einen objektrelationa-
le Datenmapper wie ActiveRecord. Durch die Kapselung des Datenbankzugriffs wird
implizit ein weitreichender Schutz vor SQL-Injections erreicht, da durch diese Zwi-
schenschicht automatisierte Validierungen der Eingaben durchgeführt werden und
nicht-gültige Zeichen automatisiert gefiltert werden [11, S. 35].
Voraussetzung für den Schutz der Anwendung ist jedoch, dass auf die von Active-
Record zur Verfügung gestellten Methoden wie beispielsweise where oder find auf-
gebaut wird. Übergabeparameter dieser Methoden werden durch Nutzung der Klasse
ActiveRecord::Sanitization automatisiert validiert. Sollten SQL-spezifische Zeichen
wie OR, AND beziehungsweise Kommentarkennzeichnungen wie -- vorhanden sein,
werden diese implizit gefiltert [32].
Sobald jedoch eigene Bedingungen oder ganze SQL-Abfragen selbst definiert wer-
den, muss zwingend eine manuelle Validierung der Parameter durchgeführt werden.
Dies kann durch die bereits oben dargestellte Filterklasse ActiveRecord::Sanitization
geschehen [32]. Folgendes Beispiel zeigt die Implementierung sicherer beziehungs-
weise unsicherer ActiveRecord-Zugriffe [33]:
class User < ActiveRecord::Base
def self.authenticate_unsafe (name, pw)
where("name = '#{ name}' AND pw ='#{pw}'").first
end
def self.authenticate_safe (name, pw)
where("name = ? AND pw = ?", name, pw).first
end
def self.authenticate_safe_simple(name, pw)
where(:name => name, : pw => pw).first
end
end
Im obigen Beispiel ist die Implementierung der Methode self.authenticate_unsafe
anfällig für SQL-Angriffe. Durch direkte Einbindung der Variablen in den Query-
Code versagt die automatische Validierung. Ein Angreifer, der in das Eingabefeld für
den Benutzernamen den Wert ' OR 1)-- einträgt, erhält automatisch Zugriff auf die
Anwendung, da die angegebene Bedienung damit immer wahr ist [33]. Die Methoden
zwei und drei implementieren dieselbe Anforderung auf sichere Art und Weise. An-
stelle der direkten Eingabe der Parameter in die Filterung, werden diese über eine
Parametrisierung mitgegeben. Hier greift die automatische Filterung, SQL-Angriffen
sind nicht möglich.
5.3 Cross-Site Scripting
Bei der Entwicklung von Rails ist festzustellen, dass in den einzelnen Major-Releases
intensiv auch an der Sicherheit des Web-Frameworks gearbeitet wurde. Während mit
dem in Rails 1 realisierten ActiveRecord-Modul ein impliziter Schutz vor SQL-
Injection verfügbar ist, brachte Rails 2 wesentlichen Fortschritt bei dem Schutz vor
Cross-Site Request Forgery. In Version 3 von Rails wurde der Kreis geschlossen und
der Schutz vor Cross-Site Scripting Angriffen, kurz XSS, wesentlich verbessert [34].
Um XSS-Angriffe zu vermeiden, ist ein grundlegendes Verständnis über die Si-
cherheitsstrategien in modernen Browsern notwendig. Die grundlegende Idee zur
Herstellung von Sicherheit in Browsern ist, dass die Ausführung jeglicher Skripte in
so genannten Sandboxes stattfindet. Damit werden unter anderem die Möglichkeiten
eines Skriptes eingeschränkt, auf grundlegende Systemoperationen zuzugreifen. Noch
wichtiger aber ist, dass ein webseitenübergreifender Datenaustausch unterbunden
wird, da pro Webseite eigenständige Sandboxes existieren. Cookie-Informationen,
Session-Ids und weitergehende zu schützende Informationen können damit nur dann
ausgelesen werden, falls Sie auch von der gleichen Webseite erstellt wurden. Dieses
Verfahren wird auch in der Literatur unter dem Begriff Same Origin Policy subsum-
miert [35, S. 276].
Cross-Side Scripting Angriffe zielen nun darauf ab, schadhaften Java-Script- oder
HTML-Quellcode in eine anzugreifende Webanwendung einzubringen und damit
dessen Ausführung im Sicherheitskontext der Webseite zu erzwingen. Im Moment der
Ausführung können diese Skripte dann auf alle Daten des Anwenders in der jeweili-
gen Sandbox der Webanwendung zugreifen [35, S. 276].
Ein Beispiel soll helfen Cross-Side Scripting basierte Angriffe zu verdeutlichen.
Sollte bei der Neuerfassung von Daten durch den Benutzer diese nicht ausreichend
durch die Webanwendung geprüft, sondern direkt verarbeitet und gespeichert werden,
können systematisch Script-Blöcke eingebracht werden. Ein Angreifer, der es schafft,
den folgenden Code durch ein Eingabefeld in eine Webanwendung einzupflegen, wird
die Möglichkeit haben, auf der Webseite evil.com alle Cookieinformationen der An-
wendungsbenutzer auszulesen.
<script>
d = document;
s = d.createElement("script")
s.src = "http://evil.com/payload?d.cookie;
d.body.appendChild(script);
</script>
Die Webseite ist damit kompromittiert. Diese oben beschriebene Angriffsform stellt
einen so genannten persistenten Cross-Side Scripting Angriff dar.
Grundsätzlich sind zwei Typen von Cross-Side Scripting Angriffen praktikabel,
nämlich persistente sowie reflexive Angriffe [35, S. 276]. Reflexive Angriffe haben
pro Ausführung das Ziel, grundsätzlich nur einem einzigen Opfer zu schaden. Dabei
wird der clientseitige Code durch das Opfer selbst an die verwundbare Seite geschickt
und anschließend dieser im Rahmen der Anfrage verarbeitet [35, S. 276f]. Ganz im
Gegensatz hierzu haben persistente Angriffe das Ziel, möglichst viele anonyme An-
wender zu treffen, in dem der Code direkt auf eine verwundbare Seite eingebettet
wird, beispielsweise in dem eine Abspeicherung in der Anwendungsdatenbank er-
folgt. Die Infizierung des Anwenders passiert dann mit dem Laden der Seite durch
das Opfer selbst [35, S. 276f].
Gegenmaßnahmen gegen Cross-Site Scripting sind vielfältig, wobei aber die Praxis
zeigte, dass nur ein relativer Schutz gegen XSS-basierte Angriffe erreicht werden
kann und auch große Webplattformen immer wieder Probleme mit dieser Art von
böswilligen Code haben [36]. Vorkehrungen können einerseits von den Anbietern von
Webanwendungen ergriffen werden, in dem diese systematisch ein- und ausgehende
Daten filtern und verdächtige Elemente entfernen. Andererseits sehen sich aber auch
Browserhersteller in der Verpflichtung, über das Sandbox-Konzept hinausreichende
Sicherheitskonzepte zum Schutz vor XSS zu realisieren [37, S. 1f]. Betrachtet werden
anbei nur die serverseitig zu realisierenden Maßnahmen.
Safe-String Konzept. Wie bereits angedeutet, hat sich der Schutz vor XSS-Attacken ab Ruby on Rails 3.0
wesentlich verändert. Während in älteren Versionen Eingaben explizit durch Verwen-
dung der Methoden escapeHTML() oder h() Daten als unsicher markiert werden
mussten, ist es in Rails 3.0 so, dass grundsätzlich alle Inhalte als unsicher eingestuft
werden, und der Entwickler explizit aufgefordert ist, sichere Inhalte im Rahmen eines
Whitelistings zu kennzeichnen [34].
Grundkonzept bei der Behandlung von XSS in Rails 3.0 ist eine klare Trennung
zwischen sicheren und unsicheren Inhalten. Aus diesem Grund wurde die Klasse Ac-
tiveSupport::SafeBuffer implementiert, welche für die interne Verarbeitung stan-
dardmäßig genutzt wird und sich aus der Klasse String ableitet. Die Methoden +,
concat sowie << wurden überschrieben [38]. Objekte dieser Klasse werden grundsätz-
lich als vertrauenswürdig eingestuft.
Ergebnis dieser Trennung ist, dass grundsätzlich alle Daten, die mit der Klasse
String erstellt werden, automatisch bei der Verkettung oder Anzeige transponiert wer-
den. Hierzu werden für HTML reservierte Zeichen wie < oder > durch das entspre-
chende HTML-Pendant ersetzt, also beispielsweise < beziehungsweise >. Somit
ist es nicht möglich, Fremdcode in Webanwendung zur Ausführung zu bringen[38].
Soll anstelle der Maskierung dem Inhalt vertraut werden und eine automatische
Entfernung von HTML-Spezifischen Tags verhindert werden, so kann dies geschehen
durch Verwendung der neuen Helper-Methode raw beziehungsweise html_safe bei
der Ausgabe. Folgendes Code-Beispiel zeigt die Auswirkung der Verwendung von
raw in einer .erb-Datei, wobei in dem Attribut name der Wert <b>XSS</b> gespei-
chert ist:
<%= booking.name %>
# => Ausgabe in HTML: <b>XSS</b>
<%= raw booking.name %>
# => Ausgabe in HTML: <b>XSS</b>
Die folgende Darstellung gibt ein Beispiel der Konsequenzen dieser Trennung:
Tabelle 5. Konsequenz Verwendung SafeBuffer
Anwendungsfall Erläuterung
1 "XSS".html_safe? Ergebnis: false. Standardmäßig werden alle Objekte
der Klasse String als Nicht-Sicher angesehen
2 xss = "XSS".html_safe
xss.html_safe?
Ergebnis: true. Mit Aufruf der String-Methode
html_safe wird ein SafeBuffer Objekt zurückgeliefert.
Daher gibt die Methode html_safe? auch entsprechend
true zurück.
3 xss = "".html_safe
xss << "<script>"
Ergebnis: "<script>". Als Ergebnis des Aufrufs xss
= "".html_safe wird ein SafeBuffer-Objekt zurückgelie-
fert. Bei der Verknüpfung des SafeBuffers mit einem
Objekt vom Typ String wird eine automatische Erset-
zung ungültiger Zeichen durchgeführt.
Wichtig ist, dass sich die Nutzung des Konzepts von html_safe alleinig auf die An-
zeige selbst bezieht. Eingaben werden nach wie vor ungefiltert abgespeichert und erst
bei der Anzeige konvertiert.
Sanitization. Es gibt immer Anwendungsfälle, bei denen es aber durchaus gewünscht ist, auch eine
weitergehende Formatierung der Benutzereingabe zu erlauben. Um dies zu ermögli-
chen ist für viele Anwendungsfälle die Nutzung des Safe_Buffer Konzepts zu restrik-
tiv. Anstelle einfach alle möglichen HTML-Tags automatisiert zu ersetzen, ist es das
Ziel, eine Filterung der Benutzereingaben durchzuführen und solche Tags zu entfer-
nen, die wirklich Schadcode enthalten können. Um dies auf sichere Weise zu ermög-
lichen, gibt es in Rails den Themenkomplex Sanitization. Konkret zu betrachten sind
hierbei die Klassen Helpers::SanitizeHelper [39] sowie Helpers::TextHelper [40].
Die Klasse TextHelper bietet hierzu die Methode simple_format. Sie entfernt au-
tomatisiert alle möglicherweise gefährlichen HTML-Tags. Nicht gefährliche Tags wie
<b> werden jedoch weiterhin nicht gefiltert und dargestellt. Zusätzlich wird aber auch
für die Textbearbeitung weitergehende Funktionalität angeboten. So wird beispiels-
weise das Tag \n automatisiert in <br/> umgewandelt. Auch die Methode simp-
le_format greift für die Filterung auf die Klasse SanitizeHelper intern zu. Sollten wei-
tergehende Anforderungen bestehen, beispielsweise eine klare Liste an erlaubten
Tags, so ist diese Klasse zu nutzen. Folgendes Quellcodebeispiel soll die Verwendung
der Sanitization Helper noch einmal verdeutlichen:
# Nutzung der Klasse TextHelper für die automatisierte
# Filterung gefährlicher Eingaben
simple_format('<a href="http://test.com/">Test</a>')
# => "<p><a href=\"http://test.com/\">Test</a></p>"
simple_format('<a href="javascript:alert(\No!\)">No</a>')
# => "<p><a>No</a></p>"
# Nutzung von SanitizeHelper für die gezielte Einschränk-
# ung der Tags
sanitize @article.body, :tags => %w(table tr td)
Textile Auszeichnungssprachen. Neben dem oben dargestellten Konzept der Sanitization, also der gezielten Filterung
von Eingaben, gibt es weitergehend auch die Möglichkeiten so genannte Textile Aus-
zeichnungssprachen zum Einsatz zu bringen, die gezielt auf die Verwendung von
HTML-Pattern verzichten und eine eigene Auszeichnungssprachen bereitstellen [11,
S. 42].
Neben den Vorteilen der einfacheren Erlernbarkeit der Auszeichnungssprache für
den Endanwender ist vor allem in Bezug auf die Sicherheit der Vorteil, dass Eingaben
in einen textilen Format an die Webanwendung übertragen werden und damit weiter-
gehend voll auf dem oben dargestellten Konzept der automatisierten Entfernung von
Strings gesetzt werden kann. Prominentestes Beispiel für eine solche Auszeichnungs-
sprache im Ruby-Umfeld stellt RedCloth dar [41], welches ebenfalls über GEM in
Rails eingebunden werden kann. Wichtig beim Einsatz ist jedoch, dass es auch hier
notwendig ist, eine Filterung der Eingaben vorzunehmen, da auch RedCloth in der
Vergangenheit nicht zuverlässig vor XSS geschützt hat [11, S. 42]. Hier kann auf das
SafeBuffer Konzept zurückgegriffen werden.
5.4 Cross-Site Request Forgery
Wie bereits in Kapitel 5.2 dargestellt, handelt es sich bei HTTP um ein zustandsloses
Protokoll. Das Konzept der Sessions in Webanwendungen adressiert dieses Dilemma
und ermöglicht so, seitenübergreifend Daten und Zustände zu speichern. Neben den
oben aufgezeigten Problemen des Session Managements ist das Cross-Site Request
Forgery eine weitere Möglichkeit, den mit dem Sessionkonzept einhergehende Si-
cherheitskontext auszunutzen und dem Anwender bösartige Anfragen unterzuschie-
ben [14, S. 49][42, S. 1]. Cross-Site Scripting wird in der Fachliteratur als ein „Slee-
ping Giant“ eingeschätzt, da Untersuchungen zeigen, dass viele Webseiten anfällig
für Angriffe dieser Art sind [42, S. 1].
Um Cross-Site Request Forgery ganzheitlich zu verstehen, muss zuerst verstanden
werden, wie sich URLs in Ruby on Rails zusammensetzen. In dem Web-Framework
wird das Routing zwischen der einzelnen Serveranfrage sowie den entsprechenden
Servercontroller durch die Datei routes.rb durchgeführt. Die Konvention in Rails sagt,
dass jede Action auch immer auf eine so genannte CRUD-Operation in der Datenbank
weist. Ein Eintrag in der routes.rb wie resources :bookmarks erzeugt damit grundsätz-
lich sieben verschiedene Standard-Routen [43].
Tabelle 6. Standardrouten in Ruby on Rails [43]
HTTP-Verb Path action Beschreibung
GET /bookmarks index Liste aller Lesezeichen
GET /bookmarks/new new Maske zur Erfassung eines Lezei-
chens
POST /bookmarks create Anlage eines Lesezeichens
GET /bookmarks/:id show Anzeige eines Lesezeichens
GET /bookmarks/:id/edit edit Maske zur Editierung eines Lezei-
chens
PUT /bookmarks/:id update Aktualisierung eines Lesezeichens
DELETE /bookmarks/:id destroy Löschung eines Lesezeichens
Mit Hilfe dieser Schemata lassen sich so beispielsweise über Eingabe der URL Daten
abrufen, ändern aber auch löschen. Die Eingabe der URL
http://railsapp.org/bookmarks/3/destroy löscht zum Beispiel einzelne Bookmarks in
der Datenbank. Diese Eigenschaft macht sich nun Cross-Site Request Forgery zu
Nutze, um vom Anwender ungewollte Aktionen auszulösen. Der Ursprung des Auf-
rufs der Seite muss dabei nicht innerhalb der Rails Webanwendung sein, sondern
kann genauso gut in einem parallel geöffneten Browserfenster, beispielsweise durch
einen E-Mail Client geschehen. Für das Unterschieben bösartige Serveranfragen sind
Image-Tags, XSS, Injection, Social Engineering sowie viele weitere Angriffsmög-
lichkeiten vorstellbar.
Anhand eines Beispielszenarios soll nun noch einmal ein möglicher Angriff durch
Cross-Site Request Forgery dargestellt werden:
Abbildung 7. Zuweisung von Sessions zu Clients
:Browser-
fenster 2:Rails Server
Serveranfrage
Erzeuge Session
mit Id = 12345Antwort mit Session Id = 12345
:Browser-
fenster 1
:HTML
Mail Server
Email im HTML-Client abrufen
<html>...<img src:“http://railsapp.org/bookmarks/3/destroy“/>…</html>
Abruf img: http://railsapp.org/bookmarks/3/destroy mit Session Id = 12345
Lösche
Bookmark mit
ID=3
Der Anwender selbst hat zwei Browserfenster geöffnet. Mit dem ersten wird eine auf
Rails basierende Webanwendung geöffnet und eine Session erzeugt. Mit einem zwei-
ten Browser befindet sich der Anwender gerade in einen HTML-basierenden Email-
Client. Über diesen wird eine E-Mail abgerufen, in welcher aber ein Bild eingebunden
ist, dass auf eine URL der Rails-Applikation verweist. Der Browser versucht nun das
Bild abzurufen und schickt automatisch ebenfalls die Session Id an dem Server. Der
Browser hat grundsätzlich keine Möglichkeit zu entscheiden, welche Anfrage gültig
ist oder nicht. Damit befindet sich der Angriff im Sicherheitskontext der Webseite
und eine Löschung, ohne dass es dem Benutzer bekannt ist, von einzelnem Booking-
Ids wird durchgeführt.
Gegenmaßnahmen. Um Angriffe gegen Cross Site Request Forgery entgegenzuwirken, stehen in Ruby on
Rails drei mehr oder weniger effektive Schutzkonzepte zur Verfügung.
Einen mäßigen Schutz bietet die Möglichkeit, anstelle beim Aufruf von Methoden
die Übergabe von Parameter mittels GET zu vermeiden und anstelle immer dann,
wenn kritische Daten zwischen dem Client und dem Server durchgeführt werden
POST-Requests zu verwenden [11, S. 17f]. Idee ist, dass POST-Requests nicht mittels
einer einfachen URL-Einbindung erreicht werden können. Jedoch stellt Webers eben-
falls fest, dass die Nutzung von Post-Variablen keinerlei Schutz an sich bietet, da sich
ebenfalls Post-Anfragen sich programmtechnisch generieren lassen. Damit stellt diese
Schutzmaßnahme nur eine Erschwerung des Angriffs, jedoch keine Verhinderung dar
[11, S. 18].
Eine weitere präventive Maßnahme zur Verhinderung von Cross-Site Request For-
gery ist die systematische Überprüfung aller Controller sowie Actions auf tatsächliche
Verwendung durch den Benutzer. Actions und Controller, die für dem Test sowie der
internen Verarbeitung alleine benötigt werden, sollten nach Möglichkeit durch Ver-
wendung des Keywords protected bei der Methodendefinition nicht von außen auf-
rufbar sein. Für das Debugging oder Unit-Tests einer Rails-Applikation können Ac-
tions durch Verwendung folgender Anweisung auf der Test sowie Produktionsumge-
bung gesperrt werden:
if (ENV['RAILS_ENV'] == 'development') then
#Nur auf der Entwicklungsumgebung aufrufbarer Code
end
Für den effektiven Schutz der Webanwendung vor CSRF bietet Ruby on Rails ein
interessantes Feature, welches in Version zwei eingeführt wurde und in Version 3 nun
standardmäßig auch aktiviert ist [44]. Dieses Feature kann, bei konsistenter Anwen-
dung, das Problem des Cross-Site Request Forgery weitgehend lösen. Über die Anga-
be des Parameters protect_from_forgery im Application Controller wird ein Session-
Token erzeugt, dass benutzerindividuell aus der Session-Id sowie einen Serverseitigen
Schlüssels generiert wird.
Ziel dieses Tokens ist, dass alle mit Ruby on Rails generierten Formulare ein ver-
stecktes Feld beinhalten, in welcher diese eindeutige Kennzeichnung hinterlegt ist.
Auf dem Server angekommen, wird dieser Schlüssel mit dem ursprünglich für diese
Anfrage definierten Parameter abgeglichen und falsche Anfragen mit einer Exception
vom Typ ActionController::InvalidAuthenticityToken abgelehnt. Ab Version 3.0.4
führt Rails anstelle einen Fehler zu werfen implizit ein session_reset() aus [45]. Zu
erwähnen ist, dass beispielsweise Ajax-Aufrufe oder Webservices ebenfalls hierdurch
geschützt werden [44].
5.5 Mass-Assignment
Das so genannte Mass-Assignment ist ein hilfreiches Feature in Ruby-On-Rails, um
einem Objekt alle benötigten Attribute auf einmal zuzuweisen. Dies kann vor allem
dann eingesetzt werden, wenn beispielsweise bereits zur Instanziierung eines Active
Record Modells eine Vielzahl an Attributen gewünschten Attribute aus den Request
Parametern übergeben werden [11, S. 25]. Mit Hilfe von Mass-Assignment in Ruby
on Rails kann beispielsweise aufbauend auf den oben dargestellten Beispielen folgen-
dermaßen durchgeführt werden:
# Methode zur automatisierten Anlage eines Bookmarks
# unter Nutzung des Mass-Assignment
def create
@bookmark = Bookmark.new(params[:bookmark])
...
end
Oben genannte Zeile kann aber durchaus problematisch gesehen werden. Geht man
davon aus, dass manipulierte Anfragen sowohl per GET- wie auch POST an die An-
wendung übermittelt werden können, so könnten von einem Angreifer ebenfalls ohne
Probleme das Mass-Assignment genutzt werden, um Datensätze und Felder, die aus
sicherheitstechnischen Anforderungen eigentlich nicht für die Bearbeitung durch den
Nutzer vorgesehen sind, bearbeitet werden [11, S. 25].
Die Erkenntnis aus dieser Problematik ist, dass ein Angreifer durch das Mass-
Assignment Felder bearbeiten kann, die ihm so nicht zugestanden sind. Im schlimms-
ten Fall können nicht geschützte Mass-Assignment Anweisungen genutzt werden, um
die Berechtigungen eines Benutzers zu manipulieren [11, S. 25].
Mögliche Ansätze, dass Mass-Assignment für bestimmte Felder zu deaktivieren
(so genanntes Blacklisting) oder zu aktivieren (so genanntes Whitelisting) kann über
die Implementierung der Attribute attr_protected sowie attr_accessible durchgeführt
werden. Nicht explizit für das Mass-Assignment ausgewiesene Attribute müssen dann
entsprechend individuell zugewiesen werden. Das Whitelisting ist häufig in der Praxis
zu empfehlen, da Änderungen und menschliche Fehler dazu führen können, dass beim
Blacklisting wichtige geschützte Attribute vergessen werden. In Version 3.0 ist Rails
ist so vorkonfiguriert, das zwingend ein Whitelisting durch den Entwickler in allen
Model-Klassen durchgeführt werden muss. Hierfür zuständig ist ein Konfigurations-
parameter in der Datei application.rb [46]. Eine Implementierung eines Whitelistening
kann folgendermaßen durchgeführt werden:
# Whitelisting des Attributs name in der von ActiveRecord
# abgeleiteten Klasse Bookmark
class Bookmark < ActiveRecord::Base
attr_accessible :name
end
Die Gefahr bei Mass-Assignment liegt daher nicht in der technischen Machbarkeit der
Implementierung, sondern in der Konzeption. Es bedarf einer intensiven Auseinan-
dersetzung mit dem Thema um zu bestimmen, welche Attribute beschreibbar sein
sollen und welche nicht.
5.6 Logging
Im Standard wird Ruby on Rails alle Anfragen von Benutzern protokollieren. Dies
kann ein großes Sicherheitsproblem darstellen, falls Informationen wie Passwörter,
Kreditkarteninformationen und weitergehende sensitive Informationen ebenfalls im
Log-Verzeichnis abgespeichert werden [45]. Um dieses Problem zu umgehen, wurde
in Rails 3.0 die Möglichkeit gegeben, in der Datei config/application.rb Parameter zur
Filterung bei Logging-Ausgaben anzugeben:
# Configure sensitive param which will be filtered from
# the log file.
config.filter_parameters += [:password]
Diese oben dargestellte Zeile ist im Standard vorhanden und muss entsprechend er-
weitert werden, je nachdem welche Informationen aus Log-Files zu entfernen sind.
Anstelle des Passworts wird anschließend im Logging der Wert [FILTERED] darge-
stellt.
6 Fazit und Ausblick
Im Rahmen dieser Ausarbeitung konnte im ersten Schritt ein generelles Modell zur
Ableitung der Sicherheitsebenen von Webanwendungen vorgestellt werden. Dieses
generelle Modell wurde anschließend genutzt, um systematisch realistische Angriffs-
szenarien vorzustellen, die Ruby on Rails-basierte Webseiten im Internet ausgesetzt
sein können. Zielsetzung war es dabei immer, dass neben der Schilderung der konkre-
ten Gefahren auch detailliert Lösungsansätze diskutiert und gegeneinander abgewo-
gen werden.
Es wurde festgestellt, dass mit Hilfe von Ruby on Rails auch sicherste Webanwen-
dungen erstellt werden können und bereits im Standard zahlreiche Funktionalitäten
zur Verfügung stehen, die den Weg zur sicheren Webanwendung vereinfachen. Vor
allem die Sicherheit hat mit der Version 3.0 des Web Application Framework noch
einmal zugenommen, da die Ergänzungen zum Schutz vor Cross Site Scripting einen
weitgehend vollständigen Schutz vor den größten Sicherheitsherausforderungen im
Web ermöglicht [4][34].
Trotz aller Automatisierung ist es aber für alle an dem Prozess der Softwareent-
wicklung beteiligten Personen nach wie vor wichtig, dass auch bei so mächtigen
Framewoks wie Ruby on Rails nach wie vor die Fähigkeit vorhanden sein muss, Si-
cherheitsrisiken bei der Umsetzung von Lösungen zu erkennen und diese zu bewer-
ten. Natürlich unterstützt Rails dabei, sichere Webanwendungen umzusetzen, die
Entscheidung aber beispielsweise welches Attribut geschützt sein soll, welche Folgen
ein bestimmter Prozess oder ein bestimmtes Vorgehen in der Implementierung nach
sich zieht, muss der Entwickler individuell abschätzen und entsprechend den optima-
len Weg zur Umsetzung finden.
Die Fähigkeit hierzu ist vor allem deshalb so wichtig, da das Thema Web-
Application-Security extrem schnelllebig und entsprechend komplex ist. Dies lässt
sich alleine schon daran feststellen, dass der auf der offiziellen Webseite des Ruby on
Rails Projekt bereitgestellte Security Guide seit dem Jahr 2009 kaum Überarbeitungen
mehr erfahren hat [11] und dieser damit Neuentwicklungen in Version 3 nicht mehr
wiederspiegelt. Deshalb ist es neben den allgemeinen vorgeschlagenen Hinweisen in
diesem Dokument ratsam für Ruby on Rails Entwickler, aktuelle sicherheitsrelevante
Neuigkeiten im Internet, beispielsweise über die Plattform
http://www.rorsecurity.info/ oder den zahlreichen Blogs im Internet zu beziehen.
Bugs und Sicherheitslücken in der Software Ruby on Rails werden entsprechend of-
fen kommuniziert und Workarounds beziehungsweise Fixes angeboten.
Referenzen
1. Schreiber, T.: Best Practices für sichere Webanwendungen. iX 03/2007: 119–122 (2007).
2. Kaspersky Lab ZAO: Cyberthreat forecast for 2012. http://www.kaspersky.com/images/
Kaspersky%20report-10-134377.pdf (2011). Abgerufen am: 02.03.2012.
3. Gieselmann, H.: Der Millionen Hack. Datendiebe brechen in Sonys Netzwerk ein. c't
11/2011 (2011).
4. OWASP Foundatoin: Top 10 2010-Details About Risk Factors. https://www.owasp.org/
index.php/Top_10_2010-Details_About_Risk_Factors (2010). Abgerufen am:
02.03.2012.
5. Kappel, G.; Pröll, B.; Reich, S.; Retschitzegger, W.: Web engineering. The discipline of
systematic development of web applications. John Wiley & Sons, Hoboken, NJ (2006).
6. Lew, P.; Olsina, L.; Zhang, L.: Quality, Quality in Use, Actual Usability and User Experi-
ence as Key Drivers for Web Application Evaluation. In: Benatallah B (ed) Web engi-
neering. 10th International Conference, ICWE 2010, Vienna Austria, July 5-9, 2010. Pro-
ceedings. Springer-Verlag, Berlin ;Heidelberg, Seite 218–232 (2010).
7. Ferner, J.: PHP Security Guide. http://www.tu-chemnitz.de/urz/www/php/rsrc/
phpsec.pdf (2006). Abgerufen am: 22.01.2012.
8. Meier, J.: Web Application Security Engineering. IEEE Security and Privacy 07/2006: S.
16–24, (2006).
9. Microsoft Corporation: Simplified Implementation of the Microsoft SDL.
http://www.microsoft.com/download/en/details.aspx?id=12379 (2010). Abgerufen am:
18.03.2012.
10. Bundesamt für Sicherheit in der Informationstechnik: Sicherheit von Webanwendungen.
Maßnahmenkatalog und Best Practices. https://www.bsi.bund.de/SharedDocs/Downloads/
DE/BSI/Publikationen/Studien/WebSec/WebSec_pdf.pdf?__blob=publicationFile (2006).
Abgerufen am: 22.01.2012.
11. Webers, H.: Ruby on Rails Security. https://www.owasp.org/images/2/26/Owasp-rails-
security.pdf (2009). Abgerufen am: 26.03.2012.
12. Ruby on Rails: Ruby on Rails 3.0 Release Notes. http://guides.rubyonrails.org/
3_0_release_notes.html (2012). Abgerufen am: 15.04.2012.
13. Oracle Corporation: Securing the Initial MySQL Accounts. http://dev.mysql.com/doc/
mysql-security-excerpt/5.1/en/default-privileges.html (2012). Abgerufen am: 14.04.2012.
14. Krautgartner, T.; Hölterhoff, M.: Web Application Security. Niemals ungeschützt. java-
Magazing 6/2009: S. 46–55 (2009).
15. Rütten, C.: Web-Server mit mod_security absichern. http://www.heise.de/security/artikel/
Die-Apache-Firewall-270782.html (2006). Abgerufen am: 11.03.2012.
16. Bundesamt für Sicherheit in der Informationstechnik: IT-Grundschutz-Katalog. https://
gsb.download.bva.bund.de/BSI/ITGSK12EL/IT-Grundschutz-Kataloge-12-EL.pdf
(2011). Abgerufen am: 18.03.2012.
17. Slater, M.: Using SSL in Rails Applications. http://www.buildingwebapps.com/articles/
6401-using-ssl-in-rails-applications (2008). Abgerufen am: 18.03.2012.
18. Rack: Request.rb. https://github.com/rack/rack/blob/master/lib/rack/request.rb (2012).
Abgerufen am: 15.04.2012.
19. Morrison, D.: SSL with Rails. http://collectiveidea.com/blog/archives/2010/11/29/ssl-
with-rails (2010). Abgerufen am: 07.04.2012.
20. PCI Security Standards Council: Payment Card Industry (PCI) Data Security Standard.
Requirements and Security Assessment Procedure. https://www.pcisecuritystandards.org/
documents/pa-dss_de-de_v2.pdf. Abgerufen am: 15.04.2012.
21. Huber, S.: attr_encrypted. https://github.com/shuber/attr_encrypted/blob/master/
README.rdoc (2011). Abgerufen am: 15.04.2012.
22. Harding, B.: Guide to Setup Rails with MySQL SSL. http://www.williambharding.com/
blog/rails/guide-to-setup-rails-with-mysql-ssl/ (2008). Abgerufen am 08.04.2012.
23. Oracle Corporation: Using SSL for Secure Connections. http://dev.mysql.com/doc/
refman/5.6/en/secure-connections.html (2012). Abgerufen am: 25.03.2012.
24. Ruby on Rails: ActionController:HttpAuthentication:Basic. http://api.rubyonrails.org/
classes/ActionController/HttpAuthentication/Basic.html (2012). Abgerufen am:
15.04.2012.
25. Network Working Group: HTTP Authentication: Basic and Digest Access Authentica-
tion. http://www.ietf.org/rfc/rfc2617.txt (1999). Abgerufen am: 15.04.2012.
26. Cardella, B.: Exploring Rails 3.1 - ActiveModel:SecurePassword. http://bcardarella.com/
post/4668842452/exploring-rails-3-1-activemodel-securepassword (2011). Abgerufen am
08.04.2012.
27. Ruby on Rails: ActionDispatch:Cookies < Object. http://api.rubyonrails.org/classes/
ActionDispatch/Cookies.html (2012). Abgerufen am: 25.03.2012.
28. Wang, X.; Feng, D.; Yu, H.: Collision for Hash Functions.
http://eprint.iacr.org/2004/199.pdf (2004). Abgerufen am: 09.04.2012.
29. Ruby on Rails (2012) Active Record Session Store. http://api.rubyonrails.org/classes/
ActiveRecord/SessionStore.html. Abgerufen am: 15.04.2012.
30. Ruby on Rails: ActionController:SessionManagement:ClassMethods. http://
rails.rubyonrails.org/classes/ActionController/SessionManagement/ClassMethods.html
(2012). Abgerufen am: 15.04.2012.
31. Webers, H.: Security and Safety of Ruby on Rails in regard to a project management
software. http://pi1.informatik.uni-mannheim.de/filepool/theses/bachelorarbeit-2007-
webers.pdf (2007). Abgerufen am: 15.04.2012.
32. Ruby on Rails: ActiveRecord:Sanitization:ClassMethods. http://api.rubyonrails.org/
classes/ActiveRecord/Sanitization/ClassMethods.html (2012). Abgerufen am: 14.04.2012.
33. Ruby on Rails: Active Record. http://api.rubyonrails.org/classes/ActiveRecord/
Base.html (2012). Abgerufen am: 14.04.2012.
34. Katz, Y.: Secure by Default: Rails 3 Security Strategy. http://www.railsdispatch.com/
posts/security (2010). Abgerufen am: 15.04.2012.
35. van Tilborg, H., Jajodia. S.: Encyclopedia of Cryptography and Security. Springer US,
Boston, MA (2011).
36. heise Security: Twitter fixt erneute XSS-Lücke. http://www.heise.de/security/meldung/
Twitter-fixt-erneute-XSS-Luecke-1315670.html (2011). Abgerufen am: 09.04.2012.
37. Louw, M.; Venkatakrishnan, V.: Blueprint: Robust Prevention of Cross-site Scripting
Attacks for Existing Browsers. 30th IEEE Symposium on Security and Privacy. http://
www.cs.uic.edu/~venkat/research/papers/blueprint-oakland09.pdf (2009). Abgerufen am
15.04.2012.
38. Katz, Y.: SafeBuffers and Rails 3.0. http://yehudakatz.com/2010/02/01/safebuffers-and-
rails-3-0 (2010). Abgerufen am: 09.04.2012.
39. Ruby on Rails: ActionView:Helpers:SanitizeHelper. http://api.rubyonrails.org/classes/
ActionView/Helpers/SanitizeHelper.html (2012). Abgerufen am: 09.04.2012.
40. Ruby on Rails: ActionView:Helpers:TextHelper. http://api.rubyonrails.org/classes/
ActionView/Helpers/TextHelper.html (2012). Abgerufen am 09.04.2012.
41. Garber, J.: RedCloth - Textile parser for Ruby. https://github.com/jgarber/redcloth/blob/
master/README.rdoc (2011). Abgerufen am: 15.04.2012.
42. Zeller, W.; Felten, E.: Cross-Site Request Forgeries: Exploitation and Prevention.
http://www.cs.utexas.edu/users/shmat/courses/library/zeller.pdf (2008). Abgerufen am:
09.04.2012.
43. Ruby on Rails: Rails Routing from the Outside In. http://guides.rubyonrails.org/
routing.html (2012). Abgerufen am: 28.01.2012.
44. Daigle, R.: What's New in Edge Rails: Better Cross-Site Request Forging Prevention.
http://archives.ryandaigle.com/articles/2007/9/24/what-s-new-in-edge-rails-better-cross-
site-request-forging-prevention (2007). Abgerufen am: 14.04.2012.
45. Korziarski, M.: CSRF Protection Bypass in Ruby on Rails. http://groups.google.com/
group/rubyonrails-security/browse_thread/thread/2d95a3cc23e03665 (2011). Abgerufen
am: 15.04.2012.
45. Ruby on Rails: Configuring Rails Applications. http://guides.rubyonrails.org/
configuring.html (2012). Abgerufen am: 09.04.2012.