Sicherheit ist ein Hauptanliegen für jeden Entwickler, der eine erfolgreiche und nachhaltige Entwicklung von Webanwendungen anstrebt. Jeder Entwickler möchte so programmieren, dass seine Anwendungen so sicher wie möglich vor Angriffen sind. Allerdings kann kein Code 100% fehlerfrei oder sicher sein. Die Entwickler sind sich also bewusst, dass sie ihr Bestes tun müssen, um ihre Anwendungen so wenig anfällig wie möglich für Angriffe zu machen. Das Aufspüren von Schwachstellen ist einfach, aber Sicherheitsverletzungen und Hacks können zu Verlusten führen. Aus diesem Grund ist es immer besser, bereits zu Beginn der Anwendungsentwicklung nach Sicherheitsproblemen zu suchen und regelmäßige Qualitätskontrollen durchzuführen, um die Dinge auf Kurs zu halten.
1] Sitzungen
Ein guter Ausgangspunkt für die Bewertung der Sicherheit sind die Sitzungen, die für bestimmte Angriffe anfällig sein können.
session[:user_id] = @current_user.id
User.find(session[:user_id])
- Ruby on Rails verwendet standardmäßig einen Cookie-basierten Sitzungsspeicher. Dies bedeutet, dass die Sitzung auf dem Server nicht abläuft, solange nichts geändert wird. Das bedeutet, dass wir niemals sensible Daten wie Passwörter, IDs usw. in Sessions speichern sollten.
- Die beste Vorgehensweise ist daher, mit einer datenbankbasierten Session zu arbeiten, was mit Rails sehr einfach ist -
Projekt::Application.config.session_store :active_record_store
Die Sitzungs-ID ist eine 32-stellige zufällige hexadezimale Zeichenfolge.
Die Sitzungs-ID wird mit SecureRandom.hex generiert, das eine zufällige hexadezimale Zeichenkette mit einer der plattformspezifischen Methoden wie OpenSSL, /dev/urandom oder Win32 zur Erzeugung kryptografisch sicherer Zufallszahlen erzeugt. Derzeit ist es nicht möglich, einen Brute-Force-Angriff, d. h. einen Angriff durch Ausprobieren, auf die Anmeldedaten in den Sitzungskennungen von Rails durchzuführen.
Hier sind einige der häufigsten sitzungsbasierten Angriffe:
Session Hijacking:- Dies ermöglicht es den Angreifern, die Sitzungs-ID eines Benutzers zu stehlen und die Webanwendung im Namen des Opfers zu verwenden.
Sitzungsfixierung: Neben dem Diebstahl der Sitzungs-ID eines Benutzers ist der Angreifer auch in der Lage, eine ihm bekannte Sitzungs-ID zu fixieren. Dies wird als Sitzungsfixierung bezeichnet.
Sitzungsablauf: Die Angreifer versuchen, den Zeitrahmen des Angriffs mit Sitzungen, die nie ablaufen, zu verlängern. Beispiele für solche Angriffe sind Cross-Site Request Forgery (CSRF), Session Hijacking und Session Fixation.
2] Befehlsinjektion
Eine Anwendung wird anfällig für Befehlsinjektion, wenn der Angreifer in der Lage ist, die Befehlszeilenparameter oder die Unix-Befehle als Ganzes zu beeinflussen. Da die Ausführung von UNIX-Befehlen in Rails jedoch nicht üblich ist, sind diese Angriffe weniger wahrscheinlich.
Andererseits können Schwachstellen in einem Hintergrundprozess entstehen, der die Unix-Befehle für die Kundendaten direkt nutzt.
Hier sind einige der üblichen Rails-Befehlszeilenmethoden:
%x[...]
system()
exec()
`…`
Es sollte auch beachtet werden, dass es mehr als eine Möglichkeit gibt, Befehle aneinander zu ketten, aber das hängt auch vom Host-Betriebssystem ab. Beispiele: "&", "&&", "|", "||" usw.
Gesicherte Umgebungsvariablen bei der Ausführung von Befehlen
Die Prozesse, die von Ihren Rails-Anwendungen ausgeführt werden, erhalten die Umgebungsvariablen der übergeordneten Prozesse, zu denen auch die API-Schlüssel usw. gehören können.
3] SQL-Einschleusung
Eine SQL-Injektion liegt vor, wenn ein Benutzer in der Lage ist, einen Wert zu manipulieren, der auf unsichere Weise in einer SQL-Abfrage verwendet wird. Dies kann zu Datenverlust, Datenlecks, erhöhten Rechten und anderen unerwünschten Ergebnissen führen.
SQL-Injection ist ein sehr einfacher und weit verbreiteter Angriff, der in der Regel auftritt und dessen Auswirkungen je nach Website und Situation, in der er auftritt, sehr schwerwiegend sein können.
Als Entwickler sollten wir uns um all die Möglichkeiten kümmern, bei denen SQL-Injection auftreten kann, und diese entsprechend behandeln.
So sieht eine SQL-Injection aus:
Employee.all(:conditions => "Bezeichnung = #{params[:Bezeichnung]}")
Der obige Code ist anfällig für SQL-Injektion, der folgende Code verhindert die SQL-Injektion.
Employee.all(:conditions => ['Bezeichnung = ?', params[:Bezeichnung]])
ODER
Employee.all(:conditions => {:designation => params[:designation]})
Gegenmaßnahmen gegen SQL Injection in Rails
Das Testen jeder Anweisung auf SQL-Injection kann eine mühsame Arbeit sein, aber wir sollten einige Gegenmaßnahmen ergreifen, wie statische Code-Scanner wie Brakeman und Sie können einige Unit-Testfälle schreiben.
a) Allgemeine Regel:- Verwenden Sie niemals Parameter in der Stringbeugung (#{}) wie folgt
Zum Beispiel
User.where("Name = '#{params[:name]}'")
b)Achten Sie darauf, dass params z.B. auch ein Array sein kann:
params[:user], wenn Sie ?user[]=1 zur URL hinzufügen. User.exists? params[:user] wird dann die Abfrage SELECT 1 AS one FROM "users" WHERE (1) LIMIT 1 ausführen.
4] Cross-Site-Scripting (XSS)
Mit Hilfe von XSS wird ein Angreifer in die Lage versetzt, Skripte im Sicherheitskontext Ihrer Webanwendung auszuführen.
Betrachten Sie dieses Rails-View-Snippet: . Wenn der Titel des Flats zusammen mit dem Hinzufügen des HTMLs bearbeitet wird, rendert dieser Rails-View diesen HTML-Code im Sicherheitskontext der Anwendung. Somit würde der Browser den HTML-Code ausführen, was ein XSS darstellt.
In der Tat funktioniert das in Rails heutzutage noch nicht, in Rails Version 2 müsste man jede einzelne Benutzereingabe mit einem Escape versehen:
Heutzutage wird in Rails jeder String mit einem Flag versehen, das ihn als HTML markiert, egal ob er sicher ist oder nicht: @flat.title.html_safe?. Falls er nicht sicher ist (z.B. von einem Parameter, aus der Datenbank, ...), wird er automatisch escaped, wenn man ihn auf diese Weise verwendet:
In Rails 3.0 ist der Schutz gegen XSS ein Standardverhalten.
Gegenmaßnahmen
a) Eine Strategie der Inhaltssicherheit (CSP)
A Inhaltliche Sicherheit Politik hat im Grunde die Form eines HTTP-Headers, in dem die Regeln für alle zulässigen Quellen für alle Arten von Assets festgelegt sind. Die Befolgung dieser Regeln hat zur Folge, dass alles andere nicht erlaubt ist. Einmal richtig implementiert, können damit alle Cross-Site-Scripting (XSS)-Schwachstellen in Ihrer Anwendung beseitigt werden.
b) HTML-Safe,ActiveSupport::SafeBuffer
Das Modul ActiveSupport::SafeBuffer wurde mit Rails 3 eingeführt, um ein HTML-sicheres Flag zu Strings hinzuzufügen. Standardmäßig ist es false, vor allem, wenn der String eine externe Quelle wie die Datenbank oder die Params hat. Das Flag wird mit "string".html_safe? zurückgegeben.
Die HTML-escape-Methode h(), die eine Zeichenkette als HTML-sicher kennzeichnet, maskiert die Zeichenkette.
h("html>").html_safe? #=> true
("html>").html_safe? #=>false
c) OWASP (Open Web Application Security Project) XSS-Prävention
Zur Verhinderung von XSS müssen alle nicht vertrauenswürdigen Daten verweigert und daran gehindert werden, direkt in den HTML-Code oder einen anderen Kontext (wie JavaScript, CSS, Attributkontexte) eingefügt zu werden.
d) XSS-Schutz in HAML-Templates
Bei Verwendung der Haml-Vorlagen anstelle der ERB-Vorlagen werden Strings automatisch auf die gleiche Weise wie in ERB-Vorlagen escaped. Und genau wie bei den ERB-Vorlagen werden HTML-sichere Zeichenketten (string.html_safe? liefert true) nicht automatisch übersprungen. Die != Notation in Haml funktioniert so wie in ERB, d.h. es wird die unescapte Version gerendert.
Standardmäßig,
="betont"
!= "Hervorgehoben"
kompiliert zu:
Hervorgehoben
Hervorgehoben
Daher ist bei der Verwendung von != in Haml Vorsicht geboten, und es sollte sichergestellt werden, dass keine Benutzerdaten unescaped wiedergegeben werden.
Nachfolgend sind einige vorbeugende Maßnahmen aufgeführt, die bei der Entwicklung von Schienenanwendungen beachtet werden können.
1] Authentifizierung
Verwenden Sie Device oder Authlogic gem.
- Um die Autorisierung zu aktivieren, vergessen Sie bitte nicht, -> hinzuzufügen.
Klasse ProjectController < ApplicationController
vor_filter :authenticate_user
- Standardmäßig verlangt Devise nur 6 Zeichen für ein Passwort. Das Minimum kann in: /config/initializers/devise.rb
config.password_length = 8..128
- Sie können die Passwortkomplexität ändern, indem Sie den folgenden Code in das Benutzermodell einfügen.
validieren :passwort_komplexität
def passwort_komplexität
if password.present? and not password.match(/\A(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+\z/)
errors.add :password, "muss mindestens einen Kleinbuchstaben, einen Großbuchstaben und eine Ziffer enthalten"
end
end
2] Unsichere direkte Objektreferenz oder erzwungenes Browsing
- Ruby on Rails-Anwendungen verwenden eine Restful-URL-Struktur, so dass die verwendeten Pfade meist erraten werden können und intuitiv sind. Um also zu verhindern, dass ein Benutzer versucht, auf Daten zuzugreifen oder diese zu ändern, die einem anderen Benutzer gehören, müssen die Aktionen speziell kontrolliert werden. In einer Vanilla-Rails-Anwendung gibt es von vornherein keinen solchen eingebauten Schutz. Außerdem kann er manuell auf der Controller-Ebene durchgeführt werden.
- Cancancan oder Pandit für die Zugangskontrolle verwenden
3] Massenzuordnung und starke Parameter
- Klasse Projekt < ActiveRecord::Base
attr_accessible :name, :admin
end
Nach dem obigen Beispiel, bei dem das Attribut admin zugänglich ist, könnte Folgendes funktionieren:
- curl -d "project[name]=triage&project[admin]=1" host:port/projects
- config.active_record.whitelist_attributes = true
4] Umleitungen und Weiterleitungen
- Es ist ratsam, Umleitungen zu vermeiden, die Parameter verwenden
Zum Beispiel:- //www.example.com/redirect?url=//www.example_commerce_site.com/checkout
- restriktiver Schutz ist die Verwendung der Option :only_path
beginnen
if path = URI.parse(params[:url]).path
redirect_to Pfad
end
rescue URI::InvalidURIError
redirect_to '/'
end
- Verfügen Sie über eine Hash-Datei mit genehmigten Websites und erlauben Sie nur diesen, weitergeleitet zu werden.
5] Dynamische Renderpfade
- Vorsicht ist geboten, wenn Sie eine Ansicht basierend auf einer Bedingung dynamisch rendern. Dies könnte dazu führen, dass die Admin-Ansicht geladen wird.
6] Ursprungsübergreifende Ressourcennutzung
- Wie Datei-Upload.
- Die empfangende Website sollte nur Domänen auf der Whitelist zulassen und sicherstellen, dass die Anfragen auch nur von diesen Domänen kommen.
- Setzen Sie außerdem den Access-Control-Allow-Origin-Header sowohl in der Antwort auf die OPTIONS-Anfrage als auch auf die POST-Anfrage. Dies liegt daran, dass die OPTIONS-Anforderung zuerst gesendet wird, um festzustellen, ob die entfernte oder empfangende Site die anfragende Domäne zulässt.
- Es wird eine POST-Anfrage gesendet. Auch hier muss die Kopfzeile gesetzt werden, damit die Transaktion als erfolgreich angezeigt wird.
7] Fehler in der Geschäftslogik
- Die Anwendungen können unabhängig von der Technologie, auf der sie basieren, Fehler in der Geschäftslogik enthalten, die zu Sicherheitslücken führen können. Es kann sehr schwierig sein, solche Sicherheitsprobleme mit automatisierten Tools zu erkennen. Praktiken wie die regelmäßige Überprüfung des Codes, Pair Programming und das Schreiben von Unit-Tests können Ihnen helfen, das Auftreten solcher Sicherheitsprobleme zu vermeiden.
8] Sensible Dateien
Im Folgenden sind einige Dateien aufgeführt, auf die wir bei der Entwicklung einer Webanwendung achten sollten.
/config/database.yml- Kann Produktionsanmeldedaten enthalten.
/config/initializers/secret_token.rb - Enthält ein Geheimnis, das zum Hashing des Sitzungscookies verwendet wird.
/db/seeds.rb - Kann Seed-Daten enthalten, einschließlich des Bootstrap-Admin-Benutzers.
/db/development.sqlite3 - Kann echte Daten enthalten.
9] Verschlüsselung
Ruby on Rails verwendet OS-Verschlüsselung. Sie sollten fast nie Ihre eigenen Lösungen für die Verschlüsselung schreiben.
Rails aktualisieren und einen Prozess für die Aktualisierung von Abhängigkeiten haben.
Tools zur Erkennung von Sicherheitsproblemen in Schienenanwendungen
- Bremser
- bundler-audit
- Codesake::Morgendämmerung
- Gestell::Attacke
- Vogelspinne
- Hakiri Werkzeuggürtel