En av tingene jeg har gruet meg mest til å skrive i arbeidet med nye Calcuttagutta har vært et filter som håndterer teksten vi putter inn. Det er jo slik at vi må tillate at noe html kommer gjennom, sånn som formattering, bilder, bildeplassering etc., men samtidig er det jo slik at hvem som helst kan registrere seg og legge inn kommentarer, så vi kan ikke tillate alt mulig rart heller.
Standardoppførselen til django er at den escaper absolutt alt før det går inn i databasen, og så putter det rett ut igjen, slik at hvis du prøver å skrive
kursiv vil det i stedet stå <i>kursiv</i>. I utgangspunktet er altså sikkerheten godt ivaretatt, men ikke brukervennligheten.
Først så jeg for meg at jeg kanskje måtte skrive mitt eget filter. Det er to måter man kan gjøre dette på. Man kan enten lage et eget filter for å fjerne all slem kode, og bruke det i stedet for djangos innebygde super-rens som fjerner alt, eller man kan la django gjøre jobben først, og så lage et script som tilbakesubstituerer det man vil tillate. Den første tilnærmingen er veldig vanskelig. Vanskeligere enn man skulle tro, faktisk. Jeg så for meg at det ville være gjennomførbart hvis man var tilstrekkelig god i regular expressions, men så kom jeg over en forumpost der det ble hevdet at det faktisk kan bevises at man ikke kan parse html med regexps, på grunn av noe med språk og nivåer og noe annet som hørtes ut som ekte vitenskap. Jeg finner den ikke akkurat nå, men
denne er mye morsommere, om enn noe mindre saklig. Jeg sakser:
Every time you attempt to parse HTML with regular expressions, the unholy child weeps the blood of virgins, and Russian hackers pwn your webapp. Parsing HTML with regex summons tainted souls into the realm of the living. HTML and regex go together like love, marriage, and ritual infanticide.
Den andre tilnærmingen, å tilbakesubstituere snill kode, er enklere, og konsekvensene av å gjøre feil er mindre, men det er fortsatt ikke trivielt. Jeg ville derfor helst unngå å måtte skrive mitt eget filter.
Digresjon: Disse to fremgangsmåtene, altså å fjerne kun slem kode, eller å først fjerne all kode, og så putte den snille tilbake igjen, kalles henholdsvis blacklist og whitelist. Whitelist er tryggere, siden det kun krever at du vet at listen din ikke inneholder potensielt farlige tags, mens en blacklist krever at du inkluderer alle potensielt farlige tags, som er en mye vanskeligere oppgave.
Jeg sjekket litt rundt, blant annet på
django-users, men det er faktisk overraskende vanskelig å finne en standard måte å håndtere dette problemet på. Jeg fant imidlertid flere henvisninger til
html5lib, som ser ut til å kunne gjøre jobben. Det kan imidlertid gjøre mye annet også, og virket litt komplisert å sette seg inn i, pluss at det bruker en hardkodet whitelist, så det er ikke superenkelt å tilpasse. Og tilpasning er nødvendig. Jeg vil for eksempel ikke tillate de samme tagene i en tittel eller en lynforumpost som i en artikkel eller en kommentar. Jeg utsatte derfor problemet, og brukte et par måneder på andre ting.
Nå nylig returnerte jeg til dette problemet, siden det er en av de viktiste tingene jeg må fikse før vi kan ta i bruk djangogutta, og denne gangen kom jeg over et verktøy som heter
bleach. Det er en html-rensker for python, skrevet av en fyr som er
webutvikler hos Mozilla, så jeg føler meg rimelig sikker på at det er bra saker. Den er basert på html5lib, men skrevet slik at det er kjempelett å bruke en egen whitelist, så han har essensielt gjort det jeg hadde sett for meg at jeg måtte gjøre, bare at det sikkert er bedre.
Jeg har derfor installert denne pakken på serveren vår (jeg installerte den i en katalog på hjemmeområdet, og la til denne i pythonpathen (la meg nok en gang nevne at jeg er kjempefornøyd med
subsys)), og tatt den i bruk. Foreløpig tillater vi følgende tags i artikler og kommentarer:
'a', 'b', 'blockquote', 'br', 'caption', 'center', 'cite', 'div', 'em', 'font', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'label', 'li', 'ol', 'p', 'small', 'span', 'strong', 'sub', 'sup', 'table', 'td', 'th', 'tr', 'tt', 'u', 'ul'
og disse i titler:
'b', 'br', 'i', 'sub', 'sup', 'u'
Hvis noen ser en som ikke burde være med, eller vil legge til en ekstra man ikke kan leve uten, er det bare å si fra. Sjekk det ut på
www.presskanne.com.
Og en ting til, bleach kommer også med en linkify-funksjon, så jeg tror vi kommer til å gå for auto-linkifisering i lynforumet. Jeg begynner å bli lei av alle problemene vi har hatt på det området.
-Tor Nordam
Comments