PHP, Ajax und Sicherheit

  • Hallo zusammen,


    ich hänge gedanklich gerade an einer Stelle, bei der nun die Profis vermutlich die Hände über dem Kopf zusammenschlagen.


    Ich werkle an einer Applikation, welche ich über Vue (bzw. Quasar). Über Ajax greife ich zudem auf Inhalte von MySQL zu, wozu ich mir wiederum auf dem Server entsprechende PHP Skripte erstellt habe.


    Da es sich somit um eine Applikation handelt, von der im Grunde der komplette Quellcode im Browser als Javascript einsehbar ist, habe ich mich gefragt, was einen Angreifer davon abhalten würde, den Code zu kopieren und somit einfach eigene Anfragen an das PHP/MySQL zu senden. Da könnte der Angreifer dann ja walten, wie er wollte.


    Meine Frage nun: Kann ich das über z.B. HTACCESS einfach verhindern, dass das PHP Skript von einem fremden Server aufgerufen wird? Oder ist das quasi sowieso nicht möglich?`


    Vielen Dank für Hinweise :)

    DIrk

  • Hallo,


    natürlich kann jeder, der möchte, die Anfragen in der Browser Konsole einsehen und kopieren. Dagegen kannst du auch meiner Meinung nach nicht viel machen.


    Wenn die Abfragen via Ajax wirklich so sensibel sind, solltest du vielleicht einen Login bauen?

    Du könntest im PHP Script abfragen, ob der User, der die Ajax anfrage stellt, eingeloggt ist, und dann dementsprechend reagieren.


    Das würde den User natürlich nicht davon abhalten, die Ajax abfragen zu manipulieren, aber du hättest bessere Kontrolle, wer überhaupt an die Daten gelangt.

  • Hi,


    du solltest auf gar keinen Fall SQL-Statements vom Client zulassen. Sobald ein Angreifer einmal in deinem Quellcode gesehen hat wie's geht kann er ja sonst auch mit anderen Tools solche Abfragen auf deine Datenbank starten.


    Stattdessen sollte dein PHP-Code die Anfragen selbst formulieren und nur einzelne Informationen vom Client darin mit aufnehmen. Diese Daten sollten auch escaped werden, um dich vor SQL Injection zu schützen, bzw. am besten werden prepared statements verwendet.


    Wenn dir das noch nicht weiterhilft, zeig doch vielleicht mal ein bisschen Code, dann kann man konkretere Tipps geben :)

  • Natürlich sind die SQL Statements NICHT im Client, sprich Browser zu sehen. Das SQL steht in der PHP Datei und der Browser ruft diese mit den maximal notwendigen Infos auf, um die Anfrage zu steuern.


    Das Konzept der Prepared Statements kannte ich als Begriff noch nicht (danke für den Tipp), auch wenn dies bereits so ähnlich schon umgesetzt ist.


    Was den Login betrifft: Aber nehmen wir einmal an, auch die Login-Anfrage ist über Ajax implementiert, da die Anwendung eine SPA ist und nur die Möglichkeit hat, über Ajax zu kommunizieren.


    Im Grunde war eben eine Überlegung sicherzustellen, dass z.B. das PHP Skript nur von einem bestimmten Server angesprochen wird.

    Oder arbeitet man da gar besser mit asynchroner Verschlüsselung der Parameter?

  • Die Kernfrage sollte sein: Sind die Eingaben oder Ausgaben Deiner PHP-API (ist im Grunde ja nichts anderes) geheim oder sowieso für die Öffentlichkeit bestimmt? Falls Ersteres zutrifft, wirst Du um ein Login/Session System nicht herumkommen.


    Die Anfragen zu verschleiern oder anderweitig zu verschlüsseln ist bei JavaScript, das im Browser ausgeführt wird, völlig sinnbefreit. Durch die eingebauten Debuggingtools jedes Browsers, die selbst Laien bedienen können, erreicht Du damit gar nichts.


    Fakt ist, Du kannst nicht limitieren, von wo das PHP-Script angesprochen wird. Die Anfragen kommen von den Clients und damit aus einer Umgebung, die Du nicht unter Kontrolle hast. Da ist alles manipulierbar, es ist immer nur ein Katz und Mausspiel. Sorge lieber dafür, dass keine Sicherheitslücken existieren und nur jene Informationen abgerufen werden können, für die ein User die Berechtigung hat.


    Ohne weitere Details, wird man Dir nur schwer gezielte Tipps geben können. Das sind die allgemeinen Hinweise, die wir Dir geben können.

  • Nachdem ich meine letzte Nachricht abgeschickt hatte, fiel mir auch auf, dass dies ein wenig sinnbefreit ist. Da man ja den JS Quellcode sieht, bringt ja auch eine asynchrone Encryption nix, weil man ja die Keys bräuchte. Bitte mal ignorieren, diesen geistigen Fehlgriff :)


    Ja, es ist eine PHP-Api, genau. Geheim soll dabei sein, dass man sich als Nutzer in einen Bereich einloggt und in diesem dann eben Inhalte bekommt, die zu einem gehören. Für den eingeloggten Nutzer ist es somit nicht geheim, aber es soll auch nicht möglich sein logischerweise, dass man auf Inhalte, welche zu einem anderen Nutzer gehören, zugreifen kann.

    Aber ich kann doch im PHP checken, von wo die Anfrage kommt und somit IPs etc limitieren?


    Die Grundgedanken der Anwendung sind im Grunde wie folgt:


    1. Es ist eine SPA, bei der nur einzelne, user-bezogene Inhalte dynamisch aus einer MySQL Datenbank kommen. Neben öffentlichen Seiten gibt es eben auch einen internen Bereich.

    2. User loggt sich mit seinen Zugangsdaten ein, dieser Login-Vorgang läuft auch über Ajax (Axios)

    3. Wenn User verifiziert werden kann, so sieht er nun eben auf einer "internen" Seite persönliche Infos etc.

  • Aber ich kann doch im PHP checken, von wo die Anfrage kommt und somit IPs etc limitieren?

    Klar, du kannst immer eine Session ID, z.B. über Cookies mitschicken - bei SPA bieten sich auch JWT (JSON Web Token) an, die kannst du sogar serverseitig signieren und auf dem Server die Signatur wieder prüfen, damit du weißt, dass die Inhalte des Tokens nicht manipuliert werden.


    Irgendwie musst du also eine Sitzungs ID zwischen Browser und Server kommunizieren - diese Sitzungs ID kannst du dann zusammen mit dem Nutzernamen in einer Datenbank speichern, oder das PHP Session ID verwenden (hier wird auf dem Dateisystem gespeichert). Den Benutzernamen kannst du dir aber auch aus dem signierten JWT nehmen.

  • Wobei ich anmerken möchte, dass eine simple PHP-Session in den meisten Fällen absolut ausreicht und theoretisch auch sicherer umgesetzt werden kann (über ein HttpOnly-Cookie vs. den JWT z.B. im localStorage des Browsers).


    JWT ist sinnvoll für die Verwendung zwischen verteilten Systemen, aber für eine einfache SPA unter der gleichen Domain wie die API eher Overkill. Alleine weil man Token refreshing noch ordentlich umsetzen muss.

  • Okay, logisch. Aber dann sehe ich in dem Einsatz von JWT gegenüber Sessions eigentlich nur noch Nachteile (z.B. JWT verlängert sich nicht automatisch sondern muss refreshed werden mit Hilfe eines zweiten Tokens ...)

    Müssen andere Sitzungssysteme auch. Nicht alle Backends laufen auf PHP und nicht jedes System nutzt die eingebauten PHP Sessions.

    Der Vorteil von signierten JWT ist, dass du über mehrere Backend Server Daten austauschen kannst, ohne Datenbank oder Dateisystemablage. Die Systeme müssen sich nur ein Signaturschlüssel teilen.

  • Ja genau, das ist ja letztlich was ich oben schrieb:

    JWT ist sinnvoll für die Verwendung zwischen verteilten Systemen, aber für eine einfache SPA unter der gleichen Domain wie die API eher Overkill.

    Warum ich so darauf herumreite: Es gibt haufenweise Tutorials im Netz die JWTs als das Mittel der Wahl für SPAs darstellen, und Entwickler denen das Konzept neu ist bauen das nach ohne zu hinterfragen. Und dann steht der Token am Ende doch im localStorage und ggf. spart man sich sogar die Refresh-Logik, was zu einer schlechten Nutzererfahrung führt, da man irgendwann plötzlich ausgeloggt wird. Oder noch schlimmer (habe ich leider schon oft genug in freier Wildbahn gesehen): Man verpasst dem Token kein Ablaufdatum. Dann hat man Tokens verteilt die man nicht revoken kann (außer natürlich man ändert das Secret für alle Tokens).


    Insgesamt ist Authentifizierung mittels JWT deutlich komplexer und es ist auch schwerer das sicher und vollständig zu implementieren, daher meine Empfehlung wenn man einfach nur einen normalen User-Login umsetzen möchte und PHP nutzt (in anderen Sprachen wie JS/NodeJS gibt es auch diverse Frameworks die das können): Sessions nutzen :)

  • Warum ich so darauf herumreite: Es gibt haufenweise Tutorials im Netz die JWTs als das Mittel der Wahl für SPAs darstellen, und Entwickler denen das Konzept neu ist bauen das nach ohne zu hinterfragen.

    Da hast du natürlich recht - da greift meine Betriebsblindheit.



    Ja genau, das ist ja letztlich was ich oben schrieb:

    Nanu, hattest du deinen Beitrag noch editiert oder habe ich das schlicht überlesen?