Wie Sie wissen, zielen die meisten Angriffe von BlackHat-Hackern darauf ab, die Serverdaten von Webanwendungen und -diensten zu gefährden. Gleichzeitig wird der Client-Teil zumindest heute angegriffen. Nach der trockenen Definition ist jeder Angriff eine Reihe von Maßnahmen eines Hackers, die auf die Netzwerk- und Datenübertragung, die Daten und deren Substitution, die Infrastruktur und die technischen Merkmale der Implementierung der Webanwendung abzielen. Aus diesem Grund verlangen internationale Unternehmen von Entwicklungsingenieuren einen verantwortungsbewussteren und gründlicheren Umgang mit der Sicherheit von Clientanwendungen.
Am Beispiel meines Projekts werde ich darüber sprechen, wie Clientanwendungen heute angreifen und wie Sie diese Bedrohungen vermeiden können.
Top 10 Bedrohungen für 2013 - 2017.Wie Sie sehen, stehen unter den Hauptbedrohungen Injektion, Fehlerauslösung, Umgehung der Authentifizierung und unsichere vertrauliche Daten an erster Stelle. Die Gefahr der Verwendung von Komponenten mit bekannten Sicherheitslücken ist weiterhin relevant. Es traten auch neue Bedrohungen auf: Hacking des Zugriffskontrollmechanismus, unsichere Deserialisierung und Serialisierung von Daten, unzureichend detaillierte Protokollierung und Überwachung.
Im Jahr 2001 gründeten Mark Curfy und Dennis Groves das OWASP (Open Web Application Security Project). Dies ist ein internationales OpenSource-Projekt für den Erfahrungsaustausch zur Bekämpfung von Schwachstellen in Clientanwendungen, an dem eine große Anzahl von Anwendungssicherheitsingenieuren teilnimmt. Die OWASP-Community füllt das Portal mit einer Vielzahl von Artikeln mit Informationen zu Sicherheitslücken, Schulungsmaterialien, Tools zum Testen und Abwehr von Angriffen. Echte Angriffe werden beschrieben, ihre Aspekte werden aufgedeckt und es wird beschrieben, was getan werden muss, um Bedrohungen zu verhindern.
Um zu verstehen, welche Bedrohungen für ein Projekt gefährlich sind, müssen Sie es gründlich testen. Zu diesem Zweck verfügt das Netzwerk über Anwendungen, Frameworks und Onlinedienste, die bestimmte Schwachstellen automatisch identifizieren. Für lokale Tests empfehle ich die Verwendung von Anwendungen und Frameworks. Für das Testen von Projekten im Betrieb ist es sehr nützlich, auch Onlinedienste hinzuzufügen.

Aber auch wenn die Testtools Sie in Berichten nicht über signifikante Schwachstellen informiert haben (was unwahrscheinlich ist), sollten Sie dennoch darauf achten, vertrauliche Daten im Versionskontrollsystem zu speichern, die Anwendung, den Authentifizierungsmechanismus, den Kennwort-Hashing-Algorithmus, die Verschlüsselung vertraulicher Daten sowie Protokollierungssysteme zu erstellen und Überwachen der gesamten Webanwendung. In diesem Fall ist es besser, auf Nummer sicher zu gehen und nicht blind auf Automatisierung zu vertrauen.
Git
Lassen Sie uns zunächst über vertrauliche Daten in Git sprechen. Im Idealfall wird ein separates Repository mit Geheimnissen zum Speichern vertraulicher Daten zugewiesen. Während der Montage zur Inbetriebnahme werden vertrauliche Daten abgerufen und in die Anwendung eingenäht. Heute sind Hashicorp Vault, Keywhiz, Docker-Geheimnisse, Azure Key Vault und eine Reihe anderer beliebt.
Aber was ist, wenn Sie keinen solchen Speicher haben? Sie können Tools verwenden, um Dateien mit Geheimnissen zu verschlüsseln und auszublenden, wodurch die Funktionen von Versionskontrollsystemen erweitert werden.
Das erste, was mir in den Sinn kommt, ist die universelle BlackBox-Lösung. Es kann mit jedem Versionskontrollsystem verwendet werden, z. B. Mercurial, Git usw. Darüber hinaus gibt es zwei Erweiterungen für Git: git-crypt und git-secret. Ich empfehle die Verwendung der zweiten, da sie mir am bequemsten zu verwenden und in Bezug auf die Beschreibung in der offiziellen Dokumentation verständlicher erscheint. Nach der Installation von git-secret müssen Sie es im Git-Repository initialisieren. Denken Sie daran, die zu verwendende Erweiterung in der .gitattributes- Datei anzugeben . Konfigurieren Sie als Nächstes die Zugänglichkeit von Geheimnissen: Identifizieren Sie die Benutzer, denen Sie Zugriff auf vertrauliche Daten gewähren möchten. Fügen Sie dann Dateien mit vertraulichen Daten hinzu und git-secret-hide
sie über git-secret-hide
. Sie können versteckte Dateien durch git-secret-reveal.
brew install git-secret //
git secret init //
git secret tell your@gpg.email  //
git secret add <files...> //
git secret hide  //
git secret reveal  //
Webpack
Eine andere Möglichkeit, Bedrohungen zu beseitigen, besteht darin, das Webpack korrekt zu konfigurieren. Zum Schutz vor XSS-, XEE- und ähnlichen Angriffen müssen Sie die Richtlinien CORS (Cross-Origin Resource Sharing) und CSP (Content Security Policy) einhalten. In beiden Fällen ist es wichtig, den Überschriften zu folgen, um die Richtigkeit bestimmter im Projekt verwendeter Skripte zu überprüfen. Browser verfügen über Mechanismen zum Überprüfen der Zuverlässigkeit einer bestimmten Quelle. Safari gibt beispielsweise bei jedem Schritt Warnungen aus, wenn CORS und CSP falsch konfiguriert sind.
Es gibt zwei Möglichkeiten, CORS und CSP einzuhalten. Die erste besteht darin, die Header für die Beantwortung von Anforderungen auf der Serverseite zu konfigurieren. Die zweite besteht darin, beide Richtlinien über Meta-Tags und Attribute zu registrieren. Die letztere Methode wird empfohlen, wenn Sie faule Back-End-Entwickler haben, diese immer beschäftigt sind und kein Interesse an Sicherheitsrichtlinien haben. Meta-Tags können sofort beim Erstellen der Anwendung registriert werden. Plugins wie das HTML-Webpack-Plugin, das HTML-Webpack-Exclude-Assets-Plugin, das Script-Ext-HTML-Webpack-Plugin, das csp-HTML-Webpack-Plugin und Crypto helfen uns dabei. Wenn Sie in Ihrem Projekt Ressourcen von Drittanbietern haben (z. B. Links zu externen Schriftarten, die in CSS verwendet werden; von CDN geladene Ressourcen usw.), empfehle ich außerdem, das Webpack-Subresource-Integrity-Plugin zu verwenden. Auf diese Weise werden Sie den Browser darüber informieren, dass die im Skript geladenen Ressourcen zuverlässig sind, keine Injektionen enthalten, vollständig und unberührt sind. Und selbst wenn jemand schädliche Daten in die Ressource eingefügt hat und Sie diese hochgeladen haben, müssen Sie darauf vorbereitet sein und Ihr Projekt vor solchen Bedrohungen schützen.
Ich möchte besonders auf die Reihenfolge achten , in der die Klasseninstanzen für die Plugins erstellt werden. Die Reihenfolge sollte genau so sein:
const SHA256 = (str) => CRYPTO.createHash('sha256').update( str, 'utf8').digest('base64'); const sha256Str = SHA256( '' + Date.now() ); […] new HtmlWebpackPlugin({ filename: 'index.html', template: 'public/index.html' }), new ScriptExtHtmlWebpackPlugin({ custom: [{ test: /\.js$/, attribute: 'nonce', value: 'nonce-' + sha256Str }] }), new HtmlWebpackExcludeAssetsPlugin(), new CspHtmlWebpackPlugin({ 'base-uri': '\'self\'', 'object-src': '\'none\'', 'script-src': ['\'self\'', '\'unsafe-eval\'', '\'nonce-' + sha256Str + '\''], 'style-src': ['\'unsafe-inline\'', '\'self\''] }, { devAllowUnsafe: false, enabled: true, hashingMethod: 'sha256' }), new SriPlugin({ hashFuncNames: ['sha256', 'sha384'], enabled: true }), […]
Während der Montage zeigt das <hed>
dann das Meta-Tag http-equiv=content-security-policy
. Anweisungen werden in das content
, das angibt, welchen Skripten und Ressourcen vertraut werden kann.
Die base-uri
Direktive zeigt an, welche Basis-URL zum Laden von Skripten, CSS, Bildern und mehr verwendet wird.
Objekte werden normalerweise nicht geladen, setzen Sie also none
auf die Anweisung object-sr
c.
Die Anweisung script-src
gilt für JS-Skripte.
Vergessen Sie nicht, jedes Mal ein Attribut vom Typ nnce-<hshVlue>
zu registrieren. Darüber hinaus muss der Hash mit dem SHA256- oder SHA512-Algorithmus berechnet werden.
Was die style-src
Direktive style-src
, hat unser Projekt eine Besonderheit: Wir verwenden styled-Komponenten, um CSS für jede Komponente zu schreiben und sie voneinander zu isolieren. Und deshalb muss angegeben werden, dass in uns style-src
unsafe-inline
und self
in style-src
, andernfalls fallen gestylte Komponenten ab.

Das script
Tag wird automatisch auf nnce-<hshVlue>
, integrity
und cross-origin
. Sie teilen dem Browser mit, dass Ressourcen aus zuverlässigen Quellen abgerufen werden. Wenn der Browser andernfalls feststellt, dass die Ressource nicht mit CSP oder CORS übereinstimmt, wird dieses Skript oder die CSS-Datei einfach nicht geladen, und es wird Folgendes in die Konsole geschrieben: "Achten Sie auf dieses Skript in dieser Zeile, in der Sie initialisieren." ihn. Schau, du hast etwas falsch gemacht! " .
Die MDN- , OWASP- und W3C- Dokumentation enthält Richtlinien zum Durchsetzen von CSP- und CORS-Richtlinien. Darüber hinaus melden alle Penetrationstest-Tools die Einhaltung der CORS- und CSP-Regeln im Projekt. Jedes Framework oder Tool, das automatische Tests eines Projekts durchführt, weist auf Mängel hin.
Benutzerauthentifizierung
Wir verwenden OpenID Connect und das Kerberos-Protokoll. Ein ziemlich verbreiteter OpenID-Standard wird verwendet, um externe Benutzer zu authentifizieren.
Kerberos eignet sich besser für das interne Netzwerk, in der Bank wird es zur automatischen Authentifizierung von Mitarbeitern verwendet. Angenommen, es gibt einen lokalen Computer, auf dem ein Mitarbeiter der Organisation arbeitet. Er hat sich einmal auf diesem Computer authentifiziert und muss dann nirgendwo den Login und das Passwort erneut eingeben: Der Mitarbeiter meldet sich bei einer Anwendung an und das System authentifiziert sie sofort. Kerberos verfügt über subtile Einstellungen für den lokalen Computer. Dies ist schwierig, da es für jeden Computer und jeden Browser konfiguriert werden muss . Wenn Internet Explorer normalerweise die Standardeinstellungen und Chrome die IE-Einstellungen aufruft, muss Firefox diese separat konfigurieren. Safari unter MacOS X findet die Einstellungen selbst, aber für Safari unter Windows müssen Sie sie manuell angeben.
Sie müssen Ihre Anwendung in allen Browsern überprüfen, ob sie überall ordnungsgemäß funktioniert. Wenn ich beispielsweise unter Windows arbeite, installiere ich Safari lokal und teste mein Projekt darin. Wenn ich unter Mac arbeite, rufe ich Windows in einer virtuellen Maschine auf, um die Anwendung auf den entsprechenden Browserversionen auszuführen.
Die Authentifizierung kann in modernen Anwendungen mithilfe von Passport.js und Express-Session-Paketen sowie des Auth0-SDK implementiert werden.
Wenn Sie keinen Authentifizierungsdienst über OpenID Connect oder ein anderes Protokoll entwickeln können, verwenden Sie eine Proxy-Schicht wie Auth0 und dergleichen, sodass die Authentifizierung über ein Drittunternehmen erfolgt, das darauf spezialisiert ist, Benutzern einen sicheren Zugriff auf Internetressourcen zu ermöglichen.
Wenn wir eine Anwendung auf Node.js aktualisieren, empfehlen wir die Verwendung von Passport.js-, Express-Session- usw. Paketen auf dem Server. Um die Sicherheit auf dem Client zu gewährleisten, erhöhen wir die Komponente unabhängig für die Authentifizierung. Vergessen Sie nicht, das Attribut "Autocomplete off" im Authentifizierungsformular anzugeben, um die automatische Vervollständigung der Formularfelder auszuschließen.
Passwort-Hashing
Auf der OWASP-Website wird empfohlen, keine in die Datenbank integrierten Kennwort-Hashing-Mechanismen zu verwenden. Hierzu ist es besser, Pakete wie Argon2, PBKDF2, ccrypt und bcrypt zu verwenden. In meiner Praxis verwende ich Argon2 - dies ist ein Wrapper für GCC-, PGP / GPG-Algorithmen usw., aber Sie müssen zuerst das GCC-Paket installieren. Argon2-Verwendungsschema:
1. GCC >= 4.8 install $ brew install gcc
2. - $ npm install -g node-gyp
3. Argon2 $ npm install argon2
4. import * as ARGON from 'argon2'; ARGON.generateSalt().then( (salt: string) => { ARGON.hash('some-user-password', salt) .then((hash : string) => { console.log('Successfully created Argon2 hash:', hash);
Verschleierung
Durch die Verschleierung können Sie den Code so ändern, dass er nicht in Komponenten analysiert werden kann. Schließlich verwenden Angreifer - und nicht nur sie - sehr oft Reverse Engineering: Der Programmierer nimmt eine JS-Datei und beginnt mit der Analyse der Quellen. Auf diese Weise kann er die verwendeten Methoden erlernen oder den Arbeitsmechanismus eines bestimmten Skripts verstehen, um schädlichen Code zu implementieren. Oder verwenden Sie diese Mechanismen, um eine Webanwendung zu hacken und einen Stealth-Angriff durchzuführen.
Hacker geraten nicht in Schwierigkeiten. Zunächst untersuchen sie die Ressource, ermitteln die Schwachstellen und den Angriffsvektor. Beispielsweise manipulieren sie Daten oder nutzen Schwachstellen in Transportprotokollen aus. Der Angriffsvektor kann auf die Schwachstellen eines bestimmten Betriebssystems abzielen, von denen es in jedem UNIX-System viele gibt. Sicherheitslücken können jedoch nur verwendet werden, wenn der Administrator schlecht konfigurierte Sicherheitsrichtlinien hat, z. B. falsch festgelegte URLs, die nach draußen gehen.
Zur Aufklärung wird also Reverse Engineering verwendet. Es ist unmöglich, es vollständig auszuschließen, aber es kann sehr schwierig sein. Dafür werden in meinem Fall verschiedene Obfuscatoren verwendet - Javascript-Obfuscator. Darauf aufbauend wird ein Plugin für Webpack erstellt - Webpack-Obfuscator. Auch für Webpack erstellt Obfuscator-Loader. Dieses Paket enthält empfohlene Einstellungen für verschiedene paranoide Ebenen: niedrig, mittel und hoch. Sie finden sie auf der offiziellen Website. Wenn Sie diesen Verschleierer verwenden, denken Sie daran, dass er mit dem in das Webpack integrierten Minifizierungsmechanismus sehr schlecht funktioniert. Verwenden Sie Minifizierung und Verschleierung nicht zusammen, da der Verschleierer sonst den Skriptcode vollständig beschädigen kann.
Darüber hinaus erhöht der Obfuscator die Lautstärke des Skripts und dessen Laden. Hier müssen Sie selbst entscheiden: Entweder Sie verbessern die Sicherheit, Stabilität und Zuverlässigkeit, verlieren aber an Komfort und Geschwindigkeit. Achten Sie entweder auf die Geschwindigkeit, aber vergessen Sie die Sicherheit und befolgen Sie die Richtlinien.
Bedrohungsprotokollierung und -überwachung
Es besteht eine solche Bedrohung wie die Verwendung von Paketen mit bereits bekannten Sicherheitslücken. Bedrohungsanalysatoren wie npm audit, Snyk und LGTM helfen in solchen Situationen. Npm Audit ist ein Standarddienstprogramm, das in npm integriert ist. Sie müssen diesen Befehl jedoch ständig aufrufen oder Krücken entwickeln. Daher rate ich Ihnen, Snyk zu verwenden. Dieses Projekt verfügt über eine eigene Datenbank mit Schwachstellen. Wenn Sie den Test starten, greift Snyk auf diese Datenbank zu und lädt den Bericht vertraulich in Ihr Snyk-Projekt hoch, auf das Außenstehende keinen Zugriff haben. Sie können Ihr Projekt zwar nur 300 Mal kostenlos überprüfen, und wenn Sie jedes Pre-Commit überprüfen, werden diese 300 kostenlosen Versuche sehr schnell beendet. Daher ist es besser, einen Test für Pre-Push- oder Pre-Merge-Hooks durchzuführen.
Der Mensch ist die wichtigste Verwundbarkeit eines Systems. Überprüfen Sie daher unbedingt das Projekt, bevor Sie mit dem Erstellen der Anwendung beginnen, da selbst der Quellcode möglicherweise etwas Bösartiges enthält. Es ist gut, wenn nur eine Person Zugriff auf das Projekt hat, aber normalerweise arbeiten wir als Teams. Was wäre, wenn eine Art „Wohltäter“ auftauchte, der sich entschied, das Unternehmen „wunderschön“ zu verlassen und Spuren zu hinterlassen? Dies muss auch berücksichtigt werden.
Ich empfehle, das Snyk-Paket von Anfang an zu verwenden und den Scan von der Konsole aus zu starten. Hier ist alles einfach: Legen Sie nach der Installation das Login und das Passwort für das Konto fest, und der Test selbst kann folgendermaßen durchgeführt werden:
- Nach der Installation von npm i snyk —D Abhängigkeit und Angabe von "snyk": true in package.json, führen Sie Folgendes aus:
./node_modules/.bin/snyk wizard --dev
- Fügen Sie in package.json Skripte und Einstellungen hinzu:
{ ... "scripts": { ... "test": "npm run test:snyk && npm run test:jest", ... "test:snyk": "snyk test --dev", ... "prepare": "npm run prepare:snyk", "prepare:snyk": "snyk protect" }, "husky": { "hooks": { "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", "pre-commit": "npm run test:snyk && npm run lint && npm run test:jest", "pre-push": [ "npm run test:snyk", "npm run lint", "npm run test:jest", "npm run build:production" ], ... } }, "snyk": true }
Oben haben wir uns eine lokale Überprüfung auf Sicherheitsbedrohungen angesehen. Um Pakete auf bekannte Bedrohungen zu überprüfen, empfehle ich außerdem die Verwendung von LGTM. Verwenden Sie dieses Projekt in Verbindung mit GitHub oder Bitbucket (bis Sie es ausprobiert haben, war es nicht erforderlich), und der Code wird bei jedem Push sofort überprüft.
Anwendungsüberwachung
Im Bereich Front-End sind die Tools bereits gut etabliert. Für die Protokollierung und Überwachung des Client-Teils stehen Tools für jeden Geschmack zur Verfügung. Die bekanntesten sind Sentry, TrackJS und InsightOps. Sentry Server kann auf seinen physischen Servern bereitgestellt werden. In unseren beiden Projekten haben wir beispielsweise einen separaten Server verwendet, der vollständig für die Protokollierung des Betriebs von Anwendungen konfiguriert wurde. Wir gingen zur URL und legten dort alle Protokolle ab. Wenn in der Anwendung ein Fehler auftritt, wird dieser in einen try catch-Block eingeschlossen und über die Raven-Paketmethoden an den Sentry-Server gesendet. Alles ist einfach und bequem. Wenn in Sentry undurchsichtige URLs angezeigt werden, die Sie nicht registriert haben, wenn Sie Einbettungen oder undurchsichtige Nachrichten sehen, versuchen diese, Sie zu hacken. In meiner Praxis passierte dies regelmäßig. Zum Beispiel versuchte eines der Projekte - ein Dienst zur Umgehung von Werbeblockern und Antivirenprogrammen - ständig, dem entgegenzuwirken und es zu knacken.
Zur Überwachung empfehle ich auch die Verwendung von Grafana. Es ist wichtig, ein System von Kriterien und Indikatoren zu berücksichtigen, die vom System überwacht werden. Wir haben den Datenverkehr, die Rückgabe von Werbung, den Grad der Anzeigenwiedergabe, die Anzahl der von Yandex stammenden Banner usw. eingestellt. (Projekte in der Rambler Group). Wir mussten verstehen, wie Yandex mit unseren Anfragen arbeitet, da es sich um einen Drittanbieter-Service handelt. Dies bedeutet, dass er überwacht werden muss. Wenn dies fehlschlägt, kann das gesamte Projekt vollständig zusammenbrechen.
Wenn Sie die gesamte Kommunikation mit Diensten von Drittanbietern überwachen, werden Sie sehr schnell einen Fehler finden. Die Geschichte stammt aus meiner Praxis: Wir haben gesehen, dass bei Yandex die Werbeantworten scharf aufgehört haben. Es stellte sich heraus, dass sie technische Störungen hatten und das gesamte Werbenetzwerk eng zusammenbrach. Und es war nicht Yandex, der uns zuerst informierte, sondern wir riefen sie an und fragten sie, was mit ihren Diensten geschah.
Was ist der beste Weg, um zu überwachen? Nehmen Sie eine kleine URL, schreiben Sie die GET-Parameter und senden Sie eine GET-Anfrage an diese URL. Verarbeiten Sie diese URL auf der Serverseite, schreiben Sie das Protokoll in die Datenbank und erhöhen Sie die Überwachung auf Grafana. Alles ist einfach.
Das ist alles In Zukunft werde ich versuchen, weiter über das Thema des Schutzes von Webanwendungen vor Bedrohungen zu schreiben. An alle, die bis zum Ende gelesen haben - ich wünsche Sicherheit für Ihre Projekte)))
Liste der Quellen zum Lesen zum Thema:
www.owasp.org/index.php/Main_Page
tproger.ru/translations/webapp-security
S. Hawks. Noch schnellere Einzelseitenanwendung: Sicherheit
Seacord, Robert C. Der CERT C-Standard für sichere Codierung / Robert C. Seacord. - 2008
Chetan Karande. Sichern von Knotenanwendungen - 2017
Steven Palmer. Sicherheitsanfälligkeiten in Webanwendungen erkennen, ausnutzen, verhindern - 2011
Robert Shimonski, Sean-Philip Oriyano. Clientseitige Angriffe und Verteidigung - 2012
Marcus Pinto, Dafydd Stuttard. Das Handbuch für Hacker von Webanwendungen: Auffinden und Ausnutzen von Sicherheitslücken, 2. Ausgabe - 2011
Karl Duuna. Sichern Sie Ihre Node.js-Webanwendung - 2015