Python 2 vs. 3: Sicherheitsunterschiede
10. Oktober 2017
0 Min. LesezeitPython 3 und Python 2 unterscheiden sich in verschiedenen Funktionen. Für sich genommen sind diese Unterschiede nicht unbedingt besser oder schlechter (auch wenn Python 3 durchaus eine Verbesserung sein sollte). Jede Änderung kann jedoch Risiken mit sich bringen. Dieser Beitrag beleuchtet einige Unterschiede zwischen den Versionen, die Auswirkungen auf die Sicherheit haben. Behalten Sie diese im Hinterkopf, wenn Sie Python-Anwendungen zwischen den Versionen migrieren.
Der aktuelle Stand der Python-Versionen 2 und 3
Python 3 wurde erstmals 2008 veröffentlicht. Ein Hindernis für die Verbreitung war die fehlende Abwärtskompatibilität. Viele Entwickler arbeiteten weiterhin mit früheren Versionen, vor allem mit Version 2, um den Aufwand für die Überarbeitung ihrer Anwendungen zu vermeiden. Deshalb wurde Python 2 weiter unterstützt und auch nach der Veröffentlichung von Version 3.0 aktiv weiterentwickelt.
Version 2.7 ist die aktuelle und letzte Version von Python 2, die von vielen Entwicklern weiterhin aktiv genutzt wird. 2.7 wurde 2010 veröffentlicht. Die Python Foundation hat angekündigt, dass der Support 2020 endet.
Python 3.6 ist die aktuelle Python-Version und wurde erstmals 2016 veröffentlicht. Python 3 gilt als Zukunft der Programmiersprache Python.
Python 2 vs. 3: Wichtige Unterschiede in der Programmiersprache und ihre Auswirkungen auf die Sicherheit
Im Folgenden werden die wichtigsten Unterschiede zwischen Python 2 und Python 3 beschrieben. Keine dieser Änderungen zielt zwar auf die Sicherheit ab, doch jede hat Auswirkungen auf die Sicherheit, die Sie beachten sollten.
Verkettung von Ausnahmen
Python 3 führte die standardmäßige Verkettung von Ausnahmen ein. In Python 2 wurden bei einer Ausnahme in einer Bibliothek, auf die das Hauptprogramm verweist, die Details dieser Ausnahme standardmäßig nicht im Traceback angezeigt. In Python 3 enthält der Traceback alle Details zu Ausnahmen – sowohl zu denen, die vom Hauptprogramm ausgelöst werden, als auch zu denen aus eingebundenen Bibliotheken.
Alle Interna Ihres Codes oder Laufzeitverhaltens, die für Benutzer sichtbar sind, stellen ein Sicherheitsrisiko dar. Die Verkettung von Ausnahmen ist zwar beim Debuggen praktisch, gibt potenziellen Angreifern aber deutlich mehr Informationen preis. Sie können einen Traceback auslösen, um zu sehen, wie die Software auf Fehler reagiert.
In Python 3 können Sie verkettete Ausnahmen deaktivieren, wenn Sie der Meinung sind, dass die Risiken den Nutzen überwiegen.
Eingabemethode
Python 2 bietet die Funktion eval(), die als unsicher gilt, weil sie den als Parameter übergebenen Text auswertet. Ein optionales zweites Argument legt globale Werte fest, die während der Auswertung verwendet werden. In Python 2 funktioniert die Funktion input() ähnlich wie eval() und ist ebenfalls unsicher.
Angreifer können diese Funktionen ausnutzen, indem sie Variablennamen in ihre Eingabe einfügen und so die Werte dieser Variablen auslesen, die vertrauliche Informationen enthalten können.
Daher gilt in Python 2 als bewährte Sicherheitsmaßnahme, weder eval() noch input() zu verwenden. Verwenden Sie stattdessen raw_input(), das Variablen im Eingabetext nicht auswertet.
Was hat sich in Python 3 geändert? raw_input() wurde entfernt und seine Funktionalität auf eine neue Funktion namens input() übertragen. Die neue Funktion input() funktioniert wie raw_input() in Python 2 und kann daher jetzt sicher verwendet werden.
Wenn Sie ein Python-3-Programm in Python 2 ausführen, lassen sich alle Eingaben jedoch ausnutzen.
Zusammenfassung:
Funktion | Python 2.x | Python 3.x |
|---|---|---|
| Wertet Variablen aus – unsicher | Wertet Variablen aus – unsicher |
| Wertet Variablen aus – unsicher | Wertet Variablen nicht aus, wie |
| Wertet Variablen nicht aus | Entfernt |
Ganzzahldivision
Python 2 behandelt Ganzzahldivision anders und weniger intuitiv als Python 3. In Python 2 ergibt die Division von Ganzzahlen immer einen ganzzahligen Wert, nämlich die größte ganze Zahl, die kleiner oder gleich dem Ergebnis ist. Diese Art der Division wird als Abrundungsdivision bezeichnet:
In Python 3 ist die Ganzzahldivision intuitiver, da bei der Division von Ganzzahlen nicht automatisch abgerundet wird:
Diese intuitivere Behandlung der Ganzzahldivision ist nicht abwärtskompatibel mit Python 2. Daher ist es besonders gefährlich, Python-3-Code in Python 2 auszuführen, denn ein anderes Verhalten bei der Ganzzahldivision führt nicht zu einem Syntaxfehler.
Dadurch entsteht auch ein potenzielles Sicherheitsproblem. Stellen Sie sich zum Beispiel eine App vor, die nach einer numerischen PIN fragt und anschließend die im System gespeicherte PIN durch die vom Benutzer eingegebene PIN teilt, um den Erfolg anzuzeigen. In Python 3 würde das wie erwartet funktionieren. Bei Ausführung derselben App in Python 2 wären jedoch zahlreiche fehlgeschlagene Versuche möglich.
Dieses Beispiel ist zwar nicht realistisch, veranschaulicht aber, dass die Rundung von Zahlen durch Ganzzahldivision (in Python 2) oder das Ausbleiben einer Rundung (in Python 3) das Verhalten sehr wahrscheinlich verändert. Angreifer könnten dies ausnutzen, um Schutzmechanismen zu umgehen.
Unicode-Unterstützung
Die beiden Python-Versionen verarbeiten Zeichenfolgen (Folgen von Zeichen) unterschiedlich.
Python 2 verwendet standardmäßig die ASCII-Zeichenkodierung. ASCII kann nur 256 Zeichen darstellen. Dadurch ist die Flexibilität von Python bei der Kodierung von Zeichen eingeschränkt, insbesondere bei Sonderzeichen.
Für die Verwendung von Unicode in Python 2 ist zusätzliche Syntax erforderlich. Bei der Verwendung von print müssen Sie den Eingabetext beispielsweise in die Funktion unicode() einschließen, damit Sonderzeichen verarbeitet werden.
Der Unicode-Standard ist deutlich vielseitiger und unterstützt mehr als 128.000 Zeichen. In Python 3 ist Unicode der Standard. Für Unicode-Werte ist keine zusätzliche Syntax nötig – sie werden automatisch als UTF-8-Zeichenfolgen ausgegeben.
Diese Änderung ist zwar leistungsstark, kann aber ein erhebliches Phishing-Risiko mit sich bringen. So können Nutzer beispielsweise auf eine URL verwiesen werden, in der Buchstaben des Domainnamens durch Zeichen aus nichtlateinischen Alphabeten ersetzt wurden. Ein Beitrag von Xudong Zheng zeigt, wie das für Nutzer aussieht:

Auf den ersten Blick sieht die URL unauffällig aus, doch der Schein trügt. Die URL in Xudongs Beispiel sieht zwar wie „apple.com“ aus, lautet tatsächlich aber „xn-pple-43d.com“. Wenn Sie beispielsweise das kyrillische „a“ (U+0430) statt des ASCII-Zeichens „a“ (U+0061) verwenden, können manche Browser die tatsächliche Domain unbeabsichtigt verschleiern. Die Website scheint also sicher zu sein, doch der Nutzer wird auf eine andere Domain weitergeleitet, die Sicherheitsrisiken bergen kann. Dies wird als Homograph-Angriff bezeichnet.
Dieser Angriff könnte Python-Anwendungen betreffen, wenn er sich gegen einen von der Python-App analysierten Verzeichnispfad oder einen Abfrageparameter richtet. Wenn die Anwendung beispielsweise den Pfad http://domain.com/Acme bereitstellt, könnte ein Angreifer die Buchstaben „Acme“ durch Zeichen aus anderen Alphabeten ersetzen und Nutzer so auf ein anderes Konto leiten.
Wenn Sie eine App von Python 2 auf 3 portieren, sollten Sie bedenken, dass alle Eingaben als Unicode dargestellt werden. Dadurch könnten Angreifer Ihre Nutzer täuschen.
Sicherheitslücken und -korrekturen in Python 3.6 vs. 2.7
In früheren Versionen von Python 2 und 3 gab es schwerwiegende Sicherheitslücken. Diese Versionen sollten Sie vermeiden (siehe CVE Details für Python-Versionen).
In den neuesten Versionen 2.7.x und 3.6.x wurden jedoch die meisten Sicherheitslücken behoben. Python 2 und 3 werden derzeit aktiv gewartet. Wenn Sie stets die neueste Version verwenden, sind Sie vor größeren Sicherheitslücken geschützt. Allerdings ist davon auszugehen, dass sich die Python Software Foundation künftig weniger auf Python 2 konzentrieren und dafür weniger häufig Sicherheitsupdates bereitstellen wird als für Python 3.
Am wichtigsten ist, dass Python 2 im Jahr 2020 das Supportende erreicht. Danach wird die Sprache nicht mehr gewartet und es werden keine Sicherheitskorrekturen mehr verfügbar sein. Wenn Sie Python 2 weiterhin verwenden, sollten Sie berücksichtigen, dass die Sprache ab 2020 unsicher wird, und mit der Planung Ihrer Migration zu Python 3 beginnen.
Unterschiedliche Abhängigkeitsgraphen, unterschiedliche anfällige Bibliotheken
Wegen der fehlenden Abwärtskompatibilität von Python 3 musste auch pip, der wichtigste Paketmanager für Python, separate Versionen für 2.x und 3.x bereitstellen und dokumentieren, welche Pakete welche Version unterstützen. Bei der Portierung einer Anwendung müssen daher oft die verwendeten Bibliotheken oder zumindest deren Versionen geändert werden.
Diese Bibliotheken sind wie jede Software nicht perfekt, und von Zeit zu Zeit werden Sicherheitslücken entdeckt. Sobald eine Sicherheitslücke bekannt wird, müssen Anwendungsverantwortliche sie schnell beheben, bevor Angreifer sie ausnutzen – ein Wettlauf, den Equifax beispielsweise deutlich verloren hat.
Korrekturen für Sicherheitslücken werden oft nicht auf alle möglichen Versionen übertragen. Deshalb müssen Sie bei der Portierung unbedingt Tests auf bekannte Sicherheitslücken einplanen. Wenn Sie aus irgendeinem Grund bei Python 2 bleiben, ist das Risiko für Sicherheitslücken noch höher, da Bibliotheken zunehmend die Unterstützung für die ältere Version einstellen, einschließlich der Bereitstellung von Sicherheitskorrekturen.
Unabhängig davon, für welche Python-Version Sie sich entscheiden: Mit Snyk können Sie Ihre Anwendung mithilfe unserer GitHub-Integration, unserer Befehlszeilenschnittstelle oder anderer integrierter Plattformen auf bekannte Sicherheitslücken testen.


