Ohjelmistojen haavoittuvuuksien tunnistuksessa perinteiset staattiset ja dynaamiset analyysimenetelmät ovat sääntöpohjaisia, ja niiden tehokkuus on usein rajoittunutta. Symbolinen suoritus tarjoaa vaihtoehdon analysoimalla ohjelman ohjausvirtaa symbolisten arvojen avulla, mutta se on laskennallisesti kallis eikä skaalaudu hyvin suuriin kokonaisuuksiin. Tietoturva-aukkojen arvioinnissa on viime vuosina sovellettu tukivektorikonetta (SVM) käyttämällä tokenisoidun Java-koodin sanapussimallia ja myöhemmin n-gram-ominaisuuksia, mutta syväoppimisen hyödyntäminen on jäänyt vielä vähäiseksi rajallisen datan takia.
Keskitymme tässä lähestymistavassa ohjelmistopakettien analysointiin erittäin hienojakoisella tasolla, eli funktioissa, jotka muodostavat aliohjelmien kokonaisvirran. Käytetty testiaineisto, SATE IV Juliet -testisarja, sisältää noin 118 yleistä heikkoutta ja koostuu pääosin synteettisestä koodista. Koska synteettinen koodi eroaa luonnollisesta koodista, analyysin tueksi on yhdistetty Debianin paketteja ja GitHubin avoimen lähdekoodin arkistoja, joita on merkitty staattisten analyysityökalujen avulla. Merkintäprosessi on haasteellinen, koska avointen lähteiden haavoittuvuuksien todellista tilaa ei aina tunneta täysin, ja siksi yhdistetään staattisen analyysin tulokset dynaamiseen analyysiin ja bugiraportteihin.
Ominaisuuksien luomiseksi lähdekoodista on kehitetty erikoistyökalu, joka tiivistää keskeiset tokenit niiden merkityksen mukaan ja pienentää sanaston laajuutta. Lopulliseen malliin valittiin 156 tokenia, joilla pyritään välttämään ylioppimista. Käännökseen vaikuttamattomat koodin osat poistettiin, ja datatyypit standardikirjastoista yhdistettiin geneerisiin tokeneihin, jotka vaikuttavat haavoittuvuuksiin. Toistuvat funktiot karsittiin mallin suorituskyvyn parantamiseksi, ja erityistä huomiota kiinnitettiin lähes identtisten funktioiden erotteluun. Kontrollivirta-analyysi sekä peruslohkojen tason tarkastelu auttoivat tunnistamaan ominaisuuksien duplikaatit.
Syväoppimismalleissa lähdekoodi esitetään abstraktin syntaksipuun avulla, ja CNN- ja RNN-verkkoja käytetään tunnistamaan haavoittuvuuksien kuvioita. Tokenien upotukset toteutettiin k-dimensionaalisina arvoina välillä −1 ja +1, joita koulutettiin backpropagaatiolla. Sanasto pidettiin pienenä ylioppimisen estämiseksi, ja tähän liittyen lisättiin pieni määrä Gaussin melua, joka osoittautui tehokkaammaksi säännöllistämiskeinoksi kuin painojen hajoamiseen perustuvat menetelmät. CNN:ssä käytettiin useita suodattimia, jotka skannaavat upotusten tilaa tietyn tokenien määrän kerrallaan, ja aktivointikerroksena toimi ReLU. RNN-arkkitehtuureina hyödynnettiin monikerroksisia gated recurrent unit (GRU) ja pitkän aikavälin muisti (LSTM) -verkkoja, jotka kykenevät havaitsemaan pitkän kantaman riippuvuuksia. Funktioiden pituuden vaihdellessa käytettiin max-pooling -kerrosta ja drop-out -säännöllistystä ylioppimisen hallitsemiseksi. Luokittelijan lopussa softmax-kerros aggregoi tulokset.
Malli vaatii tarkkaa hyperparametrien viritystä, kuten optimaaliset eräkoot, token-pituus ja oppimisnopeus Adam-optimisaattorilla. Koska aineisto on epätasapainoinen, häviöfunktioon lisätään suuremmat painot haavoittuviin luokkiin. Mallin validointiin käytetään erillistä aineistoa, joka varmistaa yleistettävyyden.
Lisäksi on tärkeää ymmärtää, että vaikka syväoppiminen tarjoaa tehokkaita keinoja haavoittuvuuksien tunnistamiseen, sen menestys riippuu olennaisesti laadukkaasta ja monipuolisesta datasta. Synteettiset testiaineistot eivät yksinään riitä kattamaan kaikkia todellisen maailman ohjelmointikäytäntöjä, joten yhdistelmä luonnollisesta koodista ja tarkoin merkitty aineisto on välttämätöntä. Merkintäprosessin automaatio vaatii edelleen inhimillistä asiantuntija-arviointia, mikä korostaa ihmisen ja koneen yhteistyön merkitystä tietoturva-analyysissä. Lisäksi syväoppimismallien tulkinta ja ymmärtäminen on haastavaa, mikä edellyttää kehittyneitä menetelmiä mallien päätösten selittämiseen ja luottamuksen rakentamiseen.
Miten vaatimusten jäljitettävyyttä voidaan parantaa syväoppimisen avulla ohjelmistokehityksessä?
Vaatimusten jäljitettävyyttä (Requirement Traceability, RT) tarkastellaan ohjelmistokehityksessä kahdesta eri näkökulmasta: ennen vaatimusten määrittelyä tapahtuva jäljitettävyyden ja vaatimusten määrittelyn jälkeen tapahtuvan jäljitettävyyden kautta. Useimmat vaatimuksiin liittyvät ongelmat voidaan jäljittää juuri ennen vaatimusten määrittelyä tapahtuvaan jäljitettävyyteen, sillä tämän vaiheen ongelmat eivät ole saaneet riittävää analyysiä. Vaikka vaatimusten prosessin parantamiseen on tehty tutkimusta, tämä osa-alue on yhä haasteellinen puutteellisten ongelmanmäärittelyjen vuoksi. Ennen vaatimusten määrittelyä tapahtuva jäljitettävyyden ongelmat jäävät usein huomiotta, ja niitä ei ole käsitelty perusteellisesti.
Ennen vaatimusten määrittelyä, jäljitettävyyttä käsitellään siinä vaiheessa, kun vaatimuksia ei ole vielä dokumentoitu, ja ne ovat osittain muotoutumassa. Ratkaisut tähän ongelmaan eivät ole kyenneet tarkastelemaan ongelman ydintä riittävän syvällisesti, mikä on heikentänyt ratkaisujen kattavuutta. Vaatimusten jäljitettävyyden ongelman määritelmä on epäselvä, ja ratkaisut keskittyvät enemmän siihen, miten ongelmat tulisi ratkaista, kuin siihen, mikä itse ongelma on. Vaatimusten jäljitettävyyden kannalta keskeinen ero on se, että jäljitettävyyden hallinta ennen vaatimusten määrittelyä keskittyy alkuperäisiin dokumentteihin ja sen, kuinka hyvin alkuperäiset tiedot voivat tukea jäljitettävyyttä vaatimusten kehityksessä.
Vaatimusten jäljitettävyyden ratkaiseminen ennen ja jälkeen määrittelyvaiheen eroaa huomattavasti. Määrittelyvaiheen jäljitettävyys riippuu kyvystä jäljittää vaatimukset alkuperäisiin dokumentteihin, ja siihen sisältyy vaatimusten hienosäätöprosessi, joka käyttää useita eri lähteitä. Tällä alueella ongelmat liittyvät usein siihen, että muutosvaatimuksia ei hallita riittävän hyvin ja jäljitettävyyttä ei voida varmistaa tarvittavassa laajuudessa.
Toisaalta, jäljitettävyyden hallinta vaatimusten määrittelyn jälkeisessä vaiheessa keskittyy muutosprosessien seuraamiseen ja siihen, kuinka hyvin vaatimusten muutokset voivat kulkea alkuperäisten spesifikaatioiden kautta dokumentointiprosessissa. Tämä vaihe on tärkeä, sillä siinä hallitaan kehitysprosessin aikana tapahtuvat muutokset, jotka voivat vaikuttaa vaatimuksiin ja niiden toteutukseen.
Vaatimusten jäljitettävyyden parantaminen on myös laajemmin yhteydessä ohjelmistokehityksen elinkaaren eri vaiheisiin. Yksi suurimmista haasteista on vaatimusten jäljitettävyyden heikko hallinta ennen vaatimusten määrittelyä, mikä johtuu usein siitä, että vaatimusten määrittelyn alkuvaiheessa ei ole riittävästi huomiota kiinnitetty tiedonkeruuseen ja sen jäljittämiseen. Näin ollen kehittäjät, jotka ovat vastuussa vaatimusten käsittelystä, saattavat kohdata vaikeuksia, koska vaatimusten alkuperä on epäselvä ja se, mitä vaatimuksilta tarkalleen ottaen odotetaan, jää usein hämäräksi.
Muutoksenhallinta on yksi kriittinen alue, joka vaikuttaa vaatimusten jäljitettävyyteen. Ennen vaatimusten määrittelyä ongelmat liittyvät siihen, kuinka paljon aikaa ja resursseja on käytettävissä jäljitettävyyden luomiseen ja kuinka se vaikuttaa ohjelmistokehityksen aikarajoihin. Kehittäjillä ei ole aina tarpeeksi aikaa ja resursseja, jotta vaatimukset voitaisiin järjestää ja ylläpitää asianmukaisesti, mikä johtaa usein siihen, että jäljitettävyyden laadun parantaminen jää toissijaiseksi. Tämä ongelma korostuu erityisesti, kun käyttäjät ja kehittäjät ovat samassa roolissa tai toimivat läheisesti toisiinsa nähden.
Vaatimusten jäljitettävyyden parantaminen ennen määrittelyä ei ole pelkästään tiedonhallintaa, vaan siihen liittyy myös roolien selkeä määrittely. Dokumentaation asiantuntijat ja muut roolit voivat auttaa tasoittamaan jäljitettävyyteen liittyviä haasteita ja parantamaan tiedon keruuprosessia. Samalla on tärkeää, että ohjelmistokehityksessä käytettävä tieto saadaan riittävän tarkasti ja kattavasti aikaiseksi, jotta vaatimukset voidaan dokumentoida ja myöhemmin jäljittää.
Tähän liittyy myös automaation lisääminen ja jäljitettävyyttä tukeviin toimiin panostaminen. Useiden tutkimusten mukaan syväoppimisen, erityisesti luonnollisen kielen käsittelyn (NLP), sanasijoittelujen ja neuroverkkojen, kuten pitkän aikavälin muistiyksiköiden (LSTM), hyödyntäminen voi tarjota merkittäviä parannuksia jäljitettävyyden hallintaan. Näitä menetelmiä voidaan käyttää vaatimusten kehityksessä kerättyjen tekstidatan analysointiin, ja niillä voidaan parantaa sekä ennen määrittelyä että sen jälkeistä jäljitettävyyttä.
Samalla kun jäljitettävyyden hallinta kehittyy, on tärkeää keskittyä myös vaatimusten ei-toiminnallisten piirteiden jäljitettävyyteen. Tämä voi sisältää esimerkiksi ohjelmiston turvallisuusvaatimukset, suorituskykyvaatimukset ja muut ei-funktionaaliset tekijät, jotka ovat olennaisia ohjelmiston elinkaaren kannalta mutta usein jäävät vähemmälle huomiolle. Tämän takia tarkasteltavan järjestelmän laaja-alainen ja syvällinen analyysi on tärkeää, jotta voidaan parantaa vaatimusten jäljitettävyyttä kaikilla tasoilla.
Kuinka tilastolliset kielimallit paljastavat ohjelmistokoodin luonnollisuuden ja säännönmukaisuuden?
Ristientropia on keskeinen käsite, jolla mitataan ohjelmistokoodin luonnollisuutta suhteessa tilastolliseen kielimalliin. Tämän mittarin avulla arvioidaan, kuinka todennäköisesti tietty dokumentti, esimerkiksi kooditiedosto, syntyy mallin oletusten mukaan. Malli kuvaa kielen todennäköisyysjakaumaa, ja ristientropia kertoo, kuinka yllätyksellinen tai ennustettava aineisto on. Matala ristientropia viittaa siihen, että aineisto on hyvin ennustettavissa mallin perusteella, mikä puolestaan tarkoittaa koodin säännönmukaisuutta ja "luonnollisuutta".
Tutkimukset ovat hyödyntäneet eri korpuksia, kuten Gutenbergin ja Brownin luonnollisen kielen aineistoja sekä Ubuntun sovelluskokoelmaa ja Java-projekteja ohjelmistokoodin puolella. Lexikaalinen analyysi ja tokenisointi mahdollistavat n-grammimallien rakentamisen, joissa mallin oppima konteksti koostuu edeltävistä sanoista tai koodelementeistä. Java ja C ovat olleet tutkimusten pääkieliä, mikä helpottaa vertailua ja laajennuksia. Mallin koulutuksessa aineisto jaetaan koulutus- ja testijoukkoihin, ja suoritetaan kymmenkertainen ristiinvalidointi, jotta tulokset ovat luotettavia.
N-grammimallit paljastavat mielenkiintoisen ilmiön: Java-ohjelmistokoodin ristientropia pienenee huomattavasti nopeammin kuin englannin kielen aineistolla, erityisesti kolmikko- tai neljänkokoisten n-grammien kohdalla. Tämä osoittaa, että ohjelmistokoodin paikallinen konteksti toistuu erittäin säännönmukaisesti, aivan kuten luonnollisessa kielessä. Java-kielen rakenteen selkeys ja johdonmukaisuus ovat osasyitä tähän, mutta tutkimukset osoittavat, ettei pelkkä kielen yksinkertaisuus riitä selittämään havaittuja alhaisia ristientropioita.
Projekti- ja domain-spesifisyys korostuvat, kun verrataan ristientropioita eri Java-projektien välillä. Mallin kyky yleistää yhdestä projektista toiseen vaihtelee, mikä tarkoittaa, että projektit sisältävät ainutlaatuisia piirteitä ja domainiin sidottuja säännönmukaisuuksia. Tämä johtaa siihen, että koodin tilastolliset mallit pystyvät paitsi tunnistamaan kielen yleisiä rakenteita, myös sovellusalueiden erityispiirteitä. Näitä ominaisuuksia voidaan hyödyntää muun muassa IDE-ohjelmistojen koodiehdotusmoottoreissa, jolloin ehdotukset perustuvat sekä kielen rakenteeseen että projektikohtaisiin käytäntöihin.
Koodin seuraavan tokenin ennustaminen trigrammimallilla perustuu tokenien paikalliseen kontekstiin ja niiden todennäköisyyksiin mallissa. Eclipse-IDE:lle kehitetty plugin osoittaa, että n-grammimallit voivat täydentää nykyisiä koodin automaattisia ehdotusjärjestelmiä tarjoamalla entistä tarkempia ja kontekstisidonnaisempia vaihtoehtoja. Malli hyödyntää edellisiä kahta tokenia ennustaakseen seuraavaa, ja ehdotukset perustuvat todennäköisyysjärjestykseen, jolloin käyttäjä saa käyttöönsä parhaat mahdolliset jatkotoimet.
On tärkeää ymmärtää, että ohjelmistokoodin luonnollisuus ei perustu pelkästään kielen yksinkertaisuuteen tai sen rakenteeseen, vaan syvempään säännönmukaisuuteen, joka liittyy projektien sisäisiin ja sovellusalueiden spesifisiin käytäntöihin. Tilastollisten kielimallien kyky tunnistaa ja mallintaa nämä paikalliset säännönmukaisuudet mahdollistaa tehokkaamman ja älykkäämmän koodin tuen sekä kehitysympäristöissä että koodin analyysissä. Tämän vuoksi on merkittävää huomioida, että ohjelmistokehityksen työkalut voivat parantua huomattavasti hyödyntämällä paitsi kielen yleisiä piirteitä myös projektien ja sovellusalueiden ainutlaatuisia piirteitä.

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский