Skip to content

Debugging in varnost

Zakaj to poglavje nujno sodi zraven

Veliko začetnih gradiv pokaže samo srečno pot: napišeš kodo, klikneš, vse dela, vsi zadovoljni. V resnici pa se začetnik največ nauči takrat, ko vidi:

  • kaj je šlo narobe,
  • kako to opazi,
  • kako napako locira,
  • kako jo popravi.

Drugi pogosto zanemarjen del je varnostni minimum. Ne gre za to, da iz začetnikov delaš varnostne strokovnjake. Gre za to, da jim ne pustiš slabih navad, ki jih bodo pozneje vlekli naprej.

Dober debugging potek

Ko nekaj ne dela, naj dijak ne divje ugiba. Naj gre po korakih:

  1. kaj točno je narobe,
  2. ali je težava v HTML, CSS, zahtevi, Flasku ali bazi,
  3. kaj pravi brskalnik,
  4. kaj pravi strežnik,
  5. kateri podatek je prvi napačen,
  6. ali je napako mogoče ponoviti.

To je preprosta metoda, a dela čudeže.

Brskalniška orodja

Elements / Inspector

Uporaben za:

  • preverjanje HTML strukture,
  • preverjanje, kateri razredi so na elementu,
  • pregled aktivnih CSS pravil,
  • razumevanje box modela.

Network

To je pogosto najbolj podcenjen zavihek pri začetnikih. Z njim lahko preveriš:

  • kateri URL je bil zahtevan,
  • ali je bila metoda GET ali POST,
  • kakšna je statusna koda,
  • ali je prišlo do preusmeritve,
  • ali se CSS ali slika vrača z 404.

Console

Tudi če JavaScript ni osrednja tema, je koristno vedeti, da konzola obstaja in da pogosto vsebuje pomembna opozorila ali napake.

Strežniški izpis

Pri Flasku je terminal pogosto enako pomemben kot brskalnik. Tam vidiš:

  • katere zahteve prihajajo,
  • kakšne statuse vrača aplikacija,
  • ali je prišlo do izjeme,
  • v kateri vrstici kode je stvar padla.

To je ogromen korak od “ne dela” do “aha, manjka commit” ali “ime polja je napačno”.

Tipični primeri napak

CSS se ne naloži

Možni razlogi:

  • napačna pot,
  • datoteka ni v static/,
  • napačno ime datoteke,
  • v predlogi ni url_for('static', ...).

Flask vrne 404

Možni razlogi:

  • napačna URL pot,
  • route ne obstaja,
  • povezava kaže na napačen naslov.

Flask vrne 405

Možni razlogi:

  • route ne podpira metode POST,
  • obrazec uporablja metodo, ki je route ne pričakuje.

Flask vrne 500

Možni razlogi:

  • Python izjema,
  • napačna SQL poizvedba,
  • podatki niso takšni, kot jih koda pričakuje,
  • manjkajoča predloga ali napačen ključ.

Kako naj dijak bere napako

Začetnik pogosto vidi veliko besedila in se ustraši. Nauči ga, da poišče:

  • prvi uporaben opis problema,
  • ime datoteke,
  • številko vrstice,
  • funkcijo, v kateri je padlo,
  • podatke, ki so problem sprožili.

To je veliko boljša navada kot naključno klikanje.

Validacija na strežniku

Osnovno pravilo:

vhodnim podatkom ne zaupamo.

Tudi če obrazec uporablja required, mora strežnik še vedno preveriti:

  • ali polje obstaja,
  • ali je prazno,
  • ali je tip smiselno pravilen,
  • ali je vrednost v dovoljenem območju.

Primer:

naslov = request.form.get("naslov", "").strip()
avtor = request.form.get("avtor", "").strip()

if not naslov or not avtor:
    return render_template("dodaj.html", napaka="Naslov in avtor sta obvezna.")

SQL injection

To je klasičen razlog, zakaj ne lepimo uporabniških vrednosti v SQL niz.

Napačno:

sql = f"SELECT * FROM knjige WHERE naslov = '{naslov}'"
cur.execute(sql)

Pravilneje:

cur.execute(
    "SELECT * FROM knjige WHERE naslov = ?",
    (naslov,)
)

To ni samo lepša sintaksa. To je osnovna obramba pred zelo banalnimi napakami in zlorabami.

XSS in prikaz podatkov

Če aplikacija prikazuje uporabniški vnos, mora paziti, da se ta vnos ne obravnava kot koda v brskalniku. Za začetni nivo zadošča:

  • nikoli slepo ne zaupaj uporabniškemu vnosu,
  • predloge naj privzeto podatke obravnavajo kot vsebino, ne kot kodo,
  • izogibaj se nevarnemu “surovemu” vstavljenju HTML-ja brez razloga.

CSRF kot koncept

Ni treba v implementacijske podrobnosti, je pa pošteno povedati:

  • če obrazec spreminja stanje aplikacije,
  • je pomembno razmišljati tudi o tem, ali zahteva res prihaja iz legitimnega konteksta.

Za začetni predmet zadošča konceptualna omemba.

Gesla

Če se v nekem trenutku dotakneš prijave uporabnikov, povej brez olepševanja:

  • gesel se ne hrani v navadnem besedilu,
  • nikoli se jih ne zapisuje kar “kot je” v bazo.

Tudi če tega v tem predmetu ne implementiraš, je pomembno, da dijaki slišijo pravilno pravilo.

Konfiguracija in skrivnosti

Pri malem učnem projektu ni treba uvajati celega sistema nastavitev, je pa pametno omeniti:

  • skrivnosti in gesla ne sodijo v javno deljeno kodo,
  • razvojne nastavitve niso isto kot produkcijske nastavitve,
  • debug=True je za razvoj, ne za objavo na spletu.

Dober kontrolni seznam, ko nekaj ne dela

1. Ali je URL pravilen?
2. Ali je metoda prava?
3. Ali route obstaja?
4. Ali so imena form polj pravilna?
5. Ali predloga obstaja?
6. Ali se CSS nalaga iz static/?
7. Ali SQL uporablja placeholderje?
8. Ali je commit izveden?
9. Kaj pravi Network?
10. Kaj pravi terminal?

Kaj naj dijak zna po tem poglavju

  • odpreti DevTools,
  • preveriti zahtevo in statusno kodo,
  • poiskati osnovno Flask napako,
  • razumeti, zakaj strežnik preverja vhod,
  • uporabljati parameterizirane poizvedbe,
  • vedeti, da razvojni strežnik ni produkcija.

Najpogostejša napaka začetnikov

Največkrat težava ni “preveč zapleten problem”, ampak majhna netočnost:

  • narobe ime polja,
  • narobe pot,
  • manjkajoča mapa,
  • napačna metoda,
  • pozabljen commit().

To je pravzaprav dobra novica, ker pomeni, da se večina napak da rešiti z mirnim, sistematičnim pregledom.

Glavno sporočilo

Dober programer ni tisti, ki nikoli ne naredi napake. Dober programer je tisti, ki zna napako mirno opaziti, razložiti in popraviti.