Säker utveckling

Itha AB · Gäller Privera 0.9.0-beta22 · Senast uppdaterad: 2026-10-23

Beskriver hur Privera utvecklas, testas, byggs och släpps, och vad som ännu saknas. Det som står under "Finns" är infört. Det som står under "Saknas" eller "Planerat" är inte infört. Datumen i planen är mål, inte avtalade åtaganden.

1. Produkten i korthet

Privera är ett Windows-program som maskerar och avidentifierar dokument. Det består av tre delar:

  • ett programfönster byggt med Electron,
  • en Python-motor som paketeras med PyInstaller och körs som en separat process, med Tesseract 5.4.1 för OCR och språkmodellen KB/bert-base-swedish-cased-ner,
  • en licens- och uppdateringsserver på Cloudflare Workers med D1-databas och R2-lagring.

Dokumenten behandlas bara på användarens dator. Programfönstret och motorn talar med varandra över lokala rör (stdio), inte över en nätverksport. Programmet kontaktar licens.privera.se för licens och uppdateringar och, första gången språkmodellen behövs, Hugging Face.

2. Översikt

OmrådeLäge
Versionshantering i Git, automatiska tester när koden ändrasFinns
Releasekontroller som stoppar bygget (paketkontroll, spärr mot kända GPL-bibliotek och AGPL, OCR-version, och från 0.9.0-beta22 kontroll av det byggda paketet)Finns, avsnitt 4
Kodsignering av installer och alla programfiler (Azure Trusted Signing)Finns
Härdning av programfönstret (Electron)Finns, med kvarvarande brister (avsnitt 7). Electrons spärrar i programfilen är satta från 0.9.0-beta22.
Regressionstest för varje bekräftat exportfel, samlad körning före varje versionFinns
Mätning av detektionens träffsäkerhet mot en låst baslinjeFinns, körs lokalt
Versionslåsta beroendenFinns, med luckor (avsnitt 6)
Skriftlig hotmodellSaknas
Oberoende kodgranskningSaknas, avsnitt 5
Automatisk bevakning av sårbarheter i beroendenDelvis. Larm från GitHub (Dependabot) för npm-beroendena sedan 2026-10-23, inte för Python-paketen och inte i CI (avsnitt 6).
SBOM per releaseFinns från 0.9.0-beta22: tas fram ur det byggda paketet i bygget. Har kända luckor (avsnitt 6).
Penetrationstest, internt eller externtEj genomfört. Offerter tas in under hösten 2026, avsnitt 9.
CI som spärrar release, och grenskyddSaknas
Fullständig signaturkontroll i den automatiska uppdateringenFinns från 0.9.0-beta22, avsnitt 8

3. Utveckling

Finns

  • All kod versionshanteras i Git. Större ändringar görs på egna grenar och slås ihop.
  • Säkerhetskritiska regler är skrivna som kod och tester, inte bara som rutin. Exempel: programmets gränssnitt får inte välja var exportloggen skrivs, huvudprocessen kontrollerar licensen innan motorn får arbeta oberoende av vad gränssnittet visar, och sökvägar från gränssnittet valideras.
  • Exportens och detektionens regler är nedskrivna i interna dokument.

Saknas

  • En skriftlig hotmodell för hela produkten. Hot har analyserats per område i interna granskningar men inte samlats.
  • Ett utvecklingsteam med flera granskare. Nästan alla ändringar görs av en och samma utvecklare.

4. Tester och kontroller

Finns

  • CI vid push och pull request. CI körs när ändringar skickas till källkodsförrådet, utom till arbetsgrenen, vars ändringar kontrolleras när de når huvudgrenen. En körning gäller den senaste ändringen i varje push. För programfönstret, licensservern och webben körs tester, typkontroll och bygge. Motorns del körs när motorn eller en fil som dess tester läser ändras, och kan startas för hand. Då installeras beroendena från låsfil, OCR-motorn och språkdata hämtas låsta, motorn paketeras med PyInstaller, hela testsviten körs mot källkoden, och en uppsättning obligatoriska regressionstester körs mot den paketerade motorn. Därefter kontrolleras paketet. CI har bara läsrätt till källkodsförrådet.
  • Regressionstester för exportfel. Varje bekräftat fel där en uppgift överlevde exporten har ett eget regressionstest. Testerna körs i CI mot källkoden. Mot det paketerade programmet körs de lokalt på byggdatorn.
  • Samlad körning av exportfelen före varje publicering. Ett test som saknas, hoppas över eller kraschar räknas som omätt och ger felkod, så att ett uteblivet mätvärde aldrig ser ut som godkänt.
  • Mätning av träffsäkerhet. Detektionens precision och träffsäkerhet per kategori mäts mot en låst baslinje, och ändringar som försämrar den fälls. Att flytta baslinjen kräver en skriftlig motivering. Mätningen körs lokalt före release, eftersom utvärderingsmaterialet inte lämnar Itha AB:s dator.
  • Paketkontroll före bygge. Bygget stoppas om den paketerade motorn eller OCR-motorn saknas, kända GPL-bibliotek (jbig, lzo2) finns bland OCR-motorns filer, OCR-motorn inte är exakt Tesseract 5.4.1 med Leptonica 1.83.1, den paketerade motorn inte matchar källkodens SHA-256, språkdata saknas eller ett AGPL-beroende finns, eller avvecklingsnyckeln saknas, inte är en Ed25519-nyckel eller är samma som licensserverns nyckel (kontrolleras i det signerade kundbygget).
  • Kontroll av det byggda paketet (från 0.9.0-beta22). Efter att programmet har packats, innan installern skapas och igen efter bygget, stoppas bygget om Electrons spärrar i programfilen (fuses) har fel läge, programfilens binära version inte är den som hör till versionen eller inte är högre än den senast utgivna, installationskatalogen har programfiler som inte kommer från Electron, eller en programfil har en ändelse som döljer den, app.asar inte innehåller den kod som byggdes, eller de uppackade filerna bredvid den inte stämmer med den, motorn innehåller paket som inte står i dess låsfil för körning, eller motorn i paketet inte är den som byggdes. Ett signerat kundbygge stoppas också om källkoden eller motorn har oincheckade ändringar, om en programfil saknar signatur, om något av NSIS-tilläggen i installern eller avinstalleraren inte är giltigt signerat, om installern inte klarar programmets egen signaturkontroll eller om SBOM:en inte kan tas fram.
  • Licensserverns driftsättning stoppas om driftdatabasen saknar migreringar.
  • Versionskonsekvens. Ett test i CI fallerar om installerns namn i licensservern inte stämmer med programmets version.

Saknas

  • CI spärrar inte release. Installern byggs, signeras och publiceras från Itha AB:s byggdator, och det finns inget tekniskt krav att CI är grön innan dess. Grenskydd med obligatorisk CI är inte infört och går inte att slå på med det GitHub-abonnemang som källkodsförrådet har i dag, ett privat förråd utan betalt abonnemang.
  • CI har inte varit grön vid varje utgivning. Alla körningar 2026-10-07, dagen då 0.9.0-beta20 och 0.9.0-beta21 gavs ut, föll. Enligt vår felsökning berodde det på två fel i testerna som bara uppträdde på GitHubs Windows-maskin, inte i programmet, men skrivbordsdelens typkontroll och bygge kördes inte i de körningarna. Av versionerna 0.9.0-beta14 till 0.9.0-beta21 gavs bara 0.9.0-beta19 ut medan CI var grön. CI är grön sedan 2026-10-13.
  • Mätningen av träffsäkerhet och den samlade körningen av exportfelen startas för hand. Resultaten är dokumenterade för en del versioner men inte för alla.

5. Kodgranskning

Finns

  • Säkerhetsrättningar granskas internt i två steg: en granskning per område och därefter en motgranskning där felen återskapas med körda prov. Granskningarna görs av Itha AB självt, med verktyg som bolaget styr, och är inte oberoende.

Saknas

  • Oberoende kodgranskning. Ingen ändring har formellt granskats av en annan person: ingen av de 17 pull requests som har slagits ihop har någon granskning, och övriga ändringar har slagits ihop utan pull request. Ingen extern part har granskat koden.
  • Krav på granskning före sammanslagning. Grenskydd går inte att slå på med förrådets nuvarande GitHub-abonnemang.

Planerat

  • Mål Q1 2027: en extern säkerhetsgranskning av koden för export, uppdatering och licens.
  • Mål Q1 2027: regel om att ändringar i export, uppdatering, licens och signering granskas av en andra person före release.

6. Tredjepartskomponenter

Finns

  • Python-paketen är låsta på exakt version för Windows x64 och Python 3.12.10. Låsfilen får inte uppdateras utan att träffsäkerheten mäts.
  • npm-beroendena är låsta i låsfil med integritetshashar.
  • Tesseract och dess C-bibliotek hämtas från conda-forge, låsta på exakt fil och kontrollerade mot SHA-256. Hämtningen kontrollerar paketens licenstexter och stoppar GPL-licensierade bibliotek.
  • Språkmodellen är låst till en bestämd revision.
  • Spärr mot kända GPL-bibliotek i OCR-motorn och mot AGPL-beroenden i motorn. Electron-delen och Python-delen kontrolleras inte mot GPL.
  • Från 0.9.0-beta22 innehåller motorn bara de paket som står i dess låsfil för körning, och bygget stoppas annars (avsnitt 4). I 0.9.0-beta21 följde utvecklingsverktygen pytest och mypy och biblioteket zstandard med i motorn.
  • SBOM i CycloneDX 1.5, från 0.9.0-beta22 framtagen ur det byggda paketet i bygget. Se SBOM.
  • Larm från GitHub om sårbara beroenden (Dependabot), påslagna sedan 2026-10-23. De gäller npm-beroendena. Larmen ger inga automatiska rättningar och körs inte i CI.

Saknas

  • Automatisk bevakning av motorns Python-paket och OCR-motorns bibliotek, och kontroll av beroenden i CI: varken npm audit, pip-audit eller OSV körs, och Dependabot-larmen gäller bara npm-beroendena. Sårbarheter i övriga beroenden upptäcks i dag bara vid manuell genomgång.
  • Licensservern i SBOM:en.
  • Hashlåsning av Python-paketen och låsning av GitHub Actions på commit i stället för tagg.
  • En uppdateringstakt för Electron. Programmet levereras med Electron 44.6.0, en serie som får säkerhetsrättningar. Enligt Electrons tidsplan upphör stödet för den 2027-03-02. Någon fast rutin för att byta serie i tid finns inte.

Planerat (datumen är förslag, se avsnitt 11)

  • Mål 2026-11-15: npm audit, pip-audit och Dependabot i CI.
  • Mål 2026-11-30: licensservern i SBOM:en.
  • Mål 2026-11-30: hashlåsning av Python-paketen och låsning av Actions på commit.

7. Härdning av programmet

Finns

  • contextIsolation: true, nodeIntegration: false och sandbox: true för programfönstret.
  • Nya fönster nekas. Externa länkar öppnas bara i webbläsaren om adressen finns på en tillåtelselista.
  • Navigering bort från programmet blockeras.
  • Content Security Policy: inga externa skript, connect-src 'self', object-src 'none', frame-src 'none'. Inline-stilar är tillåtna.
  • Licensserverns adress kan inte pekas om med miljövariabler i kundversionen.
  • Licensbevis signeras med Ed25519 och kontrolleras mot en publik nyckel som är inbyggd i programmet. Den privata nyckeln finns inte i källkoden.
  • Avvecklingsbeskedet signeras med en egen Ed25519-nyckel som är skild från licensservern. En angripare som tar över licensservern kan inte låsa upp programmet för alltid. Den privata nyckeln ska flyttas till förvaring offline; per 2026-10-23 är det inte gjort.
  • Sparade granskningar och licensfilen skyddas med Windows DPAPI via Electron safeStorage. Ingen av dem skrivs i klartext om skyddet saknas; för licensfilen gäller det från 0.9.0-beta20.
  • Licensnyckeln som väntar på bekräftelsesidan efter köpet förseglas med AES-256-GCM under en hemlighet i licensservern.
  • Electrons inbyggda spärrar i programfilen (fuses), från 0.9.0-beta22: körning som Node (RunAsNode), NODE_OPTIONS och --inspect är avstängda, och asar-integritet, OnlyLoadAppFromAsar och kryptering av kakor är påslagna. Bygget stoppas om en spärr har fel läge. Se IT-drift avsnitt 4.1.
  • Felsökningsporten (--remote-debugging-port med flera) avslutar kundutgåvan innan något fönster öppnas, utom när organisationen tillåter den med policyn AllowDebugPort, från 0.9.0-beta22.
  • Windows egna program som programmet startar, PowerShell och reg.exe, startas med full sökväg i Windows-katalogen och med en egen miljö, från 0.9.0-beta22. Katalogen tas ur den plats Windows laddade ntdll.dll från, inte ur miljövariabeln SystemRoot.

Brister vi känner till

  • Spärren GrantFileProtocolExtraPrivileges står kvar på, eftersom programfönstret laddas från en fil med file: och inte laddas alls utan den. Att stänga av den kräver att fönstret laddas genom ett eget protokoll.
  • Asar-integriteten skyddar bara app.asar. I en installation per användare kan användaren byta ut DLL-filer, .node-filer bredvid app.asar och motorn. Det som stoppar det är AppLocker eller WDAC, se IT-drift avsnitt 4.
  • I 0.9.0-beta21 och äldre är spärrarna inte satta. Den signerade programfilen i de versionerna kan användas för att köra annan kod än programmets egen, och en regel i AppLocker eller WDAC som tillåter Itha AB:s signatur släpper in dem. AppLocker behöver därför en nekande regel för de versionerna, se IT-drift avsnitt 4.

8. Bygge, signering och leverans

Finns

  • Installern byggs med tvingande kodsignering, så ett osignerat bygge går inte att få ut som installer.
  • Signering sker via Microsoft Azure Trusted Signing med utgivaren Itha AB.
  • Varje programfil i paketet (.exe, .dll, .pyd, .node) signeras om den saknar signatur. Bygget stoppas om någon programfil saknar giltig signatur eller om en av Itha AB:s signaturer saknar tidsstämpel.
  • Från 0.9.0-beta22 signeras också installerns och avinstallerarens NSIS-tillägg (bland annat System.dll och nsis7z.dll), som packas upp och laddas från %TEMP% under installationen. I 0.9.0-beta21 och äldre var de osignerade, och på en dator med Smart App Control påslaget installerades programmet då tyst utan programfiler: installern gav kod 0 men ingen Privera.exe. Se IT-drift avsnitt 2.1.
  • Installer och uppdateringar lämnas bara ut till licenser som har rätt att köra programmet.
  • Licensservern skickar HSTS och övriga säkerhetshuvuden på varje svar, och skriver en säkerhetslogg utan licensnyckel, e-post och IP-adress i klartext. Loggen sparas inte i dag. Se Kryptering och åtkomstkontroll avsnitt 2 och Säkerhetsloggning avsnitt 11.
  • Programfilen och installern har en binär filversion som stiger med varje version, 0.9.0.22 för 0.9.0-beta22. Bygget stoppas om den inte är högre än den senast utgivna. Det gör att en AppLocker-regel kan neka 0.9.0-beta21 och äldre, se IT-drift avsnitt 4.
  • Installern läggs inte ut för nedladdning utan en SBOM från samma signerade bygge.
  • Den automatiska uppdateringen kontrollerar filens SHA-512 mot uppdateringsmanifestet före installation och tvingar aldrig fram en omstart. Från 0.9.0-beta22 har programmet en egen signaturkontroll: signaturen ska ha status Valid och gälla den hämtade filen, utgivarens namn ska ha alla delarna CN, O, L, S och C med Itha AB:s värden, och filens versionsuppgift ska vara den som manifestet angav; en fil utan läsbar versionsuppgift avvisas. Kontrollen är stängd vid fel, paket för webbinstallation godtas inte, och ett nej loggas (5003). Kan äktheten inte kontrolleras på datorn, till exempel för att PowerShell är spärrat, installeras inga uppdateringar, och Om Privera säger det. Se IT-drift avsnitt 5.

Brister vi känner till

  • Uppdateringsmanifestet är inte signerat. Det skyddas av TLS, av att bara licenser med rätt att köra programmet får hämta det och av att installerns signatur och version kontrolleras innan den installeras.
  • Går den hämtade installerns versionsuppgift inte att läsa avgörs uppdateringen på signaturen.
  • Ett uppdateringsfel som inte gäller äktheten, till exempel ett nätverksfel, syns inte för användaren, bara som uppdatering.fel (5002) i säkerhetsloggen.
  • I 0.9.0-beta21 och äldre jämför signaturkontrollen bara certifikatets namn (CN), och där Windows PowerShell inte kan köras hoppas den över. En dator som uppdaterar från 0.9.0-beta21 prövar 0.9.0-beta22 med den äldre kontrollen.

9. Säkerhetstestning

Finns

  • Riktad testning av exporten: försök att få påhittade personuppgifter att överleva en export. Varje bekräftat fel blir ett regressionstest (avsnitt 4).

Saknas

  • Penetrationstest. Inget penetrationstest av programmet (kommunikationen mellan processer, uppdateringsflödet, filhantering, motorprocessen) eller av licensservern (licens.privera.se, betalkopplingen, databasen) har gjorts, varken internt eller av extern part.

Planerat

  • Offerter på ett externt penetrationstest av skrivbordsappen och licensservern tas in under hösten 2026; målet är ett genomfört test under Q1 2027. När ett test är gjort har kunder som har undertecknat säkerhetsbilagan rätt att ta del av det. Övriga kunder kan begära en sammanfattning.

10. Sårbarheter, incidenter och livscykel

Hur sårbarheter tas emot, bedöms och åtgärdas beskrivs i Sårbarhetshantering. Supportperiod, åtgärdstider och vad som gäller vid avveckling beskrivs i Livscykel och support.

Sedan 2026-09-11 omfattas Itha AB som tillverkare av rapporteringsplikten i EU:s cyberresiliensförordning, förordning (EU) 2024/2847, artikel 14.

11. Planen samlad

Datumen är förslag och inte beslutade. När de är beslutade gäller samma datum i Plan för CRA.

ÅtgärdMål (förslag)Läge
Fullständig signaturkontroll i uppdateringen, del 1: fullt utgivarnamn, avstängda webbinstallerare, synligt besked (avsnitt 8)2026-10-31Klart, i 0.9.0-beta22
Automatisk bevakning av beroenden i CI (npm audit, pip-audit, Dependabot)2026-11-15Delvis. Dependabot-larm för npm-beroendena sedan 2026-10-23. Inte i CI och inte för Python-paketen: Planerat.
SBOM framtagen automatiskt per release och kontrollerad mot bygget2026-11-30Klart, i 0.9.0-beta22. Licensservern i SBOM:en: Planerat.
Release byggs bara från en version med grön CIEj fastställtFörslag, ej beslutat
Electron som får säkerhetsrättningar (Electron 44)2026-11-30Klart
Hashlåsning, låsning av Actions på commit2026-11-30Planerat
Skriftlig hotmodellQ1 2027Planerat
Granskning av en andra person för säkerhetskritiska ändringarQ1 2027Planerat
Externt penetrationstest av skrivbordsappen och licensservernOfferter hösten 2026, genomfört test Q1 2027Planerat
Extern kodgranskningQ1 2027Planerat, budget ej fastställd
Electrons fuses satta i programfilen (avsnitt 7)Ej fastställtKlart, i 0.9.0-beta22. GrantFileProtocolExtraPrivileges står kvar på.
Egen signaturkontroll i uppdateringen, del 2: avvisar uppdateringen när kontrollen inte går att genomföraQ1 2027Klart, i 0.9.0-beta22
Teknisk dokumentation och EU-försäkran enligt CRASenast 2027-12-11Planerat

Itha AB är inte certifierat enligt ISO 27001 eller SOC 2.

Alla dokument finns också samlade i en PDF för e-post.