Seite 1 von 1
Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 09:54
von moehre
Hallo,
ich habe einen Webservice mit Web.py erstellt.
Nun möchte ich Benutzereingaben in meinem SQL-Statement verwenden. Dafür verwende ich web.input().
Code: Alles auswählen
data = web.input()
id = int(data.id)
...
cursor.execute(
"SELECT a WHERE a.id = id AND ...")
Die Eingabe besteht nur aus einem Wert der ID.
Allerdings erscheint bei mir die Fehlermeldung:
<class 'cx_Oracle.DatabaseError'> at /grid
ORA-00918: Spalte nicht eindeutig definiert
Wenn ich im SQL-Statement für a.id den Wert direkt definiere (a.id = 1) dann funktioniert es...Was mache ich falsch?
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 10:06
von BlackJack
@moehre: An welcher Stelle soll denn da der Wert von `id` in die Abfrage kommen? Gehst Du davon aus das in der Zeichenkette auf magische Weise eines der 'id', und dann natürlich auch das richtige, durch den Wert von der Python-Variable `id` ersetzt wird? Du musst im SQL Platzhalter für Werte verwenden und die Werte selber dann als zweites Argument von `execute()` übergeben. Auf *keinen Fall* die Werte selbst mit Zeichenkettenoperationen in die Anfrage rein basteln. Auf die Weise können Benutzer Dir nahezu beliebige SQL-Anweisungen da rein schmuggeln. Stichwort SQL-Injection.
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 10:37
von moehre
Ok stimmt also definiere ich einen Platzhalter und übergebe im zweiten Schritt die ID...
Code: Alles auswählen
data = web.input()
id = int(data.ID)
query = "SELECT a.id ... FROM ... WHERE a.grid_id = %s;"
cursor.execute(query, id)
Aber das funktioniert auch nicht! Folgende Fehlermeldung erscheint:
TypeError: expecting a dictionary, sequence or keyword args
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 10:46
von Sirius3
@moehre: da hilft es, die Dokumentation zu execute zu lesen, denn dort steht geschrieben, dass das zweite Argument eine Sequenz (z.B. eine Liste) oder, falls Platzhalter mit Namen verwendet werden, ein Wörterbuch sein muß.
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 10:53
von moehre
Ok danke für den Hinweis.
Wen ich jetzt aber nur ein Integer gegeben habe und keine Sequenz oder Wörterbuch, wie kann ich das Problem dann umgehen?
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 10:59
von Sirius3
@moehre: eine Liste kann auch nur ein Element enthalten.
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 11:08
von moehre
Ok also wenn ich die Benutzereingabe so definiere:
data = web.input(ID="[]") ist doch eine List vorhanden oder?
Wenn ich die Abfrage ausführe (cursor.execute(query, data.ID))erscheint vollgende Fehlermeldung:
'ascii' codec can't decode byte 0xfc in position 36: ordinal not in range(128)
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 11:23
von BlackJack
@moehre: Von dem Web-Objekt möchtest Du keine Liste sondern einen Wert den Du in eine Zahl umwandelst. Du bastelst da am falschen Ende. `execute()` möchte eine Liste mit einem Wert pro Platzhalter, das hat nichts damit zu tun wo dieser Wert ursprünglich herkommt. Du hast ja schon den ID-Wert, den musst Du in eine Liste stecken.
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 11:43
von moehre
Also ich habe ein Web-Objekt was ein String ist
1.)
Diesen wandele ich um in ein Integer
2.)
Danach erstelle ich eine Liste a und füge den Wert hinzu
3.)
Danach rufe ich den query auf
4.)
Funktioniert soweit im Debug-Modus!
Wenn ich im 5ten Schritt den Cursor ausführen will
5.)
erscheint die Fehlermeldung:
'ascii' codec can't decode byte 0xfc in position 36: ordinal not in range(128)
Der Parameter a im execute-Statement ist eine Liste die meine ID enthält...was ist jetzt noch falsch?
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 11:56
von BlackJack
@moehre: Ein kompletter Traceback wäre nützlich um mehr darüber zu erfahren wo die Ausnahme genau auftritt. Ansonsten kann man nur raten, dass Du vielleicht irgendwo in der SQL-Anfrage etwas hast das sich nicht implizit dekodieren lässt, also irgendwas ausserhalb von ASCII‽
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 12:15
von moehre
Mein SQL-Query sieht so aus:
Code: Alles auswählen
SELECT a.id AS building_nr, c.geometry.sdo_ordinates AS geometry, d.Classname AS polygon_typ FROM building a, THEMATIC_SURFACE b, SURFACE_GEOMETRY c, OBJECTCLASS d WHERE a.id = b.BUILDING_ID AND b.LOD2_MULTI_SURFACE_ID = c.ROOT_ID AND c.GEOMETRY IS NOT NULL AND b.OBJECTCLASS_ID = d.ID AND a.grid_id_500 = %s;"
Traceback:
Traceback (innermost first)
C:/Users/53_D_ML/Desktop/Masterthesis_15.06/wwwroot/REST\web\utils.py in safeunicode
return unicode(obj) ...
▶ Local vars
C:/Users/53_D_ML/Desktop/Masterthesis_15.06/wwwroot/REST\web\template.py in _escape
value = safeunicode(value) ...
.......
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 12:53
von Sirius3
@moehre: der Fehler tritt ja irgendwo im Template auf, also bei der Ausgabe, hat also erstmal nichts mit Deiner SQL-Abfrage zu tun. Da wäre es nunmal gut, Deinen gesamten Code und den kompletten Traceback zu sehen.
Übrigens sollte Programmcode NIEMALS in einem Dokumentenverzeichnis (wwwroot) liegen, auf das man auch direkt per Web-Server zugreifen kann oder potentiell wegen einer leicht falschen Konfiguration zugreifen könnte. Mit Hilfe des Programmcodes kann nämlich ein Angreifer viel einfacher nach Schwachstellen suchen, bzw. findet er im Zweifel sogar Passwörter, die im Programm benutzt werden.
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 13:14
von moehre
Also mein Code sieht folgendermaßen aus:
Code: Alles auswählen
import cx_Oracle
import json
import web
urls = (
"/grid", "grid"
)
app = web.application(urls, globals())
web.config.debug = True
connection = cx_Oracle.Connection("user/pssw@10.40.33.160:1521/sdetest", )
typeObj = connection.gettype("MDSYS.SDO_GEOMETRY")
class grid:
def GET(self):
web.header('Access-Control-Allow-Origin', '*')
web.header('Access-Control-Allow-Credentials', 'true')
web.header('Content-Type', 'application/json')
data = web.input()
id = int(data.ID)
a = [id]
cursor = connection.cursor()
cursor.arraysize = 10000
query = "SELECT a.id AS building_nr, c.geometry.sdo_ordinates AS geometry, d.Classname AS polygon_typ FROM building a, THEMATIC_SURFACE b, SURFACE_GEOMETRY c, OBJECTCLASS d WHERE a.id = b.BUILDING_ID AND b.LOD2_MULTI_SURFACE_ID = c.ROOT_ID AND c.GEOMETRY IS NOT NULL AND b.OBJECTCLASS_ID = d.ID AND a.grid_id_500 = %s;"
cursor.execute(query,a)
result = []
for id,geometry , classname in cursor:
result.append({"building_nr":id,"geometry":{"type":"polygon","coordinates":zip(*[iter(geometry.aslist())]*3),},"polygon_typ":classname,})
return json.dumps(result)
if __name__ == "__main__":
app.run()
Der Programmcode liegt auf einer Kopie des Dokumentenverzeichnisses wwwroot. Es ist nicht das originale.
Traceback
<type 'exceptions.UnicodeDecodeError'> at /grid
'ascii' codec can't decode byte 0xfc in position 36: ordinal not in range(128)
Python C:\Users\53_D_ML\Desktop\Masterthesis_15.06\wwwroot\REST\web\utils.py in safeunicode, line 351
Web GET
http://localhost:8080/grid
Traceback (innermost first)
C:\Users\53_D_ML\Desktop\Masterthesis_15.06\wwwroot\REST\web\utils.py in safeunicode
return unicode(obj) ...
▼ Local vars
Variable Value
encoding
'utf-8'
obj
DatabaseError(<cx_Oracle._Error object at 0x02C7BBE0>,)
t
<class 'cx_Oracle.DatabaseError'>
C:\Users\53_D_ML\Desktop\Masterthesis_15.06\wwwroot\REST\web\template.py in _escape
value = safeunicode(value) ...
▼ Local vars
Variable Value
escape
True
self
<web.template.Template instance at 0x02A68C88>
value
DatabaseError(<cx_Oracle._Error object at 0x02C7BBE0>,)
C:\Users\53_D_ML\Desktop\Masterthesis_15.06\wwwroot\REST\web\debugerror.pyc in __template__
▶ Local vars
C:\Users\53_D_ML\Desktop\Masterthesis_15.06\wwwroot\REST\web\debugerror.py in djangoerror
return t(exception_type, exception_value, frames) ...
▶ Local vars
C:\Users\53_D_ML\Desktop\Masterthesis_15.06\wwwroot\REST\web\debugerror.py in debugerror
return web._InternalError(djangoerror()) ...
C:\Users\53_D_ML\Desktop\Masterthesis_15.06\wwwroot\REST\web\application.py in internalerror
return debugerror.debugerror() ...
▶ Local vars
C:\Users\53_D_ML\Desktop\Masterthesis_15.06\wwwroot\REST\web\application.py in process
raise self.internalerror() ...
▶ Local vars
C:\Users\53_D_ML\Desktop\Masterthesis_15.06\wwwroot\REST\web\application.py in <lambda>
return p(lambda: process(processors)) ...
▶ Local vars
C:\Users\53_D_ML\Desktop\Masterthesis_15.06\wwwroot\REST\web\application.py in processor
return handler() ...
▶ Local vars
C:\Users\53_D_ML\Desktop\Masterthesis_15.06\wwwroot\REST\web\application.py in process
return p(lambda: process(processors)) ...
▶ Local vars
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 13:24
von BlackJack
@moehre: Wenn ich das richtig sehe tritt der Fehler bei der Behandlung eines Fehlers auf. Was sagt denn das Fehlerprotokoll des Webservers dazu?
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 13:51
von moehre
Wie kriege ich denn das Fehlerprotokoll?
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 14:32
von BlackJack
@moehre: Das hängt vom Webserver und dessen Konfiguration ab.
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 15:49
von moehre
Es liegt wohl an der API cx_Oracle!
Hier wird einiges anders gehandhabt.
Ich habe es jetzt nach langem probieren zum laufen bekommen:
Code: Alles auswählen
data = web.input(ID='')
query = "SELECT....FROM ...WHERE a.id =:grid_ID"
cursor.execute(query, {'grid_id':data.ID})
Re: Fehlerhafte Benutzereingabe mit web.input
Verfasst: Dienstag 20. September 2016, 16:06
von BlackJack
@moehre: Was heisst ”anders”, es verwendet halt 'named' als Parameterstil, das hätte man halt in der Dokumentation nachlesen können/müssen.
Ich nehme wegen solcher Details ganz gerne SQLAlchemy als Abstraktion über die DB API 2.0. Da wäre dann aber die Frage wie man dort mit den GEO-Typen umgeht, die ja nicht zum SQL-Standard gehören.