Tietoturvayhtiö OmniSecuren tutkijat eivät alun perin etsineet aukkoa. He harkitsivat Basetenia oman tekoälymallinsa ajoalustaksi ja päästivät yhtiön julkisiin verkkopalveluihin oman tuotteensa, Strix-nimisen autonomisen hakkerointiagentin. Noin 25 minuuttia myöhemmin agentilla oli voimassa oleva GitHub-tunnus, jolla pääsi ylläpitäjänä Basetenin sisäisiin koodivarastoihin.
Baseten on yhdysvaltalainen yritys, joka myy tekoälymallien ajopalvelua: asiakas tuo mallin, Baseten hoitaa palvelimet, skaalauksen ja rajapinnat. Juuri sellaiseen palveluun kertyy asiakkaiden koodia, konfiguraatioita ja julkaisuputkia.
Agentti kartoitti ensin yhtiön verkkotunnuksia ja löysi Harbor-konttirekisterin osoitteesta gcp-us-east4-zlw.registry.baseten.co. Yksi rekisterin projekteista oli julkinen. Sieltä sai ladattua baseten/baseten-app -nimisen imagen ilman minkäänlaista tunnistautumista.
Imagen sisältä löytyi ensin joukko vanhentuneita AWS-avaimia. Sitten rakennushistorian metatiedoista, kentästä history[].created_by, paljastui basetenbot-niminen GitHub:n henkilökohtainen käyttöoikeustunnus. Se oli luotu 3. maaliskuuta 2023. Se toimi yhä.
“Tämä on järjetön määrä pääsyoikeuksia jätettäväksi julkisesti ladattavaan imageen.”
Miksi salaisuus jää imageen, vaikka se poistettaisiin
Docker-image on valmiiksi paketoitu ohjelma ympäristöineen: sovellus, kirjastot ja asetukset samassa nipussa, jonka voi käynnistää millä tahansa palvelimella. Image rakentuu kerroksista. Jokainen rakennusvaiheen komento lisää uuden kerroksen edellisen päälle, eikä vanhoja kerroksia poisteta, koska image on juuri niiden summa.
Basetenin tapauksessa GitHub-tunnus oli annettu rakennusvaiheessa niin sanottuna build-argumenttina. Docker kirjaa suoritetut komennot historiaansa sellaisenaan, ja jos tunnus on komentorivillä, se päätyy myös historiaan. Vaikka väliaikaiset tiedostot siivottaisiin seuraavassa kerroksessa, merkintä jää. Poistaminen ei pyyhi historiaa, se vain lisää uuden kerroksen.
Dockerin oma dokumentaatio varoittaa tästä nimenomaisesta virheestä. Silti se on yksi yleisimmistä tavoista vuotaa tunnus, koska rakennusvaiheessa salaisuus tuntuu hetkelliseltä. Image, johon se jää, elää vuosia.
Tunnus syntyi 2023, mitätöitiin vasta tutkijoiden ilmoituksesta 2026
3.3.2023
Tunnus syntyy
GitHub-tunnus basetenbot luodaan ja päätyy build-argumenttina Docker-imagen rakennushistoriaan.
13.7.2026 klo 23.10
Ilmoitus Basetenille
Tutkijat raportoivat voimassa olevasta tunnuksesta ja julkisesta Harbor-rekisteristä.
14.7.2026 aamu
Rekisteri suljetaan
Baseten muuttaa julkisen Harbor-projektin yksityiseksi.
14.7.2026 klo 16.34
Tunnus mitätöidään
Basetenin tietoturvasta vastaava Anton vahvistaa löydöksen kriittiseksi ja tunnus vaihdetaan. Puoli tuntia myöhemmin tutkijat vahvistavat poistaneensa lataamansa imaget.
17.7.2026
Loput havainnot korjattu
Baseten ilmoittaa käsitelleensä jäljelle jääneet löydökset.
Tunnuksella oli laaja repo-oikeus. Se tarkoitti ylläpito- ja kirjoitusoikeutta Basetenin päätuotteen koodivarastoon, käyttöönottoa ohjaavaan GitOps-repositorioon ja yhtiön Homebrew-jakelukanavaan, jolla kehittäjät asentavat Basetenin komentorivityökalun. Lisäksi tunnus ylsi lukemaan ja kirjoittamaan muihin yksityisiin repositorioihin, myös asiakaskohtaisiin.
Käytännössä hyökkääjä olisi voinut muokata tuotantokoodia, työntää muutoksen käyttöönottoputkeen tai vaihtaa asennuspaketin sisällön. Silloin myrkytetty versio olisi mennyt asiakkaille normaalia päivitystä pitkin, ilman että kukaan tekee mitään epäilyttävää. Tätä kutsutaan toimitusketjuriskiksi.
Tässä kohtaa tapaus koskee myös niitä, jotka eivät koskaan avaa Basetenin hallintapaneelia. Kun yritys ostaa tekoälymallien ajopalvelun ulkopuolelta, se ostaa samalla palveluntarjoajan rakennusputken ja sen vanhat virheet. Suomalaiselle ohjelmistotalolle, joka pyörittää asiakasdataa käsittelevää mallia tällaisen alustan päällä, toimittajan kolme vuotta vanha build-argumentti on osa omaa hyökkäyspinta-alaa.
Mitään näyttöä väärinkäytöstä ei ole esitetty. Raportti ei kuitenkaan kerro, latasiko imagen joku muu niiden kolmen vuoden aikana, jona se oli julkisesti saatavilla. Jälkikäteen sitä on vaikea selvittää.
Kuka on tämän vahvistanut
Tapauksesta on toistaiseksi yksi julkinen lähde: löytäjän oma blogikirjoitus. Basetenin verkkosivuilta ei löydy tiedotetta eikä jälkiselvitystä, eikä yhtiö ole kommentoinut tapausta julkisuudessa. Myös Anton, joka raportissa kuittaa löydöksen kriittiseksi, esiintyy vain Strixin kertomana. Riippumatonta vahvistusta aikajanalle ei ole.
Julkaisijaa kannattaa katsoa tarkkaan. OmniSecure myy Strixiä tuotteena, ja raportti toimii samalla näyttönä siitä, mihin yhtiön agentti pystyy. Se ei tee havainnoista vääriä. Mutta 25 minuutin luku, korjausten nopeus ja arvio siitä, mikä jäi korjaamatta, ovat kaikki löytäjän omaa kertomaa.
Yksi aukko jää kokonaan lähteen harkintaan: raportissa ei kerrota, ilmoittiko Baseten tapauksesta asiakkailleen, myöskään niille, joiden omiin repositorioihin tunnus ylsi. Tutkijat kuvaavat yhtiön tietoturvatiimin toiminnan ammattimaiseksi ja nopeaksi, ja kiitokseksi he saivat lahjapaketin. Asiakasviestinnästä kertomus vaikenee.
Näin vanhat tunnukset löytyvät omasta putkesta
Aloita rekisteristä: tarkista, onko jokin konttiprojekti auki ilman tunnistautumista, ja käy läpi myös vanhat tagit, ei vain uusinta versiota. Imagen rakennushistorian saa auki komennolla docker history --no-trunc, josta build-argumentit näkyvät sellaisenaan. Jokainen löytynyt tunnus mitätöidään GitHub:n tai pilvipalvelun hallinnasta, ei vain poisteta imagesta.
Jatkossa salaisuudet annetaan BuildKitin secret mount -mekanismilla, joka ei jätä jälkeä kerroksiin. Oikeudet rajataan niihin repositorioihin, joita rakennus oikeasti tarvitsee, ja tunnukselle asetetaan vanhenemispäivä. Strixin oma ohje on suora: ”Get secrets out of build arguments. Use secret mounts, and make sure the commands consuming those secrets don't write them back into the image.”
Sanasto
Konttirekisteri (container registry)
Verkkovarasto, jonne ohjelmistopaketit eli imaget tallennetaan ja josta palvelimet lataavat ne käyttöön. Jos rekisteri on julkinen, kuka tahansa voi ladata sen sisällön ilman tunnuksia.
Build-argumentti
Tieto, joka annetaan ohjelmapaketin rakennusvaiheessa komentorivillä, esimerkiksi salasana tai käyttöoikeustunnus. Docker tallentaa suoritetut komennot historiaansa, joten argumentti jää talteen pysyvästi.
Henkilökohtainen käyttöoikeustunnus (personal access token)
Salasanan korvaava merkkijono, jolla ohjelma kirjautuu palveluun käyttäjän puolesta. Se toimii kunnes se erikseen mitätöidään tai vanhenee.
Yksi yksityiskohta erottaa tämän tavanomaisesta vuototapauksesta. Etsijä ei ollut ihminen, joka kaivoi kerroksia illan verran, vaan ohjelma, joka teki kartoituksen, latauksen, löydön ja oikeuksien testaamisen puolessa tunnissa. Vanhojen virheiden säilyvyysaika lyhenee sitä mukaa kuin tällainen haku halpenee.
Vuoden 2023 build-argumentti ei siis enää odota, että joku sattuu katsomaan oikeaan paikkaan oikealla hetkellä. Ensi vuonna sitä etsii moni agentti yhtä aikaa, eivätkä kaikki niistä kirjoita löydöksestään blogia.
Viikoittainen uutiskirje
Tule firmasi fiksuimmaksi AI-osaajaksi
Yksi uutiskirje kerrallaan. Kokoamme viikon tärkeimmät tekoälyuutiset suomeksi ja kerromme, mitä ne tarkoittavat sinun työsi kannalta. Luet sen kahvitauolla.