Fantastiset haavoittuvuudet ja niiden löytäminen (osa 1) - Sivustojenvälinen komentosarja Djangon muotovirheiden kanssa

XSS-komentosarjojen haavoittuvuudet

Miksi sivustojen välinen komentosarja (XSS) on edelleen yleisin Web-haavoittuvuus? XSS: n tunnistamisen teoria on melko suoraviivainen, sen havaitsemiseksi on luotu monia staattisia analysointityökaluja, ja silti siellä on niin paljon paljastuneita haavoittuvuuksia. Joten mitä antaa?

No, yksi syy on, että perinteisissä ohjelman analysointimenetelmissä ei usein voida tunnistaa tietyn koodin osan tarkoitusta. Työkalu saattaa esimerkiksi kamppailea selville, mitkä ohjelman objektit voivat sisältää käyttäjän syötteitä.

Edellisessä viestissäni kuvasin, kuinka olemme ratkaisseet tähän ongelmaan rakentamalla järjestelmän, joka oppii tuhansien avoimen lähdekoodin projektien tietoturvamäärityksiä ja käyttää niitä todellisten haavoittuvuuksien löytämiseen. Lupasin myös jakaa hienoja esimerkkejä siitä, mitä se oppi.

Päätin aloittaa mielenkiintoisella ja melko odottamattomalla mahdollisten aiheiden lähteellä Djangoa käyttävissä projekteissa. Tämä viesti on opas XSS-haavoittuvuuksien tunnistamiseen ja hyödyntämiseen validointivirheiden avulla Django-lomakkeissa. Tässä on todellinen esimerkki: https://github.com/mozilla/pontoon/pull/1175.

Hyppäämme suoraan siihen ja aloita pienellä tietokilpailulla. Kuinka monta kertaa olet kirjoittanut / nähnyt koodin, joka on samanlainen kuin seuraava katkelma?

Entä tämä?

Tai tämä?

Ne kaikki ovat laajalle levinneitä esimerkkejä siitä, kuinka yleensä ilmoitat käyttäjälle, että syötetty syöte on virheellinen, eikö niin? Tulo otetaan HTTP-pyyntöparametreista ja muotoillaan siististi muotoon MyForm-objektiin. Jos jokin kentistä sisältää virheellisen syötteen (esim. Joku kirjoitti merkkijonon "foobar" numeeriseen kenttään), 400 huono pyyntö -sivu palautetaan ja kuvataan virhe. Katkelmien välinen ero on palautetun virheen muoto - HTML-luettelo, selkeä teksti tai JSON.

Nyt miljoonan dollarin kysymys - mitkä näistä katkelmista tekevät verkkosovelluksestasi XSS: n?

Tutkimme Django-lomakkeiden sovellusliittymää kahdesta näkökulmasta:

  1. Pystyykö hyökkääjä syöttämään haitallisia tietoja käyttäjän selaimessa näkyvälle verkkosivulle?
  2. Päästäänkö tämä haitallisesta syötöstä aina kunnolla ennen kuin se palautetaan käyttäjälle?

Djangon asiakirjojen mukaan tapa rakentaa dynaamisia virheviestejä kentän validointivirheille on nostaa django.core.exmissions.ValidationError -poikkeus vastaavaan viestiin. Tällainen poikkeus, joka heitetään kaikista lomakkeen validointitoiminnoista (esimerkiksi django.forms.BaseForm-luokan menetelmät clean () ja clean_ ()), johtaa sanoman tallentamiseen lomakkeen virhekanavaan (django .forms.utils.ErrorDict) ja myöhemmin mahdollisesti näytetty käyttäjälle.

Yksi tapa käyttää tällaista poikkeusta on käyttää joitain sisäänrakennettuja lomakekenttiä, jotka heijastavat kätevästi viallista syöttöä poikkeussanomaan. Kokeilin kaikkia tässä lueteltuja Django-lomakekentätyyppejä ja sain seuraavan luettelon: ChoiceField, TypedChoiceField, MultipleChoiceField, FilePathField. Jokainen näistä generoi virheilmoituksen, kuten "Valitse oikea valinta.% (Arvo) s ei ole yksi käytettävissä olevista vaihtoehdoista.", Jossa arvo on viallinen syöttö. voittoa varten .

Toinen vaihtoehto on käyttää mukautettuja kenttiä ja / tai validointimenettelyjä. Harkitse esimerkiksi seuraavaa katkelmaa (otettu oikeasta projektista ja muokattu lyhyyden vuoksi):

Hyvä hyötykuorma olisi tässä jotain foo. .

Jep, olet oikeassa, pelkästään ValidationError-poikkeukset eivät anna meille XSS: ää. Oikean haavoittuvuuden saavuttamiseksi tarvitsemme vielä yhden aineosan - kyvyn injektoida virhesanomia lopulliseen HTML-sivulle, joka palautetaan käyttäjälle.

Edellä mainitussa ErrorDict-luokassa on seuraavat menetelmät virheilmoitusten purkamiseksi:

  1. as_data () - ei puhdistusta
  2. get_json_data (escape_html = False) - ei desinfiointia, jos escape_html == False (oletus)
  3. as_json (escape_html = False) ei desinfiointia, jos escape_html == False (oletus)
  4. as_ul () - turvallinen
  5. as_text () - ei puhdistusta
  6. __str __ () (kutsuu as_ul ()) - turvallinen

Palataan nyt takaisin pikkuvisaamme. On helppo nähdä, että katkelma 1 on turvallinen, koska siinä käytetään __str __ () -menetelmää, joka välttää syötteen. Katkelmat 2 ja 3 ovat kuitenkin vaarallisia ja voivat johtaa XSS: ään.

Täällä on kaksi pääasiallista takeaway-viestiä. Yksi kehittäjille on mantra “puhdista epäluotetut tiedot aina”. Turvallisuustutkijoille yksi on: yksinkertainen grep-R "ValidationError" saattaa laajentaa hyökkäyspintaasi sinulle.

Muuten, kunnioitat, jos läpäisit tietokilpailun oikein lukematta koko viestiä.

Rakennetaanko verkko- tai mobiilisovellusta?

Crowdbotics on nopein tapa rakentaa, käynnistää ja skaalata sovellus.

Kehittäjä? Kokeile Crowdbotics App Builder -sovellusta, jotta voit nopeasti rakentaa ja asentaa sovelluksia useilla suosituilla kehyksillä.

Varattu vai ei-tekninen? Liity satojen onnellisten joukkueiden rakennusohjelmistoon Crowdbotics-päämiesten ja asiantuntijakehittäjien kanssa. Crowdbotics Managed App Development -sovelluksen laajuus ja kustannukset ilmaiseksi.