
Am 7. August stellte Facebook Pysa vor, einen auf Open Source-Sicherheit ausgerichteten statischen Analysator, mit dem Sie mit Millionen von Instagram-Zeichenfolgen arbeiten können. Die Einschränkungen werden offengelegt, Entwurfsentscheidungen werden angesprochen und natürlich die Mittel, um Fehlalarme zu vermeiden. Die Situation wird angezeigt, wenn Pysa am nützlichsten ist und der Code, in dem der Analysator nicht anwendbar ist. Details aus dem Facebook Engineering Blog unter dem Schnitt.
Letztes Jahr haben wir darüber geschrieben, wie wir Zoncolan erstellt haben , ein statisches Analysetool, das über 100 Millionen Zeilen Hack-Code analysiert und Ingenieuren hilft, Tausende potenzieller Sicherheitsprobleme zu vermeiden. Erfolg inspiriert Pysa - Python Static Analyzer. Der Parser basiert auf Pyre, dem Python-Tool zur Typprüfung von Facebook. Pysa arbeitet mit dem Datenfluss im Code. Die Analyse des Datenflusses ist nützlich, da Sicherheits- und Datenschutzprobleme häufig als Daten modelliert werden, die dorthin gelangen, wo sie nicht sein sollten.
Pysa hilft bei der Identifizierung vieler Arten von Problemen. Der Analysator prüft, ob der Code bestimmte interne Strukturen korrekt verwendet, um den Zugriff auf oder die Offenlegung von Benutzerdaten auf der Grundlage technischer Datenschutzrichtlinien zu verhindern. Darüber hinaus erkennt der Analysator häufig auftretende Sicherheitsprobleme bei Webanwendungen wie XSS und SQL-Injection. Wie Zoncolan hat das neue Tool dazu beigetragen, die Sicherheitsanstrengungen für Python-Anwendungen zu erhöhen. Dies gilt insbesondere für Instagram.
Pysa auf Instagram
Das größte Python-Repository auf Facebook besteht aus Millionen von Zeilen auf Instagram-Servern. Wenn Pysa mit einer vom Entwickler vorgeschlagenen Codeänderung ausgeführt wird, werden die Ergebnisse in etwa einer Stunde und nicht in den Wochen oder Monaten angezeigt, die für die manuelle Überprüfung erforderlich sind. Auf diese Weise können Sie ein Problem schnell genug finden und verhindern, damit es nicht in Ihre Codebasis gelangt. Die Ergebnisse der Überprüfungen werden je nach Art des Problems und dem Signal-Rausch-Verhältnis in der jeweiligen Situation direkt an den Entwickler oder die Sicherheitsingenieure gesendet.
Pysa und Open Source
Pysa-Quellcode und viele Problemdefinitionen stehen anderen Entwicklern offen, um den Code ihrer Projekte zu analysieren. Wir arbeiten mit serverseitigen Open Source-Frameworks wie Django und Tornado. Daher stellt Pysa beim ersten Start in Facebook Sicherheitsprobleme in Projekten fest, die diese Frameworks verwenden. Die Verwendung von Pysa für Frameworks, die noch keine Abdeckung haben, ist normalerweise so einfach wie das Hinzufügen einiger Konfigurationszeilen. Sie müssen dem Analysator nur mitteilen, woher die Daten zum Server stammen.
Pysa wurde verwendet, um Probleme wie CVE-2019-19775 in Open-Source-Python-Projekten zu erkennen. Wir haben auch mit dem Zulip-Projekt gearbeitet und schloss Pysa in seine Codebasis ein.
Wie es funktioniert?
Pysa wurde mit Lehren aus Zoncolan entworfen. Es verwendet dieselben Algorithmen, um statische Analysen durchzuführen, und teilt sogar Code mit Zoncolan. Wie Zoncolan überwacht Pysa den Datenfluss in einem Programm. Der Benutzer definiert die Quellen wichtiger Daten und die Ziele, an denen die Daten eingehen. In Sicherheitsanwendungen sind die häufigsten Arten von Quellen die Punkte, an denen benutzergesteuerte Daten in die Anwendung gelangen, z. B. das Wörterbuch HttpRequest.GET in Django. Empfänger sind im Allgemeinen viel vielfältiger und können die Ausführung von APIs umfassen. Zum Beispiel
evaloderos.open... Pysa führt iterativ Analyserunden durch, um Zusammenfassungen zu erstellen, um zu bestimmen, welche Funktionen Daten von der Quelle zurückgeben und welche Parameter das Ziel erreichen. Wenn der Analysator feststellt, dass die Quelle möglicherweise eine Verbindung zum Empfänger herstellt, meldet er das Problem. Die Visualisierung dieses Prozesses ist ein Baum mit einem Problem oben und Quellen und Flüssen in den Blättern:
Um eine prozedurübergreifende Analyse durchzuführen und den Datenfluss zwischen Funktionsaufrufen zu verfolgen, müssen Sie in der Lage sein, Funktionsaufrufe ihren Implementierungen zuzuordnen. Dazu müssen Sie alle verfügbaren Informationen im Code verwenden, einschließlich optionaler statischer Typen, falls vorhanden. Wir haben mit Pyre zusammengearbeitet, um diese Informationen herauszufinden. Während Pysa stark auf Pyre angewiesen ist und beide Tools dasselbe Repository verwenden, ist es wichtig zu beachten, dass dies separate Produkte mit separaten Anwendungen sind.
Fehlalarm
Sicherheitsingenieure sind die Hauptnutzer von Pysa auf Facebook. Wie jeder Ingenieur, der mit automatisierten Fehlererkennungswerkzeugen arbeitet, mussten wir herausfinden, wie mit falsch positiven (kein Problem, kein Signal) und negativen (kein Problem, kein Signal) umzugehen ist.
Pysas Design zielt darauf ab, Probleme nicht zu übersehen und so viele reale Probleme wie möglich zu erkennen. Das Reduzieren der Anzahl von Fehlalarmen kann jedoch Kompromisse erfordern, die die Anzahl unnötiger Alarme erhöhen. Zu viele Fehlalarme führen zu Angstmüdigkeit und dem Risiko, dass echte Probleme im Lärm übersehen werden. Pysa verfügt über zwei Tools zum Entfernen unerwünschter Signale: Desinfektionsmittel und Schilder.
DesinfektionsmittelIst ein einfaches Werkzeug. Der Parser wird angewiesen, dem Datenstrom nicht zu folgen, nachdem der Strom die Funktion oder das Attribut durchlaufen hat. Mit Desinfektionsprogrammen können Sie das Wissen zur Domänentransformation codieren, das Daten immer sicher und vertraulich darstellt.
Zeichen sind subtiler: Es handelt sich um kleine Teile von Metadaten, die Pysa während der Verfolgung an Datenströme anfügt. Im Gegensatz zu Desinfektionsmitteln entfernen Zeichen keine Probleme aus den Analyseergebnissen. Attribute und andere Metadaten können verwendet werden, um Ergebnisse nach der Analyse zu filtern. Filter werden normalerweise für ein bestimmtes Quelle-Ziel-Paar geschrieben, um Probleme zu ignorieren, wenn Daten bereits für einen bestimmten Typ (aber nicht alle Typen) eines Ziels verarbeitet wurden.
Um zu verstehen, in welchen Situationen Pysa am nützlichsten ist, stellen Sie sich vor, dass der folgende Code zum Laden eines Benutzerprofils ausgeführt wird:
# views/user.py
async def get_profile(request: HttpRequest) -> HttpResponse:
profile = load_profile(request.GET['user_id'])
...
# controller/user.py
async def load_profile(user_id: str):
user = load_user(user_id) # Loads a user safely; no SQL injection
pictures = load_pictures(user.id)
...
# model/media.py
async def load_pictures(user_id: str):
query = f"""
SELECT *
FROM pictures
WHERE user_id = {user_id}
"""
result = run_query(query)
...
# model/shared.py
async def run_query(query: str):
connection = create_sql_connection()
result = await connection.execute(query)
...
Hier kann eine potenzielle SQL-Injection in load_pictures nicht ausgenutzt werden: Diese Funktion wird immer
user_idvon der Funktion load_userin gültig load_profile. Bei korrekter Konfiguration wird Pysa wahrscheinlich kein Problem melden. Stellen Sie sich nun vor, ein unternehmungslustiger Ingenieur, der Code auf Controller-Ebene schreibt, erkennt, dass das gleichzeitige Abrufen von Benutzerdaten und eines Bildes schneller zu Ergebnissen führt:
# controller/user.py
async def load_profile(user_id: str):
user, pictures = await asyncio.gather(
load_user(user_id),
load_pictures(user_id) # no longer 'user.id'!
)
...
Die Änderung mag harmlos aussehen, führt jedoch dazu, dass die benutzergesteuerte Zeichenfolge
user_idmit dem SQL-Injection-Problem in zusammengeführt wird load_pictures. In einer Anwendung mit vielen Ebenen zwischen dem Einstiegspunkt und den Datenbankabfragen erkennt der Techniker möglicherweise nicht, dass die Daten vollständig vom Benutzer gesteuert werden oder dass das Injektionsproblem in der aufgerufenen Funktion verborgen ist. Dies ist genau die Situation, für die der Analysator geschrieben wurde. Wenn ein Techniker eine ähnliche Änderung auf Instagram vorschlägt, stellt Pysa fest, dass Daten von benutzergesteuerten Eingaben zu einer SQL-Abfrage übertragen werden, und meldet das Problem.
Einschränkungen des Analysators
Es ist unmöglich, einen perfekten statischen Analysator zu schreiben . Pysa hat Einschränkungen hinsichtlich Umfang, Datenfluss und Entwurfsentscheidungen, wodurch die Leistung hinsichtlich Genauigkeit und Genauigkeit beeinträchtigt wird. Python als dynamische Sprache weist einzigartige Merkmale auf, die einigen dieser Entwurfsentscheidungen zugrunde liegen.
Problemraum
Pysa wurde entwickelt, um nur Sicherheitsprobleme im Zusammenhang mit Datenströmen zu erkennen. Nicht alle Sicherheits- oder Datenschutzbedenken werden als Datenströme modelliert. Schauen Sie sich ein Beispiel an:
def admin_operation(request: HttpRequest):
if not user_is_admin():
return Http404
delete_user(request.GET["user_to_delete"])
Pysa ist nicht das richtige Tool, um sicherzustellen, dass
user_is_adminvor einem privilegierten Vorgang eine Berechtigungsprüfung ausgeführt wird delete_user. Der Analysator kann Daten von request.GETgerichtet an erkennen delete_user, diese Daten werden jedoch nie validiert user_is_admin. Sie können den Code neu schreiben, um das Problem Pysa-modelliert zu machen, oder Sie können die Berechtigungsprüfung in einen Verwaltungsvorgang einbauen delete_user. Dieser Code zeigt jedoch zunächst, welche Probleme Pysa nicht löst.
Ressourcenlimits
Wir haben eine Entwurfsentscheidung für die Einschränkungen getroffen, damit Pysa die Analyse abschließen kann, bevor die vorgeschlagenen Änderungen in die Codebasis gelangen. Wenn der Analysator Datenströme in zu vielen Attributen eines Objekts überwacht, müssen Sie manchmal das gesamte Objekt vereinfachen und so behandeln, dass es genau diese Daten enthält. Dies kann zu Fehlalarmen führen.
Eine weitere Einschränkung ist die Entwicklungszeit. Es wurde ein Kompromiss erzwungen, welche Python-Funktionen unterstützt werden. Pysa nimmt beim Aufrufen von Funktionen noch keine Dekoratoren in das Aufrufdiagramm auf und überspringt daher Probleme innerhalb der Dekoratoren.
Python als dynamische Sprache
Die Flexibilität von Python erschwert die statische Analyse. Es ist schwierig, Datenströme durch Methodenaufrufe ohne Typinformationen zu verfolgen. Im folgenden Code kann nicht bestimmt werden, welche der Implementierungen
flyaufgerufen wird:
class Bird:
def fly(self): ...
class Airplane:
def fly(self): ...
def take_off(x):
x.fly() # Which function does this call?
Der Analysator arbeitet in völlig untypisierten Projekten. Es ist jedoch wenig Aufwand erforderlich , um die wichtigen Typen abzudecken.
Die Dynamik von Python führt zu einer weiteren Einschränkung. Siehe unten:
def secret_eval(request: HttpRequest):
os = importlib.import_module("os")
# Pysa won't know what 'os' is, and thus won't
# catch this remote code execution issue
os.system(request.GET["command"])
Die Ausführungsanfälligkeit ist hier deutlich sichtbar, wird jedoch vom Analysator übersprungen. Das Modul wird
osdynamisch importiert. Pysa versteht nicht, dass die lokale Variable os genau das Modul darstellt os. Mit Python können Sie fast jeden Code jederzeit dynamisch importieren. Darüber hinaus kann die Sprache das Verhalten eines Funktionsaufrufs für fast jedes Objekt ändern. Pysa kann lernen, das Betriebssystem zu analysieren und das Problem zu erkennen. Aufgrund der Dynamik von Python gibt es jedoch endlose Beispiele für pathologische Datenströme, die der Analysator nicht sehen wird.
Ergebnisse
Im ersten Halbjahr 2020 machte Pysa 44 Prozent aller auf Instagram entdeckten Probleme aus. Unter allen Schwachstellentypen wurden 330 eindeutige Probleme bei den vorgeschlagenen Codeänderungen festgestellt. 49 (15%) Probleme erwiesen sich als signifikant, 131 der Probleme (40%) waren real, hatten jedoch mildernde Umstände. In 150 Fällen (45%) wurden falsch negative Ergebnisse verzeichnet.
Wir überprüfen regelmäßig gemeldete Probleme auf andere Weise. Zum Beispiel über das Bug Bounty-Programm. So stellen wir sicher, dass wir alle falsch negativen Signale korrigieren. Die Erkennung jeder Art von Sicherheitsanfälligkeit ist konfigurierbar. Durch ständige Weiterentwicklung sind Sicherheitsingenieure zu anspruchsvolleren Typen übergegangen, um tatsächliche Probleme zu 100 Prozent zu melden.
Insgesamt sind wir mit den Kompromissen zufrieden, die wir eingegangen sind, um Sicherheitsingenieuren bei der Skalierung zu helfen. Aber es gibt immer Raum für Entwicklung. Wir haben Pysa entwickelt, um die Codequalität durch die enge Zusammenarbeit zwischen Sicherheitsingenieuren und Programmierern kontinuierlich zu verbessern. Auf diese Weise konnten wir schnell iterieren und ein Tool erstellen, das unseren Anforderungen besser entspricht als jede sofort einsatzbereite Lösung. Die Zusammenarbeit der Ingenieure führte zu Ergänzungen und Verfeinerungen der Pysa-Bewegungen. Beispielsweise hat sich die Art und Weise, wie Sie die Problemablaufverfolgung anzeigen, geändert. Es ist jetzt einfacher, falsche Negative zu erkennen.
Dokumentation und Tutorial zum Pysa-Analysator .
Erfahren Sie in Online-Kursen zu SkillFactory, wie Sie einen hochkarätigen Beruf von Grund auf neu aufbauen oder Ihre Fähigkeiten und Ihr Gehalt verbessern können:
- «Python -» (9 )
- «Python » (2 )
- Python (10 )
E
- Machine Learning (12 )
- «Machine Learning Pro + Deep Learning» (20 )
- « Machine Learning Data Science» (20 )
- Data Science (12 )
- - (8 )
- (9 )
- DevOps (12 )
- Java- (18 )
- JavaScript (12 )
