Query Ergebnis manipulieren (Proxy)

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
naheliegend
User
Beiträge: 439
Registriert: Mittwoch 8. August 2018, 16:42

Hi,

es gibt eine Applikation, die ganz normal über den ORM Anfragen an eine MySQL Datenbank stellt.

Jetzt sollen die Queries und das Resultat dieser Queries untersucht werden, ohne, dass die Applikation angefasst werden soll. Das gehört zur Anforderung dazu.

Die Untersuchung soll derart ablaufen, dass wenn etwas Bestimmtes in dem Anfrage-SQL von der Applikation steht, dass dann ein Wert aus dem Ursprungs-Query-Ergebnis an einen separaten Service geschickt und im Ursprungs-Query-ergebnis ersetzt wird.

Pseudo:

Code: Alles auswählen

def check(query):
	if 'foo' in query:
		query_result = query.get_result()
		send_value_to_sevice(query_result.value('hallo'))
		query_result = query_result.replace('hallo', 'moin')
		return query_result
	else:
		query_result = query.get_result()
		return query_result 

Mir kommt da bislang nur ein Proxy in den Sinn, der genau das kann. Jedoch finde ich bei ProxySQL nicht so eine Fähigkeit. Der kann SQL rewriten, aber Werte aus dem Ergebnis auslesen und an einen anderen Service schicken, habe ich nicht gefunden.

Bei dem alten mysql proxy habe ich gefunden, dass er pro Query ein LUA-Skript aufruft und man ggf dort das Ganze platzieren kann. Aber der wird von Mysql auch nicht mehr empfohlen.

Jetzt überlege ich, ob man den Proxy-Server nicht selbst bauen kann? Quasi als Django-Applikation oder so. Nur weiß ich nicht, wie performant und einfach das wäre.
Die App müsste auch das Mysql-Protokol verstehen, weil das ja vorne reinkommt.

Hat jemand eine Idee?

Schöne Ostertage.
__backjack__: "Jemand der VB oder PHP kann, der also was Programmieren angeht irgendwo im negativen Bereich liegt (...)"
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Es klingt schwer nach einem XY-Problem. Was ist denn die Art der Daten, und unter welchen Umständen sollen die verändert werden?

Wenn du das selbst bauen willst, ist das ein sehr teures und langwieriges Unterfangen, und die Performance wird stark leiden, weil so wie beschrieben ALLE Daten gescannt werden müssen. Und weil man das gesamte MySQL protocol nachimplementieren muss, kann das auch eine ganze Weile dauern, bis es wirklich stabil ist, und die Ursache für Fehler in Produktion sein.

Mit Django kann man da nichts ausrichten, das muss man basierend auf den bekannten socket Abstraktionen selbst bauen.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Einen Anfang findet man hier: https://github.com/PyMySQL/PyMySQL/tree/main/pymysql - das ist dann zumindest der "Downstream".
naheliegend
User
Beiträge: 439
Registriert: Mittwoch 8. August 2018, 16:42

Entschuldige, ich dachte die Details wären nicht wichtig. Es geht um Encryption. Der separate Service wäre ein HSM. Queries, die persönliche Daten abfragen, die verschlüsselt in der DB liegen, sollen vor Erreichung der App ans HSM geschickt werden und entschlüsselt dann hochgereicht werden. Genauso wäre es dann beim Schreiben, bloß andersherum. Der Proxy wäre quasi der Händler zwischen dem Ganzen und müsste unterscheiden zwischen Queries mit Daten, die ver- oder entschlüsselt werden müssen oder halt nicht. Theoretisch könnte das funktionieren. :D
__backjack__: "Jemand der VB oder PHP kann, der also was Programmieren angeht irgendwo im negativen Bereich liegt (...)"
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das diese Vorstellungen ueber das Ver/Entschluesseln von Daten nicht sinnvoll sind, hatten wir ja schon an anderer Stelle besprochen. *Musst* du das machen, weil jemand dich dazu zwingt? Oder glaubst du nur, dass es eine gute Idee ist? Als Marketinggag zb?

Wenn wir mal als gegeben nehmen, dass es so sein muss: der erste & offensichtliche Schritt, diese Anforderung umzusetzen, besteht darin, sich das ORM selbst zu Nutze zu machen. Denn was von der Datenbank geliefert wird, kann ruhig verschluesselt sein, wenn die Entschluesselung transparent fuer den Benutzer beim Gebrauch eines ORM-Objektes geschieht.

Dafuer kann man dann zB geeignete eigene Feld-Typen definieren, welche beim Zugriff transparent in beide Richtungen die notwendigen Schritte durchfuehren. Siehe zB https://docs.djangoproject.com/en/4.0/h ... el-fields/

Gibt es einen Grund, das so nicht zu machen? Welchen?
naheliegend
User
Beiträge: 439
Registriert: Mittwoch 8. August 2018, 16:42

Ich habe das mal testweise im ORM umgesetzt und die entsprechenden Methoden überschrieben:

Code: Alles auswählen

class EncryptCharField(models.CharField):
  description = "Encrypted values"

  def get_prep_value(self, value):
    # encrypt data with your own function
    value = http_post(value=value, url_endpoint='encryption')
    return value
  
  def from_db_value(self, value, expression, connection):
    if value is None:
      return value
    #decrypt data with your own function
    value = http_post(value=value, url_endpoint='decryption')
    return value

  def to_python(self, value):
    if isinstance(value, UserInformation):
      return value
    if value is None:
      return value
    #decrypt data with your own function
    value = http_post(value=value, url_endpoint='decryption')
    return value
http_post() ruft einen API-Endpunkt an, der den value ent- oder verschlüsselt. Das funktioniert tatsächlich, sodass das FE transparent die echten Werte enthält, obwohl in der DB verschlüsselte liegen.

Jetzt frage ich mich nur, was die Admin macht? Wenn ich da einen Wert für ein EncryptCharField ändere, dann funktioniert das nicht mehr. Nutzt die Admin für ein Update oder Insert nicht den ORM, also die oben definierten Methoden?
__backjack__: "Jemand der VB oder PHP kann, der also was Programmieren angeht irgendwo im negativen Bereich liegt (...)"
Antworten