Linuchs: Angriff auf Datenbank - neuen User anlegen

Moin,

heute hatte ich einen massiven Ansturm auf meine Datenbank. Gemerkt, weil ich plötzlich 1200 vom Programm ausgelöste Mails bekam, dass diese Abfrage länger läuft als 3 sec.

Eigentlich hätte die Kontrolle greifen müssen, dass eine REQUEST_URI max. 110 Zeichen lang sein darf. Sie ist länger und enthält SQL-Code. Muss noch klären, wieso das umschifft wurde.

Es wurde eine counter-Tabelle (Zugriffszähler) manipuliert. Uralt-Routine, in der addslashes() fehlte. Habe ich sofort nachgetragen und den Query-String auf delete, insert, select und update geprüft.

Der Query-String enthielt sowas: FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name=0x746d5f75736572 AND table_schema=0x746d33 LIMIT 2,1) Eine Tabelle namens 0x746d5f75736572 habe ich gar nicht. Was bedeutet das?

Nun möchte ich einen neuen Datenbank-User anlegen, der nur Leserechte hat.

Wie geht das? Die mySQL-Doku ist dermaßen unübersichtlich und das Stichwort read only kommt nicht vor.

Wenn nun jemand zu Recht eine Seite angezeigt bekommt und ich möchte den Zähler hochsetzen, muss ich wohl den SQL-User wechseln. Muss ich die Datenbank schließen und neu öffnen?

fragt Linuchs

  1. Moin Linuchs,

    bei MySQL/MariaDB gibt es die Möglichkeit Rechte auf Tabellenebene zu vergeben. Was du suchst ist GRANT: https://mariadb.com/kb/en/grant/

    Die Dokumentation ist bei MariaDB leider nur in Englisch vorhanden.

    Wenn die Rechte dir reichen, könnte man auch zwei Verbindungen mit verschiedenen Nutzern zu öffnen, und diese unterschiedlichen Variablen zuzuweisen. Sofern du mehrere DB-Verbindungen öffnen darfst. Das kommt auf deinen Hoster an. Je nach Einsatzzweck kannst du dann die Nur-Lesen-Verbindung oder die Verbindung mit Schreibrechten nutzen.

    Viele Grüße

    Jens

  2. Hallo Linuchs,

    wenn Du einen neuen DB-User anlegst, soll der vermutlich auch nuf vom Localhost aus zugreifen können, also bei Dir nur über deine PHP-Skripte.

    GRANT SELECT ON <table.database> FOR "lin-sel"@"localhost" IDENTIFIED BY "<password>"

    Siehe auch Manual

    Und dann auch mal die Grants anzeigen lassen!

    LG
    DB-Willi

    1. Hallo Willi,

      habe als root den Benutzer angelegt für localhost mit Passwort und per GRANT SELECT erlaubt.

      In phpMyAdmin kann ich mich damit aber nicht anmelden.

      Also auch auf dem Debian-Rechner diesen Benutzer mit demselben Passwort angelegt. Komme trotzdem nicht rein in phpMyAdmin.

      Was ist zu tun? Reicht SELECT nicht aus, um die Tabellen zu sehen?

      Linuchs

    2. Hallo Linuchs,

      wenn Du einen neuen DB-User anlegst, soll der vermutlich auch nuf vom Localhost aus zugreifen können, also bei Dir nur über deine PHP-Skripte.

      Das war leider verkehrt herum:

      `GRANT SELECT ON <table.database> FOR "lin-sel"@"localhost" IDENTIFIED BY "<password>"`   
      

      Beim Objekt vom höchstwertigsten zum niedrigsten geordnet:

      `GRANT SELECT ON <database.table> FOR "lin-sel"@"localhost" IDENTIFIED BY "<password>"`   
      

      Siehe auch Manual

      Und dann auch mal die Grants anzeigen lassen!

      LG
      DB-Willi

  3. Hi,

    Es wurde eine counter-Tabelle (Zugriffszähler) manipuliert. Uralt-Routine, in der addslashes() fehlte.

    Wirklich addslashes? Fehlte da nicht eher ein mysqli_real_escape (oder wie auch immer die Datenbank-Escape-Funktion genau heißt)?

    cu,
    Andreas a/k/a MudGuard

    1. Hallo MudGuard,

      Wirklich addslashes? Fehlte da nicht eher ein mysqli_real_escape (oder wie auch immer die Datenbank-Escape-Funktion genau heißt)?

      Genau. Aus dem PHP manual: „Die Funktion addslashes() wird manchmal fälschlicherweise verwendet, um zu versuchen[,] SQL Injection zu verhinden.“ (Hervorhebung von mir)

      Bis demnächst
      Matthias

      --
      Du kannst das Projekt SELFHTML unterstützen,
      indem du bei Amazon-Einkäufen Amazon smile (Was ist das?) nutzt.
      1. Tach!

        Aus dem PHP manual: „Die Funktion addslashes() wird manchmal fälschlicherweise verwendet, um zu versuchen[,] SQL Injection zu verhinden.“ (Hervorhebung von mir)

        Ja, man sollte schon die datenbankspezifischen Funktionen verwenden. Allerdings kann addslashes() bereits ausreiched sein. Die wesentlichen Zeichen für SQL-Statements im MySQL-Dialekt sind von addslashes() abgedeckt. Die Zeichen, die außer diesen von mysqli_real_escape_string() behandelt werden, sind nicht für die sichere Übertragung von Daten via SQL-Statement-String in die Datenhaltung notwendig. Sie sind für Spezialfälle gedacht. Beispielsweise dient das Maskieren der Zeilenendezeichen dafür, dass in Logfiles keine Zeilenschaltung erfolgt. Ein SQL-String auf dem Weg in die Datenbank kann diese aber problemlos als unmaskierte Zeichen enthalten.

        Trotzdem nochmal die Empfehlung, die vorgesehene Funktioen zu verwenden, dann muss man sich keine Gedanken machen, ob die Spezialfälle zutreffen oder nicht.

        dedlfix.