Hvad vi gør.

En struktureret intern gennemgang mod en etableret tjekliste, hvert kvartal, plus umiddelbart efter enhver ikke-triviel afhængighedsopdatering eller ændring af auth-flader. Tjeklisten følger rammen OWASP ASVS Level 2 + OWASP API Security Top 10 — vi hævder ikke certificering, men vi bruger frameworkets spørgsmål ordret, hvor det er nyttigt. Hver gennemgang producerer en dateret rapport, der commit'es til repositoriet, dokumenteret med filstier og testfiler; fund afhjælpes enten i en refereret commit eller accepteres som restrisiko med begrundelse.

  • Master-tjekliste — otte områder: autentificering og session, offentlig viewer + JSON-LD-endpoint, dashboard-skrivestier, lager, egne domæner, afhængigheder, hemmeligheder, logning og monitorering.
  • Kvartalsvis gennemgang — hver række dokumenteret i filen med stier og testfiler; pass / delvis / fejl pr. række. Fund afhjælpes enten i en refereret commit eller accepteres eksplicit som restrisiko med begrundelse.
  • Afhængigheds-hygiejnepip-audit ved hver gennemgang. Pinnet requirements.txt uden versionsintervaller; opdateringer er bevidste og testede.

De bærende kontroller.

Konkrete, verificerbare påstande — hver er en egenskab ved kode eller konfiguration, en kontrollant kan tjekke.

  • Krypteret i transit. TLS på alle offentlige flader (qrregistry.io, qrregistry.eu, viewere på egne domæner) via Caddy med on-demand certifikatudstedelse. Sessions-cookien er HttpOnly + Secure + SameSite=Lax.
  • Krypteret i hvile. PostgreSQL + MinIO på EU-hardware med diskkryptering.
  • Ingen adgangskoder. Kun magisk link. Råtokenet er ~256 bits CSPRNG-entropi, udløber på 15 minutter og forbruges ved første brug; databasen gemmer kun en SHA-256-hash, så en databaselæsning alene kan ikke logge nogen ind.
  • Differentieret målgruppe-auth. Revisor- / genvinder- / reparatør- / notified-body-legitimationer er kortlivede JWT'er, som kan tilbagekaldes fra én admin-flade; en tilbagekaldelse træder i kraft ved næste request, ikke ved JWT-udløb.
  • Skrivestier med ejerskabstjek. Hver skrivning på pas, attesteringer, domæner og aktiver er serverside afgrænset af row.user_id == user.id. Andre brugeres rækker returnerer 404 i stedet for 403 — vi lækker ikke eksistensoplysninger.
  • Restricted-tier-filter. En enkelt funktion (strip_to_visible) styrer hver passflade — HTML-viewer, JSON-LD-endpoint, audit-feed, PDF. Ingen felt kan lække via én gren og ikke en anden.
  • Append-only audit-kæde. Hver gemning skriver en passport_revisions-række med hash_before / hash_after / struktureret diff. DELETE /dashboard/passports/{id} returnerer ubetinget 403 — artikel 10(4) livstidsbevaring.
  • Allowlist for egne domæner. Caddys on-demand-TLS-spørge-endpoint er bundet til loopback og konsulterer tabellen over verificerede domæner; kun verificerede og provisionerede værtsnavne udsteder et certifikat. Single-claim-invariant — et værtsnavn kan kun tilhøre én ejer.
  • Hemmeligheds-disciplin. Ingen hemmeligheder i kildekoden. .env er den eneste fortegnelse; pr.-tjeneste-miljøvariabler (database, Stripe, Resend, MinIO) er uafhængige.
  • Privatlivsbevarende analytics. Scan-events registrerer en ISO-landekode (header-afledt, aldrig rå IP) og en grov enhedsklasse — aldrig en tracking-cookie, aldrig en legitimationsidentitet. Dokumenteret og synligt under /privacy.

Hvad vi udtrykkeligt ikke gør.

Vi betaler ikke for en tredjeparts penetrationstest, før en kundes indkøbsporten gør det berettigede omkostninger. ESPR artikel 11(h) definerer ikke en certificeringssti og kræver ikke tredjeparts-test; en bestilling til 15-30k € køber troværdighed, men ingen regulatorisk <code>✅</code>, og den daterede interne gennemgang dokumenterer samme bevismateriale med færre omkostninger, mens virksomheden er lille.

Vi hævder ikke SOC 2- eller ISO 27001-certificering. Vores infrastrukturudbyders position står bag footer-linjen <em>„ISO 27001 aligned“</em>; certificeringen tilhører dem, ikke Contenza K/S.

Vi lader ikke som om en ren gennemgang er fraværet af fund. Gennemgangen 2026-04-30 markerer fem 🟡 delvis-rækker — fire er afhængigheds-CVE'er med tilgængelige fix-versioner sporet som en opfølgningsopdatering, og en er en udskudt applikationslags-rate-limit. Ærlig er mere nyttigt end aspirativt.

Hvad I kan læse.

  • Master-tjeklisten ligger på docs/security-review-checklist.md i kilderepositoriet — hver række er et spørgsmål, den næste gennemgang skal besvare med dokumentation.
  • Hver dateret gennemgang ligger på docs/security-review-{YYYY-MM-DD}.md — filstier, testfiler og fund, i filen. Git-historikken viser, hvad der ændrede sig mellem gennemgange.
  • Hver offentlig påstand på denne side svarer til en række i den seneste gennemgang.

Rapportér en sårbarhed.

Skriv til teamet med detaljer. Vi behandler sikkerhedsmeldinger som prioritet og svarer inden for én forretningsdag. Der er endnu intet formelt bug-bounty-program — i vores skala er anerkendelsen et hjerteligt tak og en plads i changeloggen.

Spørgsmål til denne politik? Brug kontaktformularen — eller skriv til teamet via oplysningerne på kontaktsiden.