Eksperter laver hitliste over farligste programmeringsfejl

En gruppe sikkerhedseksperter har sammensat en liste over de 25 fejl, der giver den største risiko for sikkerhedsproblemer og hacking.

At sikre et netværk kan til tider virke lige så uoverskueligt som en gøre en si vandtæt. Men med en liste over de 25 farligste programmeringsfejl har en gruppe eksperter nu gjort det en anelse lettere at sikre sig mod uvelkomne gæster og usikker udveksling af data.

Eksperterne, der blandt andet kommer fra The Sans Institute, MITRE, Microsoft, diverse universiteter og amerikanske sikkerhedstjenester, understreger samtidig, at en stor del af de 25 programmeringsfejl er kendetegnet ved, at ganske mange programmører ikke forstår dem, samt at der sjældent undervises systematisk.

»Effekten af disse fejl rækker langt. Alene to af dem var årsag til sikkerhedsbrud på mere end 1,5 millioner websites i 2008 ? og disse sikkerhedsbrud overførtes til computere hos de personer, der besøgte de pågældende websites, og forvandlede deres computere til zombier«, skriver Bob Martin, projektleder ved MITRE, en non-profit-sikkerhedsorganisation, i en kommentar til listen.

Sølle 25 fejl

Adskillige eksperter samt private og offentlige virksomheder har allerede rost listen som et værdifuldt værktøj i kampen mod cyberspionage og hackere.

»Når forbrugerne kan se, at sølle 25 fejl er skyld i de mest sårbare situationer, vil det formentligt skabe en ny standard for påpasselighed«, siger Konrad Vessey, kommunikationsmedarbejder i det amerikanske National Security Agency ifølge dagbladet USA Today.

Samme holdning har Ryan Barnett, sikkerhedsdirektør i virksomheden Breach Security, som i USA Today blandt andet påpeger, at man sidste år sporede mindst 1,5 millioner ondsindede programmer på nettet.

»Den afgørende forklaring er mangel på viden om sikre kodningsprincipper. Denne liste vil skabe en større bevidsthed hos udviklere og føre dem i den rigtige retning«, siger Ryan Barnett.

Tips og korrekturforslag til denne historie sendes til tip@version2.dk
Kommentarer (17)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Torben Mogensen Blogger

... er at bruge et underspecificeret og usikkert sprog som C. Flere af de nævnte fejl (CWE-119, CWE-404, CWE-665) kan helt eller delvist undgås ved at bruge sprog, der ikke tillader uinitialiserede variable, checker for grænser af arrays of offsets, bruger automatisk lageradministration, ikke tillader unsafe casts, ikke tillader nul-pointere eller pointere til lokale variabler, osv.

Det er ikke svært at sikre mod disse ting i sprog- og compiler design, og prisen i køretid er minimal, så der er ikke nogen undskyldning for at blive ved sprog som C (eller C++, der arver de fleste af C's svagheder). Det skulle da lige være vedligeholdelse af gamle systemer, hvilket er årsagen til at COBOL endnu lever.

  • 0
  • 0
Claus Stovgaard

Jeg er ikke enig i at fejlen ligger i at bruge et sprog som C. Fejlen ligger at programmøren ikke forstår hvad han skal bruge til opgaven.

Jeg er selv embedded mand, så næsten alt hvad jeg laver forgår I C, eller VHDL.

Hvornår man skal bruge en uinitialiseret variabel. Se på OpenSSL PRNG, den benytter det netop til entropi . Ellers vil en god løsning være et LFSR i en FPGA.

Har tidligere lavet en del realtime billedbehandling, og for at kunne overholde realtids kravet, så skal der netop være mulighed for at pointe til data i lokale variabler.

Så jer ser det mere som et spørgsmål om det rigtige sprog til opgaven, end at et sprog er forkert. Især et sprog som C der har haft tid til at vise sin styrke.

  • 0
  • 0
Poul-Henning Kamp Blogger

... er at bruge et underspecificeret og usikkert sprog som C. Flere af de nævnte fejl (CWE-119, CWE-404, CWE-665) kan helt eller delvist undgås ved at bruge sprog,[...]

Bare pokkers at disse sprog ofte lukker sandkassen om sig, så man ikke kan løse den foreliggende opgave på en passende effektiv vis...

Poul-Henning

  • 0
  • 0
Anonym

Jeg er selv embedded mand, så næsten alt hvad jeg laver forgår I C, eller VHDL.

At du benytter VHDL er forståeligt, hvis du f.eks. skal programmere en FPGA, men C er ikke noget særligt godt sprog til indlejret S/W. Ofte er indlejrede systemer også tidstro systemer og her er der ingen support fra C overhovedet. Derudover har C problemer med at supportere low-level I/O, da det ikke er muligt at konvertere en octetstrøm til en datatype uden at skulle gøre det "manuelt".

Har tidligere lavet en del realtime billedbehandling, og for at kunne overholde realtids kravet, så skal der netop være mulighed for at pointe til data i lokale variabler.

Hvis man ønsker at overholde krav om tidstro opførsel, er det ikke pegere, der er til nogen hjælp. Det er derimod sprogsupport for analyse af den tidslige opførsel (som C ikke har).
Derudover kunne jeg da godft tænke mig et (meget lille) eksempel på hvad du mener med at have pegere til lokale variable og deres brugen heraf.

  • 0
  • 0
Torben Mogensen Blogger

Bare pokkers at disse sprog ofte lukker sandkassen om sig, så man ikke kan løse den foreliggende opgave på en passende effektiv vis...

Det er kun et god argument, hvis du har meget strikse ressourcekrav. C bliver brugt mange steder, hvor disse krav ikke er til stede. Og mener du virkelig, at alle C's underspecificerede opførsler og usikkerheder er nødvendige for at kunne programmere effektivt?

Hvornår man skal bruge en uinitialiseret variabel. Se på OpenSSL PRNG, den benytter det netop til entropi.

Da C ikke laver nogensomhelst garantier for opførslen af ikke-initialiserede variabler, ser jeg dette som en meget risikabel brug, som i værste fald åbner for sikkerhedshuller.

  • 0
  • 0
Carsten Frigaard

Men du kan nemt løse dit problem i C ved at få f.eks. GCC til at advare om uinitialiserede variable (-Wuninitialized) eller indføre en garbage collector i C (f.eks en Boehms GC, fundet gratis og fri på nettet)....

Kigger du næremere på de famøse 25 fejl, f.eks et par af dem du nævner

CWE-119: Failure to Constrain Operations within the Bounds of a Memory Buffer

CWE-404: Improper Resource Shutdown or Release

CWE-665: Improper Initialization

så dækker de lidt bredere, og at skyde C skylden i skoene er nok lidt for hurtigt. 404 og 665 kunne vel ligeså findes i Java eller lign. Spørgsmålet er nærmere om man ikke skal bruge værktøjer til semantisk at checke koden istedet for at tro på at det sidste nye skrig indefor programmering vil rede din røv?

Eller med andre ord: gamle programmeringssprog = kendte fejl og mangler på lavt niveau, nye programmeringssprog = nye fejl og mangler på et højere niveau.

mvh
.carsten

  • 0
  • 0
Daniel Møller

Eller med andre ord: gamle programmeringssprog = kendte fejl og mangler på lavt niveau, nye programmeringssprog = nye fejl og mangler på et højere niveau.

Sikkerheds-fælder på lavt niveau vil man tilgengæld ramme ind i med en væsentlig højere frekvens end sikkerheds-fælder på et højere abstraktionsniveau.

Og jo højere abstraktions-niveau, desto størrer sandsynlighed er der for at man kan skrive kode der tager hånd om problematikken - specielt fordi performance somregel er af mindrer afgørende betydning end når vi snakker low-level kode.

Noget af det der imo gør C# til et godt general-purpose sprog er netop evnen til at sandboxe i de måske 99% af tiden hvor man skriver kode hvor f.eks. pointer-aritmetik ikke er af afgørende betydning og hvor man hellere vil have sikkerheden. Men samtidig tilbyde at man explicit kan hoppe ud af sandkassen i de her resterende 1% af tilfældende hvor man måske arbejder med high-performance kode.

Her synes jeg Java begår en fejl ved at insistere på at pakke udviklere ind i vat.

  • 0
  • 0
Klaus Petersen

Jeg foretrækker ikke at tænke over sikkerhed og den slags tjavs, med mindre det er i en kontekst hvor den slags er bydende nødvendigt.

Når det så er sagt, så er den slags information stadig god læsning. Hvorfor? Jo, fordi de nævnte fejltagelser er en kilde til bugs, der kan være fordømt svære at få ram på, hvis ikke man har en idé om hvad der er galt.

Mht enhver form for 'religionskrige' over programmerings-sprogs styrker og svagheder - Scotty says: "The right tool for the right job, damn you! How many times do I have to tell you?"

Der var en gang, hvor det amerikanske forsvar ville have det perfekte programmeringsprog. De fik Ada. Der er amerikanere, for hvem man ikke skal vove at sige det navn højt.

  • 0
  • 0
Anonym

Når jeg kigger i en log vi har for knap et år, så topper angrebsforsøg mod web med forsøg på remote execution af PHP kode.

Den ville jeg betragte som den absolut største trussel mod infection af websider.

(MS) SQL injection forekommer tilsyneladende kun i bølger.

Sprog synes jeg ikke jeg vil lave religionskrig, men til orientering var:
MPE/iX (HP3000)
http://en.wikipedia.org/wiki/HP_3000
inklusive alle subsystemer skrevet i Pascal (+ lidt modcal)

VOS (Stratus aka IBM system 88 aka Olivetti CPS32)
http://en.wikipedia.org/wiki/Stratus_VOS
inklusive drivere osv også Pascal.

  • 0
  • 0
Torben Mogensen Blogger

at skyde C skylden i skoene er nok lidt for hurtigt. 404 og 665 kunne vel ligeså findes i Java eller lign.

Det er så også nogle af de ting, jeg ville lave om på Java, hvis jeg havde magten til det. :-)

Spørgsmålet er nærmere om man ikke skal bruge værktøjer til semantisk at checke koden istedet for at tro på at det sidste nye skrig indefor programmering vil red[d]e din røv?

Sådanne semantiske checks er generelt uafgørlige, så man vil enten overse mange fejl eller få mange falske positiver. Og C's underspecificerede semantik gør analyserne meget upræcise, så "ægte" fejl drukner i falske.

Så er det bedre at sikre, at man slet ikke kan lave disse fejl, eller i det mindste, at lave sproget, så analyserne kan laves mere præcise. Så kan du kalde den semantiske analyse for typeinferens. :-)

  • 0
  • 0
Anonym

Sådanne semantiske checks er generelt uafgørlige, så man vil enten overse mange fejl eller få mange falske positiver. Og C's underspecificerede semantik gør analyserne meget upræcise, så "ægte" fejl drukner i falske.

Ja det er et problem ved statisk analyse af C - selv ved brug af MISRA C.

Hvis man benytter SPARK er man dog sikret mod de problemer, du nævner, og så har man endda mulighed for at bevise partiel[1] korrekthed.

[1] Termineringsproblemet spøger selvfølgelig stadig.

  • 0
  • 0
Anonym

Der var en gang, hvor det amerikanske forsvar ville have det perfekte programmeringsprog. De fik Ada. Der er amerikanere, for hvem man ikke skal vove at sige det navn højt.

Jeg er lige starte på et projekt, hvor vi har valgt Ada som programmeringssprog. Det er sket ud fra kriterier som support af tidstro opførsel, ingen skjult brug af dynamisk lagerallokering, stærke datatyper, support for modularisering og generelle krav om høj kvalitet.

Jeg kender ikke til andre sprog (udover Ada delmængden SPARK), der kan afløse Ada. Du skal da være velkommen til at foreslå nogle!

  • 0
  • 0
Klaus Petersen

Tjaah ... med et sprog så komplekst og ambitiøst som Ada, så bliver du ret afhængig af kvaliteten af compileren. Med hensyn til alternativer, så har jeres team, for mig at se, allerede truffet jeres valg af ret sobre grunde.

Resten handler om alt mulig andet, og ingen diskussion her kan gøre forskellen mellem succes og fiasko.

  • 0
  • 0
Jens Madsen

Oprindeligt, er den eneste årsag til C, at det oversætter effektiv, med en lille compiler. I dag, kan du med langt mere ideelle sprog, opnå en ligeså god oversættelse - eller måske bedre - fordi compileren er mere intelligent. Eksempelvis er ingen grund til i++ mv. som del af sætninger, da man altid kan analysere dette, og gøre det samme automatisk.

I forbindelse med embedded elektronik, er årsagen til C, at compilerne er simple - og det er stor sandsynlighed for, at der findes en compiler. Samtidigt, lægges stadigt lidt vægt på resourceforbruget. Men normalt kan det ikke begrunde anvendelsen af C.

Det, som derimod kan begrunde anvendelsen af C, er overskuelighed fra C kode, til maskinkode. Skal du stå inde for, at compileren har gjort sit arbejde korrekt, er det nemmere at validere en C compilers job manuelt, end C++ og Java. Samarbejdet mellem maskinkode og C kode, fungerer også godt.

I modsætning til hvad mange tror, er C dog ikke et ideelt sprog med hensyn til resourcer. Faktisk fylder oversatte sprog enormt. Det mest idelle, er stadigt, at undersøge opgaven, og bygge alt op omkring en fortolker, så mest muligt skrives i et fortolket sprog til opgaven. Når dette fortolkede sprog, "compileres" til kode, der er nemt at håndtere af noget maskinkode, eller C kode, vil koden som regel være langt mindre. Og det er oftest nemmere at vedligeholde. Hvis nogen husker tiden fra Basic, så skete reelt det, at programmerne steg med en faktor 10-20, ved overgangen til C og pascal. De første medtog hele biblioteker uden oprydning, og det var årsagen. Men selv efter dette blev optimeret bort, var ofte en faktor 5 større kode, i et C program end et "basic" program.

Hastighedsmæssigt, er fortolket kode, ofte også bedre end C - her er programmøren bevidst om hastighedsproblemet på forhånd, og udvikler kode med optimale store O funktioner. Samtidigt, ved man hvor flaskehalsene er i koden, og disse dele analyseres, for at finde de få indstruktioner der er specielt kritiske - og disse laves som specielle indstruktioner, der måske søger noget igennem, og implementeres i assembler. Ialt vil et fortolket sprog, fordi de kritiske dele er i assembler (ofte kun simple søge ordre, erstat ordre mv), normalt gå hurtigere, end compileret C kode, fordi den del af koden, som udføres 85% af tiden oftest foregår i maskinkode. Det viser sig, at største delen af kode, normalt står og laver nogle ganske få operationer, måske søger/ændrer i træer, eller endog kører samme kode.

I forbindelse, med embeddede applikationer, kan jeg godt acceptere C og VHDL, såfremt at koden er lille, og overskueligt. Men begynder du, at opnå kode i megabyte størrelse, vil jeg bestemt synes, at du skal satse på et bedre sprog, eller sikre at størstedelen af koden er "data", f.eks. fortolkede symboler. Enten, må opgaven gribes bedre an, så koden fylder mindre, og fejlrisikoen minimeres ved brug af C, eller der må bruges sprog, som er egnet til en så stor opgave.

  • 0
  • 0
Jens Madsen

Hvornår man skal bruge en uinitialiseret variabel. Se på OpenSSL PRNG, den benytter det netop til entropi . Ellers vil en god løsning være et LFSR i en FPGA.

Her må jeg sige, at jeg er rimeligt uenig med dig - og min opfattelse er, at din holdning må skyldes en total misforståelse, eller mangel på forståelse omkring programmeringssprog og kodning. Kodning, skal beskrive, hvad du ønsker gjort - og den skal ikke bero på et "misfoster" i programmeringssproget, såsom en uinitialiseret variabel. Derfor, må du ikke anvende uinitialiserede variable. Den rette metode, er at bruge en random funktion. På den måde, er din kode fremtidssikret, så den i princippet, vil kunne anvendes, af en bedre compiler, der ikke accepterer uinitialiserede variable.

I assembler, begynder vi at kunne diskutere om ovenstående gælder. Her, beskriver du, hvordan du ønsker en opgave udført af CPU'en. Det er ikke et rigtigt programmeringssprog. Alligevel, bør du lave assembler kode så struktureret som mulig, og samle din tilfældighedsfunktion i en rutine, så det er nemt at ændre metoden. Måske, er den netop ikke tilfældig nok, fordi en anden programmør lægger en ramcheck rutine der nulstiller ram'en ind ved opstart. Under alle omstændigheder, er det derfor dårlig kode.

Genneralt gælder, at et programmeringssprog skal være deterministisk, og ikke må kunne udføre tilfældigheder, med mindre sproget direkte instrueres deri, f.eks. ved brug af random funktionen. Ofte, er på specifikationsniveau, lagt regler for, hvilke dele der skal være deterministiske, og sproget kan indeholde strukturer der ulovliggør brugen af random i dele af koden, der ikke må indeholder tilfældighed - det som indeholder tilfældighed, er måske begrænset til, at må kodes af ganske få programmører, der har et specielt ansvar. Det kan ofte hjælpe til færre fejl, at specificere en stor del, eller største delen af koden, er af deterministisk struktur, og kun må kodes deterministisk. Deterministisk kode, er ofte mere beviseligt, det kan bedre logges, det er nemmere at notere fejl mv. og det har derfor mange positive egenskaber. Det kan være direkte farligt, at lade enhver programmør, kode ikke deterministisk kode - eksempelvis kan måske ikke optages en keystroke, og programmets bad behavior bevises og analyseres, hvorefter programmøren kan sættes for en domstol og retten.

  • 0
  • 0
Anonym

Tjaah ... med et sprog så komplekst og ambitiøst som Ada, så bliver du ret afhængig af kvaliteten af compileren.

Ada er er stort sprog, men det er nu ikke særlig komplekst og faktisk mindre komplekst end C++.

Mht. oversætter, så kan jeg varmt anbefale GNU Ada oversætteren, da jeg har brugt den med success i flere projekter. GNU Ada er en Ada front-end til den velkendte GCC compiler (der også har en C, C++ mv. front-end).

  • 0
  • 0
jonas førstø

Programserien Testen på DR1 er i gang med at lave et program om IT-kriminalitet.

Jeg vil gerne høre om konkrete eksempler, hvor I har fundet sårbarheder på danske sites, hvor I har kontaktet ejerne for at forklare dem om problemet, og hvor der ikke efterfølgende er blevet gjort noget for at rette op på situationen.

Kontakt mig på jokf@dr.dk
Mvh
Jonas Førstø
Testen/DR

  • 0
  • 0
Log ind eller Opret konto for at kommentere