JavaScript fejler rigeligt i Node.js-økosystemet – fundet automatisk PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

JavaScript-fejler rigeligt i Node.js-økosystemet – fundet automatisk

Her er et interessant papir fra den nylige 2022 USENIX-konference: Mining af Node.js-sårbarheder via objektafhængighedsgraf og -forespørgsel.

Vi vil snyde en lille smule her ved ikke at grave i og forklare kerneforskningen præsenteret af forfatterne af artiklen (noget matematik og kendskab til operationel semantik notation er ønskværdigt, når man læser det), som er en metode til statisk analyse af kildekode, som de kalder ODGEN, en forkortelse for Objektafhængig grafgenerator.

I stedet ønsker vi at fokusere på implikationerne af, hvad de var i stand til at opdage i Node Package Manager (NPM) JavaScript-økosystemet, stort set automatisk ved at bruge deres ODGEN-værktøjer i det virkelige liv.

En vigtig kendsgerning her er, som vi nævnte ovenfor, at deres værktøjer er beregnet til det, der er kendt som statisk analyse.

Det er her, du sigter mod at gennemgå kildekoden for sandsynlige (eller faktiske) kodningsfejl og sikkerhedshuller uden faktisk at køre den overhovedet.

Test-det-ved-køre-det er en meget mere tidskrævende proces, der generelt tager længere tid at konfigurere og længere tid at gøre.

Som du kan forestille dig, dog såkaldte dynamisk analyse - faktisk at bygge softwaren, så du kan køre den og udsætte den for rigtige data på kontrollerede måder - giver generelt meget mere grundige resultater og er meget mere tilbøjelige til at afsløre mystiske og farlige fejl end blot at "se på det omhyggeligt og forstå, hvordan det virker ”.

Men dynamisk analyse er ikke kun tidskrævende, men også svært at gøre godt.

Med dette mener vi virkelig, at dynamisk softwaretest er meget let at gøre dårligt, selvom du bruger evigheder på opgaven, for det er nemt at ende med et imponerende antal tests, der alligevel ikke er helt så varierede, som du troede, og som din software er næsten sikker på at bestå, uanset hvad. Dynamisk softwaretest ender nogle gange som en lærer, der stiller de samme eksamensspørgsmål år efter år, så elever, der har koncentreret sig helt om at øve sig på "tidligere opgaver", ender med at klare sig lige så godt som elever, der virkelig har mestret faget.

Et tragisk net af forsyningskædeafhængigheder

I nutidens enorme kildekodeøkosystemer for software, hvoraf globale open source-lagre som NPM, PyPI, PHP Packagist og RubyGems er velkendte eksempler, er mange softwareprodukter afhængige af omfattende samlinger af andres pakker, hvilket danner et komplekst, forfærdeligt forsyningsnet. kædeafhængigheder.

Implicit i disse afhængigheder, som du kan forestille dig, er en afhængighed af hver dynamisk testsuite leveret af hver underliggende pakke – og disse individuelle tests tager generelt ikke (kan faktisk ikke) højde for, hvordan alle pakkerne vil interagere, når de 'er kombineret for at danne din egen, unikke applikation.

Så selvom statisk analyse i sig selv ikke er tilstrækkelig, er det stadig et glimrende udgangspunkt for at scanne softwarelagre for skarpe huller, ikke mindst fordi statisk analyse kan udføres "offline".

Især kan du regelmæssigt og rutinemæssigt scanne alle de kildekodepakker, du bruger, uden at skulle konstruere dem til kørende programmer og uden at skulle komme med troværdige testscripts, der tvinger disse programmer til at køre på en realistisk række forskellige måder.

Du kan endda scanne hele softwarelagre, inklusive pakker, du måske aldrig skal bruge, for at ryste kode ud (eller for at identificere forfattere), hvis software du ikke er tilbøjelig til at stole på, før du overhovedet prøver det.

Endnu bedre, nogle typer statisk analyse kan bruges til at gennemse al din software for fejl forårsaget af lignende programmeringsfejl, som du lige har fundet via dynamisk analyse (eller som blev rapporteret gennem et bug bounty-system) i en enkelt del af en enkelt software produkt.

Forestil dig for eksempel en fejlrapport fra den virkelige verden, der kom ind fra naturen baseret på et bestemt sted i din kode, hvor du havde brugt en kodningsstil, der forårsagede en bruge efter frigivelse hukommelsesfejl.

A bruge efter frigivelse er der, hvor du er sikker på, at du er færdig med en bestemt hukommelsesblok, og afleverer den tilbage, så den kan bruges andre steder, men glemmer så, at den ikke er din mere og fortsæt med at bruge den alligevel. Som ved et uheld at køre hjem fra arbejde til din gamle adresse måneder efter, du flyttede ud, bare af vane, og undre dig over, hvorfor der er en mærkelig bil i indkørslen.

Hvis nogen har kopieret og indsat den buggy-kode i andre softwarekomponenter i dit firmalager, kan du muligvis finde dem med en tekstsøgning, forudsat at den overordnede struktur af koden blev bibeholdt, og at kommentarer og variabelnavne blev brugt ikke ændret sig for meget.

Men hvis andre programmører blot fulgte det samme kodesprog, måske endda omskriver den fejlbehæftede kode til et andet programmeringssprog (i jargonen, så det var leksikalsk anderledes) ...

… så ville tekstsøgning være tæt på nytteløs.

Ville det ikke være praktisk?

Ville det ikke være praktisk, hvis du statisk kunne søge i hele din kodebase for eksisterende programmeringsfejl, ikke baseret på tekststrenge, men i stedet på funktionelle funktioner såsom kodeflow og dataafhængigheder?

Nå, i USENIX papiret, vi diskuterer her, har forfatterne forsøgt at bygge et statisk analyseværktøj, der kombinerer en række forskellige kodekarakteristika til en kompakt repræsentation, der angiver "hvordan koden omdanner sine input til sine output, og hvilke andre dele af koden får indflydelse på resultaterne”.

Processen er baseret på de førnævnte objektafhængighedsgrafer.

Enormt forenklet er ideen at mærke kildekoden statisk, så du kan se, hvilke kombinationer af kode-og-data (objekter), der er i brug på et tidspunkt, der kan påvirke objekter, der bruges senere.

Så burde det være muligt at søge efter kendt dårlig kodeadfærd – lugter, i jargonen – uden faktisk at skulle teste softwaren i en live-run og uden kun at skulle stole på tekstmatchning i kilden.

Med andre ord kan du muligvis opdage, om koder A har produceret en lignende fejl som den, du lige har fundet fra koder B, uanset om A bogstaveligt talt kopierede B's kode, fulgte B's fejlagtige råd eller blot valgte de samme dårlige arbejdspladsvaner som B.

Løst sagt kan god statisk analyse af kode, på trods af at den aldrig ser softwaren køre i det virkelige liv, hjælpe med at identificere dårlig programmering lige i starten, før du injicerer dit eget projekt med fejl, der kan være subtile (eller sjældne) nok i det virkelige liv, at de aldrig dukker op, selv under omfattende og strenge live-tests.

Og det er den historie, vi satte os for at fortælle dig i starten.

300,000 pakker behandlet

Forfatterne til papiret anvendte deres ODGEN-system på 300,000 JavaScript-pakker fra NPM-lageret for at filtrere dem, som deres system foreslog kunne indeholde sårbarheder.

Af disse beholdt de pakker med mere end 1000 ugentlige downloads (det ser ud til, at de ikke havde tid til at behandle alle resultaterne), og bestemte ved yderligere undersøgelse de pakker, hvor de troede, de havde afsløret en fejl, der kunne udnyttes.

I disse opdagede de 180 skadelige sikkerhedsfejl, inklusive 80 kommandoindsprøjtningssårbarheder (det er her, upålidelige data kan overføres til systemkommandoer for at opnå uønskede resultater, typisk inklusive fjernudførelse af kode), og 14 yderligere kodeudførelsesfejl.

Af disse fik 27 i sidste ende CVE-numre, der genkendte dem som "officielle" sikkerhedshuller.

Desværre er alle disse CVE'er dateret 2019 og 2020, fordi den praktiske del af arbejdet i dette papir blev udført for mere end to år siden, men det er først blevet skrevet op nu.

Ikke desto mindre, selvom du arbejder i en mindre udbredt luft end akademikere ser ud til (for de fleste aktive cybersikkerhedsresponderere betyder bekæmpelse af nutidens cyberkriminelle at afslutte enhver forskning, du har lavet, så snart du kan, så du kan bruge den med det samme)...

…hvis du leder efter forskningsemner til at hjælpe mod forsyningskædeangreb i nutidens gigantiske softwarelagre, så overse ikke statisk kodeanalyse.

Livet i den gamle hund endnu

Statisk analyse er faldet i en vis unåde i de senere år, ikke mindst fordi populære dynamiske sprog som JavaScript gør statisk behandling frustrerende hårdt.

For eksempel kan en JavaScript-variabel være et heltal på et tidspunkt, og derefter få en tekststreng "føjet" til den helt lovligt om end forkert, og dermed gøre den til en tekststreng, og kan senere ende som endnu en objekttype helt.

Og en dynamisk genereret tekststreng kan på magisk vis blive til et nyt JavaScript-program, kompileret og eksekveret på runtime, og dermed introducere adfærd (og fejl), der ikke engang eksisterede, da den statiske analyse blev udført.

Men dette papir antyder, at selv for dynamiske sprog kan regelmæssig statisk analyse af de arkiver, du stoler på, stadig hjælpe dig enormt.

Statiske værktøjer kan ikke kun finde latente fejl i kode, du allerede bruger, selv i JavaScript, men også hjælpe dig med at bedømme den underliggende kvalitet af koden i alle pakker, du overvejer at adoptere.


LÆR MERE OM FOREBYGGELSE AF FORSYNINGSKÆDEANgreb

Denne podcast indeholder Sophos-ekspert Chester Wisniewski, Principal Research Scientist hos Sophos, og den er fuld af nyttige og brugbare råd om håndtering af forsyningskædeangreb, baseret på de erfaringer, vi kan lære af gigantiske angreb i fortiden, såsom Kaseya og SolarWinds.

Hvis der ikke vises en lydafspiller ovenfor, lytte direkte på Soundcloud.
Du kan også læse hele podcasten som en fuld udskrift.


Tidsstempel:

Mere fra Naked Security