Seite 1 von 1
Flask: Werte in einem Template verarbeiten
Verfasst: Freitag 20. Juni 2014, 14:40
von peddy
Hallo,
ich beschäftige mich seit ein paar Stunden mit Flask und habe gerade einen Knoten im Kopf, bezüglich Templates.
Code: Alles auswählen
def connect_db():
rv = sqlite3.connect(app.config['DATABASE'])
rv.row_factory = sqlite3.Row
return rv
def get_db():
if not hasattr(g, 'sqlite_db'):
g.sqlite_db = connect_db()
return g.sqlite_db
@app.teardown_appcontext
def close_db(error):
if hasattr(g, 'sqlite_db'):
g.sqlite_db.close()
@app.route('/user/<hash_value>')
def user_startpage(hash_value):
db = get_db()
cur = db.execute("""select t.name, ut.completed
from users as u
join users_trainings as ut on u.ID = ut.U_ID
join trainings as t on ut.T_ID = t.ID
where u.hash='{}'""".format(hash_value))
trainings = cur.fetchall()
db = get_db()
cur = db.execute("select first_name || ' ' || name from users where hash='{}'".format(hash_value))
user_name = cur.fetchall()
return render_template('show_user_trainings.html', trainings=trainings, user_name=user_name)
Code: Alles auswählen
{% extends "layout.html" %}
{% block body %}
<h2>{{ user_name[0] }}</h2>
<ul class=entries>
{% for training in trainings %}
<li>{{ training.name }} {{ training.completed}}
{% else %}
<li><em>Unbelievable. No entries here so far</em>
{% endfor %}
</ul>
{% endblock %}
Es geht um sie übergebene Variable user_name. Wenn ich sie wie hier verwende bekomme ich so etwas wie <sqlite3.Row object at 0x105261470> als Antwort. Wie komme ich am leichtesten an den Inhalt dran?
Re: Flask: Werte in einem Template verarbeiten
Verfasst: Freitag 20. Juni 2014, 14:45
von Hyperion
peddy hat geschrieben:
Es geht um sie übergebene Variable user_name. Wenn ich sie wie hier verwende bekomme ich so etwas wie <sqlite3.Row object at 0x105261470> als Antwort. Wie komme ich am leichtesten an den Inhalt dran?
Das ist kein Jinja2-Problem (das ist die Template Engine, die Flask einsetzt!), sondern ein DB API 2.0 Problem

Zeile 27 ist der Knackpunkt. Schreib da einfach mal ``user_name = "Hyperion"`` rein und freue Dich über die Ausgabe
Du solltest Dir dringend noch mal das
DB2-API angucken.
Du suchst hier vermutlich ``fetchone`` und willst dazu noch den einzigen, also den 0. Index

Re: Flask: Werte in einem Template verarbeiten
Verfasst: Freitag 20. Juni 2014, 14:52
von peddy
Vielen Dank für die schnelle Hilfe. Mit fetchone bekomme ich den Wert nun richtig übergeben. Die DB2-API sollte ich mir aber wirklich mal ansehen, damit ich auch verstehe was ich da mache

Re: Flask: Werte in einem Template verarbeiten
Verfasst: Freitag 20. Juni 2014, 15:03
von BlackJack
@peddy: Du hast Dir da eine wunderbare SQL-Injection-Sicherheitslücke eingebaut. Man formatiert keine Werte selber in Zeichenketten mit SQL-Anweisungen. Werte die vom Benutzer beliebig vorgegeben werden können schon mal gar nicht!
Re: Flask: Werte in einem Template verarbeiten
Verfasst: Freitag 20. Juni 2014, 15:10
von Sirius3
@peddy: Was Du da machst ist ein SQL-Injection-Scheunentor, da hash_value ein beliebiger String sein kann, der ungesehen in einen SQL-Befehl eingebaut wird.
Was ist `g` bei Dir? Das `hasattr` ist in vielerlei Hinsicht ein Anti-Pattern. Erstens verschleierst Du damit ein `global`, in einem Fall, wo es ausnahmsweise mal ok wäre. Zweitens erzeugst Du auf magische Weise Attribute in `g`, die sehr schwer zu durchschauen sind. Und drittens ist `g` für einen globalen Namen viel zu nichtssagend.
Re: Flask: Werte in einem Template verarbeiten
Verfasst: Freitag 20. Juni 2014, 15:15
von Hyperion
Sirius3 hat geschrieben:
Was ist `g` bei Dir? Das `hasattr` ist in vielerlei Hinsicht ein Anti-Pattern. Erstens verschleierst Du damit ein `global`, in einem Fall, wo es ausnahmsweise mal ok wäre. Zweitens erzeugst Du auf magische Weise Attribute in `g`, die sehr schwer zu durchschauen sind. Und drittens ist `g` für einen globalen Namen viel zu nichtssagend.
Das ``g`` ist bei Flask aber
vorgesehen. Im Kontext von Flask ist das ``g`` also vollkommen i.O.

Re: Flask: Werte in einem Template verarbeiten
Verfasst: Freitag 20. Juni 2014, 18:15
von DasIch
Sirius3 hat geschrieben:Was ist `g` bei dir? Das `hasattr` ist in vielerlei Hinsicht ein Anti-Pattern. Erstens verschleierst Du damit ein `global`, in einem Fall, wo es ausnahmsweise mal ok wäre. Zweitens erzeugst Du auf magische Weise Attribute in `g`, die sehr schwer zu durchschauen sind. Und drittens ist `g` für einen globalen Namen viel zu nichtssagend.
Als Flask Entwickler muss ich hier quasi erstmal jedem Punkt widersprechen. g ist Teil des Application Context, heisst Attribute die man darauf setzen existieren solange wie der Application Context existiert - überlichweise also für die Zeit und in dem Thread in dem auf ein Request geantwortet wird.
Global wird hier also gar nichts gesetzt, wäre auch vorallem in diesem Fall gar nicht ok, schliesslich will man nicht dass mehrere Threads parallel auf die Connection zugreifen. Magisch wird hier dementsprechend auch nichts erzeugt sondern einfach nur dann wenn eine Datenverbindung innerhalb eines Application Context gebraucht wird und dann auch nur maximal einmal. g wird hier also wie ein Cache genutzt und dass ist ein übliches Pattern in Flask Anwendungen.
Sicherlich könnte man einen längeren Namen wählen, da g aber sehr generisch ist wäre dieser nicht wesentlich weniger nichtssagend. Insofern geht man einfach davon aus dass sich jemand der Flask Anwendungen schreibt bzw. deren Code liest sich mit Flask beschäftigt hat und dementsprechend weiß was flask.g ist.
Re: Flask: Werte in einem Template verarbeiten
Verfasst: Freitag 20. Juni 2014, 18:29
von jens
Ein Objekt mit einem Buchstaben als Namen ist schon was sehr abgefahren, oder?
Re: Flask: Werte in einem Template verarbeiten
Verfasst: Samstag 21. Juni 2014, 10:48
von peddy
Was ist `g` bei Dir? Das `hasattr` ist in vielerlei Hinsicht ein Anti-Pattern. Erstens verschleierst Du damit ein `global`, in einem Fall, wo es ausnahmsweise mal ok wäre. Zweitens erzeugst Du auf magische Weise Attribute in `g`, die sehr schwer zu durchschauen sind. Und drittens ist `g` für einen globalen Namen viel zu nichtssagend.
Ich kann leider auch nicht beantworten warum 'g' gewählt wurde. Den Code habe ich eins zu eins vom Flask Tutorial übernommen. --->
http://flask.pocoo.org/docs/tutorial/dbcon/
Re: Flask: Werte in einem Template verarbeiten
Verfasst: Samstag 21. Juni 2014, 10:54
von peddy
BlackJack hat geschrieben:@peddy: Du hast Dir da eine wunderbare SQL-Injection-Sicherheitslücke eingebaut. Man formatiert keine Werte selber in Zeichenketten mit SQL-Anweisungen. Werte die vom Benutzer beliebig vorgegeben werden können schon mal gar nicht!
Ich nehme an du beziehst dich auf diese Stelle:
Code: Alles auswählen
cur = db.execute("""select t.name, ut.completed
from users as u
join users_trainings as ut on u.ID = ut.U_ID
join trainings as t on ut.T_ID = t.ID
where u.hash='{}'""".format(hash_value))
Wie vermeidet man den am besten eine Injektion. Gibt es da ein best practice?
Re: Flask: Werte in einem Template verarbeiten
Verfasst: Samstag 21. Juni 2014, 10:57
von snafu
jens hat geschrieben:Ein Objekt mit einem Buchstaben als Namen ist schon was sehr abgefahren, oder?
Du meinst sicher "ein globales Objekt". Oder hälst du ``x`` und ``y`` bei mathematischen Berechnungen sowie ``i`` und ``j`` als Zählervariablen für ähnlich abgefahren?

Re: Flask: Werte in einem Template verarbeiten
Verfasst: Samstag 21. Juni 2014, 11:00
von snafu
peddy hat geschrieben:Wie vermeidet man den am besten eine Injektion. Gibt es da ein best practice?
Guck dir mal die Doku zu
Cursor-Objekten an. Da steht recht übersichtlich, was man für Möglichkeiten hat. Wurde übrigens bereits von Hyperion verlinkt.