Rails 2.3 Anwendungen sicher betreiben
Obwohl Ruby on Rails in Version 2.3 schon viele Jahre nicht mehr mit Sicherheitsupdates versorgt wird, basieren noch immer viele Anwendungen darauf.
Um einen sicheren Betrieb dieser Systeme zu gewährleisten, kommen folgende Optionen infrage:
- Upgrade auf aktuelle Rails Version
- Isolierung in Docker-Container
- Zugriffseinschränkung via Firewall und Co.
- Neuentwicklung
- Umstieg auf Rails LTS
Dieser Artikel bespricht deren Vor- und Nachteile und zeigt welche Varianten wann zu empfehlen sind.
Ausgangssituation und Risiken
Das Web-Framework Ruby on Rails erfreute sich Ende der 2010er Jahre großer Beliebtheit. Webanwendungen ließen sich mit viel weniger Aufwand entwickeln als dies bis dahin der Fall war. Sehr viele der damals entstandenen Applikationen verwendeten das Framework in Version 2.3.
Zehn Jahre später hat sich das für viele Systeme nicht geändert – sie basieren nach wie vor auf Version 2.3.
Dies stellt jedoch ein großes Sicherheitsproblem dar, denn Rails 2.3 wird von offizieller Seite schon jahrelang nicht mehr mit Sicherheitsupdates versorgt. Genau genommen stellten die Rails-Entwickler den Support für Version 2.3 im Jahr 20131 ein.
Sicherheitsupdates wären jedoch dringend notwendig, denn auch im Jahr 2021 werden noch immer neue Sicherheitslücken in Rails 2.3 gefunden.
Was das Problem noch verschärft, ist der Umstand, dass viele dieser de-facto unsicheren Anwendungen auf völlig veralteten Servern betrieben werden, die für sich als unsicher gelten.
Der Umzug auf einen aktuellen Server um zumindest auf der Betriebssystem-Ebene geschützt zu sein, ist allerdings nicht möglich, weil Rails 2.3 mit neueren Ruby-Versionen nicht lauffähig ist2.
Wer auf die Idee kommt, in einer aktuellen Linux-Distribution einfach eine kompatible Ruby-Version zu installieren (z.B. über über rvm), wird enttäuscht werden. Denn Ruby setzt gewisse Abhängigkeiten zu nativen C-Libraries voraus, die in aktuellen Distributionen in aller Regel nicht mehr zur Verfügung stehen.
Eine Rails 2.3 Anwendung stellt also nicht nur auf Framework-Ebene, sondern auch in den darunterliegenden Schichten (Ruby, Betriebssystem) ein latentes Sicherheitsrisiko dar, das je nach Wichtigkeit der Anwendung den laufenden Betrieb eines Unternehmens gefährden oder gar den Ausfall eines Softwareprodukts bedeuten kann.
Betreiber veralteter Rails-Anwendungen sollten sich die Frage stellen, wie viel es kosten würde, würde ihr Unternehmen aufgrund eines Hackerangriffs stillstehen.
Die Antworten darauf werden unterschiedlich drastisch ausfallen. Die Frage sollte aber jedenfalls dazu anregen, sich darüber Gedanken zu machen, wie man die Anwendung wieder sicher bekommt.
Dabei ist anzumerken, dass die nun präsentierten Lösungswege lediglich die technische Infrastruktur absichern. Die Anwendungsentwickler bleiben verantwortlich für die Sicherheit des individuellen Anwendungscodes.
Upgrade auf aktuelle Rails Version
Eine naheliegende Option ist, die bestehende Anwendung auf eine aktuelle und damit offiziell gewartete und sichere Rails Version zu bringen. Leider haben Rails-Upgrades nicht den Ruf unproblematisch vonstatten zu gehen. Gerade in den frühen Tagen des Frameworks ging der Upgrade-Prozess mit vielen Inkompatibilitäten einher. Allein das Upgrade einer Anwendung von Rails 2.3 auf 3.0 kann ein weiter, aufwendiger Sprung sein. Direkt auf eine aktuelle Version wie 6.1 zu wechseln, wird in der Entwicklergemeinde als unmöglich angesehen.
Ein oft genannter Faktor für den Aufwand eines Upgrades ist wie viele Zusatzbibliotheken (sogenannte Gems) benutzt werden. Diese müssen aufgrund von Inkompatibilitäten mit Sprache Ruby oder dem Framework Rails im Laufe des Upgrade-Prozesses selbst aktualisiert oder gar ersetzt werden. Verwendet die Software wenige oder gar keine zusätzlichen Gems, macht dies die Upgrade-Option attraktiver.
Der große Vorteil dieser Variante ist, dass die aktualisierte Anwendung auf einem aktuellen Linux-Betriebssystem mit aktuellen Ruby läuft. Unternehmen müssen allerdings auch bedenken, dass dieser Weg in Zukunft konsequent weiter gegangen werden muss, da eine heute aktuelle Rails-Version in ein paar Jahren ebenfalls veraltet sein wird. Dass ein aktueller Tech Stack ein Vorteil bei der Personalsuche ist, darf nicht vergessen werden.
Zusammenfassend gesagt, ist das Upgrade auf eine aktuelle Rails-Version ein gangbarer aber aufwendiger Weg, um die Infrastruktur der Anwendung wieder sicher zu machen. Der potenziell hohe Aufwand wird eher gerechtfertigt sein, wenn die Anwendung das Kerngeschäft eines Unternehmens bildet, wie das zum Beispiel bei SaaS-Produkten der Fall ist.
Isolierung in Docker-Container
Erscheint der Upgrade-Prozess als zu teuer, muss eine andere Lösung her. Ein valider Gedanke aus IT-Sicht ist, die Anwendung in einem Docker-Container zu verpacken und damit so gut es geht zu isolieren.
Der Container würde selbstverständlich auf einem aktuellen und sicheren Linux-Server gehostet. Die Angriffsfläche über ein veraltetes Betriebssystem wäre damit eliminiert.
Allerdings hilft diese Lösung nicht mit den veralteten Rails und Ruby Versionen im Container selbst, weshalb dieser Weg nicht ans gewünscht Ziel führt. Geht man ihn aus welchen Gründen auch immer, darf der Aufwand nicht unterschätzt werden, die Anwendung in einen Docker-Container zu verpacken.
Zugriffseinschränkung via Firewall und Co.
Ebenfalls weniger aufwendig als ein Rails-Upgrade ist die Option, die Anwendung durch Firewall und zusätzliche Barrieren wie HTTP Basic Authentication von außen abzuschirmen. SaaS-Produkte mit externen Kunden sind davon selbstverständlich ausgeschlossen.
Der geringe Aufwand macht diese Option sehr attraktiv. Zu bedenken sind allerdings welche Pfade existieren, um Daten ins System zu bringen, zu verändern und zu löschen. Hat die betreffende Anwendung beispielsweise eine Importschnittstelle, kann diese indirekt als Einfallstor ausgenutzt werden. Vorhandene Importschnittstellen im Programmcode abzusichern, könnte dieses Problem beseitigen oder zumindest das Risiko verkleinern.
Muss eine Anwendung nicht unbedingt von außen erreichbar sein, und können etwaige Importschnittstellen abgesichert werden, ist die Einschränkung des Zugriffs via Firewall und Co. eine kostengünstige Option, die fallweise in Betracht gezogen werden kann. Da die ursächlichen Probleme, nämlich die Unsicherheit von Betriebssystem, Ruby sowie Rails, damit nicht gelöst werden, wird dieser Ansatz nur für unkritische Anwendungen ernsthaft in Erwägung zu ziehen sein.
Neuentwicklung
Während die Anwendung bei der Abschirmung mit Firewall und Co. unverändert weiterbetrieben wird, ist die gänzliche Neuentwicklung der Anwendung konträr dazu. Selbiges gilt für den Aufwand. Ob sich die daraus resultierenden hohen Kosten auszahlen, hängt vom Zustand der Anwendung und den wirtschaftlichen Rahmenbedingungen ab.
Zieht man diesen Ansatz in Erwägung, geht man das Risiko ein, dass man auf ein Framework bzw. einen Tech Stack setzt, für den die laufende Aktualisierung – wie beim Rails-Upgrade-Prozess – ebenfalls aufwendig und kostenintensiv ist. Programmiersprachen und Frameworks haben dabei unterschiedliche Auffassungen über langfristige Stabilität und Rückwärtskompatibilität. Eine sorgsame Auswahl der Technologien in Hinblick auf die langfristige Wartbarkeit ist daher geboten.
Zudem ist klar, dass diese Variante in der Regel sehr kostenintensiv sein wird. Aber wenn Änderungskosten hoch und Benutzerfreundlichkeit niedrig sind, kann eine Neuentwicklung auch wirtschaftlich Sinn ergeben. Dieses Argument wird verstärkt, wenn das Unternehmen ohnehin größere Prozessänderungen plant, deren Abbildung in der Software durch mangelnde Wartbarkeit schwierig werden würde.
Die Neuentwicklung ist sicherlich die teuerste Variante. Sie kann wirtschaftlich dann gerechtfertigt werden, wenn sich die Anwendung sowohl aus Benutzersicht als auch aus technischer Sicht in einem schlechten Zustand befindet.
Umstieg auf Rails LTS
Mit der gänzlichen Neuentwicklung steht neben dem Rails-Upgrade somit eine zweite vollwertige, wenngleich kostspielige Option bereit, während die beiden anderen bis jetzt besprochenen Ansätze nur Teil- oder Notlösungen sind.
Mit Rails LTS existiert eine in den meisten Fällen günstigere dritte Lösung.
Die deutsche makandra GmbH versorgt ausgelaufene Rails-Versionen, beginnend mit Rails 2.3, mit aktuellen Sicherheitsupdates und bietet diese kommerziell an.
Diese Variante bietet einige Vorteile. Der wohl größte Vorteil ist, dass die Anwendung selbst, wenn überhaupt nur minimal, geändert werden muss, um mit Rails 2.3 LTS lauffähig zu sein.
Ein weiterer Vorteil ist, dass Rails 2.3 LTS mit aktuellen Ruby-Versionen kompatibel ist. Zum Zeitpunkt der Veröffentlichung dieses Artikels war dies Ruby 2.7. Damit kann eine auf Rails LTS aufbauende Webanwendung auf einem aktuellen Ubuntu 20.04 LTS betrieben werden.
Ein ebenfalls nicht zu unterschätzender Vorteil ist die wirtschaftliche Kalkulierbarkeit, denn es ist von vornherein klar, wie viel die Inanspruchnahme des kommerziellen Angebots über die folgenden Jahre kosten wird. Das Restrisiko einer Preiserhöhung darf hier natürlich nicht unerwähnt bleiben.
Rails LTS ermöglicht den sicheren Betrieb der Anwendung auf allen Ebenen der Infrastruktur, nämlich auf Betriebssystem-, Ruby- und Rails-Ebene. Der geringe Anpassungsbedarf im Anwendungscode und die kalkulierbaren Kosten machen diese Option sehr attraktiv.
Schlussfolgerung
Die Vorteile von Rails LTS machen sie vor allem für firmeninterne Anwendungen interessant, die ihren Zweck bestens erfüllen und seit Jahren brav ihren Dienst leisten. Aus der Sicht des Autors ist dieser Weg in jedem Fall in Betracht zu ziehen.
Sind die Benutzer allerdings sehr unzufrieden mit der Anwendung, und lässt sich dieser Umstand auch aufgrund mangelnder Wartbarkeit kaum ändern, ist eine gänzliche Neuentwicklung eine veritable wenngleich kostspielige Option.
Das Upgrade auf eine aktuelle Rails-Version ist in der Regel nicht ganz so aufwendig wie die Neuentwicklung, verlangt aber dennoch einen nicht zu verachtende Investition von Zeit und Geld. Dieser Weg ist wohl eher für SaaS-Produkte interessant, wo auch andere Faktoren eine Rolle spielen – zum Beispiel um mit dem Einsatz moderner Technologien attraktiver für potenzielle Mitarbeiter zu sein.
Für unkritische interne Anwendungen, deren zeitweiliger Ausfall den laufenden Betrieb eines Unternehmens gar nicht bis wenig stören würde, ist schließlich die bestmögliche Abschottung des Systems über Firewalls und andere Mechanismen ein gangbarer Weg.
Dieser kann durch die Isolierung der Anwendung in einem Docker-Container komplettiert werden. Die alleinige Isolierung eines Systems über Docker macht diese jedoch noch nicht sicher, da unsichere Versionen sowohl von Rails als auch von Ruby betrieben werden würden. Diese Maßnahme ist folglich nur orthogonal zu anderen Maßnahmen zu sehen und keineswegs eine Lösung für sich.
Fußnoten
1 Der letzte Minor-Release 2.3.18 wurde am 18. März 2013 veröffentlicht, siehe https://rubygems.org/gems/rails/versions
2 Ubuntu 20.04 Focal Fossa liefert offiziell Ruby 2.7 aus. Rails 2.3 erfordert allerdings entweder Ruby 1.8.7 oder 1.9.3.