Security Testing Policy
Security Testing Policy
Project / Organization: BilkoALAI Holding AS — BalkanDrop AccountingPayment SaaSApp
Policy Number: POL-SEC-TEST-001
Version: 1.0
Date: 2026-02-23
Author: CTO / Security EngineerArchitect
Status: Draft
Reviewers: CISO, Engineering Lead, DPOCTO
Next Review: 2027-02-23
Classification: Confidential
Document History
| Version |
Date |
Author |
Changes |
| 0.1 |
2026-02-23 |
CTOSecurity Architect |
Initial draft — Drop security testing policy for Bilkomethodology |
1. Purpose & Scope
Purpose: This policy defines the security testing requirements,methodology, tools, schedule,frequency, and acceptanceremediation criteriarequirements for all systems operated by ALAI Holding AS for the BilkoDrop platform.payment Bilko handles regulated financial data (tax IDs, IBAN, accounting records) across three jurisdictions.app. Security testing is mandatory,mandatory not— optional.no system goes to production without completing applicable security tests.
Regulatory basis:
- IKT-forskriften (FOR-2003-05-21-630) §§ 5-6 — ICT security verification
- DORA (EU) 2022/2554 Art. 24-25 — Digital operational resilience testing
- Finanstilsynet licensing requirements — penetration test before production launch
- GDPR Art. 32(1)(d) — regular testing of technical measures
Scope:
- All
Bilkoproduction applicationsAPIs —and Express APIendpoints (apps/api/getdrop.no, api.getdrop.no),
Next.js- All
frontendAWS infrastructure (apps/web/),App databaseRunner, layerS3, (PrismaKMS, +Secrets PostgreSQL),Manager)
- All CI/CD pipelines and
externalbuild systems
- All third-party integrations (
SEF,BankID, HR-FISK).Sumsub, Open Banking partners)
- Developer workstations handling Confidential or Restricted data
Policy Owner: CISO ([email protected])
Operational Owner: Security team + Engineering Lead
2. Security Testing PyramidMethodology
Approach: Shift-left security — testing integrated throughout development, not bolted on at the end.
Testing layers:
graphDevelopment TDPhase
subgraph+-- AUTOMATED["AutomatedUnit security tests — Vitest (runscurrent: 20+ security-specific tests)
+-- SCA — npm audit (every commit, automated)
+-- Secret scanning — detect leaked credentials (every commit)
Build / CI pipeline)"]
SAST["SAST\nESLint Security Rules\nTypeScript strict mode\nnpm audit\nSnyk SCA"]
UNIT["Security Unit Tests\nVitest\nRBAC matrix tests\nOrg isolation tests\nEncryption tests\nVAT accuracy tests"]
INT["Integration Tests\nVitestPhase
+-- Supertest\nAuthSAST flow— tests\nJWTstatic validation\nRatecode limiting tests"]
end
subgraph PERIODIC["Periodicanalysis (scheduled)"]every DAST["DAST\nOWASPPR ZAP\nMonthly— planned Phase 2)
+-- pre-release"]SCA E2E["Security— E2E\nPlaywright\nCross-tenantdependency boundaryvulnerability tests\nPrivilege escalation tests"]
end
subgraph MANUAL["Manualcheck (scheduled)"]every PENTEST["PR)
+-- Secret scanning — full scan (every PR)
Deployment Phase
+-- DAST — OWASP ZAP against staging (planned — Phase 3)
+-- API security scan — endpoint fuzzing (planned — Phase 3)
Operational Phase
+-- Vulnerability assessment — external attack surface (quarterly)
+-- Penetration Test\nExternaltest vendor\nAnnual"]— REVIEW["Securitymanual Codeexpert Review\nPre-mergetesting (security-sensitivebefore PRs)\nArchitecturePhase 3 launch)
+-- Post-incident review quarterly"]— endregression UNITtests -->after INTany -->security DAST --> PENTESTincident
3. AutomatedCurrent Security TestingTest (CI/CD)Coverage
Every push to main and every pull request triggers:
3.1 StaticVitest AnalysisUnit (SAST)Security Tests
Status: Implemented — 20+ security-specific tests
Source: src/drop-app/src/__tests__/
ToolTest Category |
What It ChecksTest |
Failure ThresholdSource |
ESLint + eslint-plugin-securityAuthentication |
CommonJWT JSsecret securityrequired patternsin (eval, RegExp DoS, object injection)production |
Any errorauth.test.ts level finding blocks merge |
TypeScript strict modeAuthentication |
TypeCookie: safetyhttpOnly=true, preventssecure=true, implicit any that could bypass validationsameSite=strict |
Build failure blocks mergeauth.test.ts |
npm audit --audit-level=highAuthentication |
KnownJWT vulnerabilitiescontains in dependenciessetIssuedAt() |
HIGH or CRITICAL CVEs block mergeauth.test.ts |
Snyk (optional Phase 2)Authentication |
DeeperSession revocation: revoked token rejected |
auth.test.ts |
| Authentication |
Logout revokes all user sessions |
auth.test.ts |
| Password |
bcrypt used — not SHA-256 |
utils-server.test.ts |
| Password |
bcrypt cost factor >= 12 |
utils-server.test.ts |
| Password |
SHA-256 hash rejected as invalid (fix C4) |
utils-server.test.ts |
| Input Validation |
IBAN checksum validation |
validation.test.ts |
| Input Validation |
Currency whitelist enforced |
validation.test.ts |
| Input Validation |
Language whitelist enforced |
validation.test.ts |
| Input Validation |
Amount: NaN/Infinity rejected |
validation.test.ts |
| Input Validation |
HTML tags stripped by sanitizeText() |
validation.test.ts |
| SQL Injection |
Parameterized queries for all user inputs |
db.test.ts |
| Rate Limiting |
Auth rate limit: 10/60s enforced |
middleware.test.ts |
| Rate Limiting |
Transaction rate limit: 10/60s enforced |
middleware.test.ts |
| CSRF |
Origin header validated |
middleware.test.ts |
| CSRF |
Invalid origin rejected |
middleware.test.ts |
| IDOR |
Transaction query scoped to user_id |
transactions.test.ts |
| IDOR |
Recipient query scoped to user_id |
recipients.test.ts |
| Feature Flags |
Cards endpoint returns 404 when flag disabled |
feature-flags.test.ts |
3.2 Running the Security Test Suite
# Run all security tests
cd src/drop-app && npx vitest run --reporter verbose
# Run specific security test file
npx vitest run src/__tests__/auth.test.ts
# Run with coverage
npx vitest run --coverage
Blocking criteria: All security tests MUST pass before merge to main branch.
4. Testing Types, Tools & Schedule
4.1 SCA including— licenseSoftware complianceComposition Analysis
Status: Implemented (npm audit)
3.2
Current Securitydependency Unitsecurity Testsstatus (Vitest)2026-02-13
Location: apps/api/src/__tests__/security/audit):
Required
test
suites:
RBACPackage |
MatrixVersion |
Tests
Risk |
| Status |
//jose |
Every^6.1.3 |
permissionLow |
combinationNo mustknown beCVEs |
explicitly
tested
describe('RBACbcryptjs |
—^3.0.3 |
InvoiceLow |
access',No ()known =>CVEs |
{
const
rolesbetter-sqlite3 |
=^12.6.2 |
['owner',Low |
'admin',No 'accountant',known 'viewer']CVEs |
test.each([
['owner',
'create',next |
true],16.1.6 |
['admin',Low |
'create',Recent true],version |
['accountant',
'create',
true],react |
['viewer',19.2.3 |
'create',Low |
false],Latest ['owner',major |
'delete',
true],
['admin',radix-ui |
'delete',^1.4.3 |
true],Low |
['accountant',UI 'delete', false],
['viewer', 'delete', false],
])('role=%s action=%s expected=%s', async (role, action, expected) => {
const token = signTestJWT({ role, org: 'org-1' })
const res = await request(app).post(`/api/invoices`).set('Authorization', `Bearer ${token}`)
// check response matches expected
})
})
Organization Isolation Tests (Multi-Tenant Critical)
describe('Org isolationonly — no cross-tenant data leak', () => {
let org1Token: string
let org2InvoiceId: string
beforeAll(async () => {
// Setup two orgs with data
org1Token = signTestJWT({ org: 'org-1', role: 'owner' })
const org2Token = signTestJWT({ org: 'org-2', role: 'owner' })
// Create invoice in org-2
const res = await request(app)
.post('/api/invoices')
.set('Authorization', `Bearer ${org2Token}`)
.send(validInvoicePayload)
org2InvoiceId = res.body.id
})
test('org-1 cannot read org-2 invoice', async () => {
const res = await request(app)
.get(`/api/invoices/${org2InvoiceId}`)
.set('Authorization', `Bearer ${org1Token}`)
expect(res.status).toBe(404) // NOT 403 — don't reveal existence
})
test('org-1 list does not include org-2 data', async () => {
const res = await request(app).get('/api/invoices').set('Authorization', `Bearer ${org1Token}`)
const ids = res.body.data.map((i: any) => i.id)
expect(ids).not.toContain(org2InvoiceId)
})
})
Field Encryption Tests
describe('Field encryption — L4 Restricted', () => {
test('PIB stored encrypted in DB', async () => {
const testPIB = '123456789' // fake PIB
// Create contact with PIB
await request(app)
.post('/api/contacts')
.set('Authorization', `Bearer ${ownerToken}`)
.send({ name: 'Test', taxId: testPIB, type: 'RS' })
// Read raw DB value — should not be plaintext
const raw = await prisma.$queryRaw`
SELECT "taxId" FROM "Contact" WHERE name = 'Test'
`
expect(raw[0].taxId).not.toBe(testPIB)
expect(raw[0].taxId).toMatch(/^[A-Za-z0-9+/]+=*:[A-Za-z0-9+/]+=*:[A-Za-z0-9+/]+=*$/)
// Should be base64:base64:base64 format (iv:authTag:ciphertext)
})
test('decrypted PIB matches original on read', async () => {
const res = await request(app).get('/api/contacts').set('Authorization', `Bearer ${ownerToken}`)
const contact = res.body.data.find((c: any) => c.name === 'Test')
expect(contact.taxId).toBe('123456789')
})
})
VAT Accuracy Tests (Financial Compliance)
describe('VAT calculation accuracy', () => {
test('RS: VAT 20% on standard goods (NUMERIC precision)', () => {
const net = new Decimal('100.00')
const vatAmount = net.mul('0.20')
const gross = net.plus(vatAmount)
expect(vatAmount.toString()).toBe('20.00')
expect(gross.toString()).toBe('120.00')
})
test('HR: VAT 25% (EUR since Jan 2024)', () => {
const net = new Decimal('100.00')
const gross = net.mul('1.25')
expect(gross.toString()).toBe('125.00')
})
test('BA: VAT 17% (UIO standard)', () => {
const net = new Decimal('100.00')
const gross = net.mul('1.17')
expect(gross.toString()).toBe('117.00')
})
test('No float drift on invoice totals', () => {
// Known JS float bug: 0.1 + 0.2 !== 0.3
const line1 = new Decimal('0.10')
const line2 = new Decimal('0.20')
expect(line1.plus(line2).toString()).toBe('0.30')
// Contrast: expect(0.1 + 0.2).toBe(0.3) would FAIL
})
})
Authentication Tests
describe('Auth — JWT security', () => {
test('expired access token returns 401', async () => {
const expiredToken = signTestJWT({ exp: Math.floor(Date.now() / 1000) - 1 })
const res = await request(app)
.get('/api/invoices')
.set('Authorization', `Bearer ${expiredToken}`)
expect(res.status).toBe(401)
})
test('tampered token returns 401', async () => {
const validToken = signTestJWT({ role: 'viewer' })
// Tamper: change role claim in payload
const parts = validToken.split('.')
const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString())
payload.role = 'owner' // attempt privilege escalation
parts[1] = Buffer.from(JSON.stringify(payload)).toString('base64url')
const tamperedToken = parts.join('.')
const res = await request(app)
.delete('/api/invoices/any-id')
.set('Authorization', `Bearer ${tamperedToken}`)
expect(res.status).toBe(401)
})
test('rate limiting: 6th auth attempt in 15min returns 429', async () => {
for (let i = 0; i < 5; i++) {
await request(app).post('/api/auth/login').send({ email: 'x', password: 'wrong' })
}
const res = await request(app).post('/api/auth/login').send({ email: 'x', password: 'wrong' })
expect(res.status).toBe(429)
})
})
3.3 Dependency Scanning
# .github/workflows/security.yml
- name: Audit dependencies
run: npm audit --audit-level=high
# HIGH or CRITICALknown CVEs
|
fail
the
build
-Source: name: Check for secrets in code
uses: trufflesecurity/trufflehog@main
# Scans for committed credentials, API keys
~/ALAI/products/Drop/security/drop-security-rapport.md
Dependency update policy:
CRITICALSecurity CVE:patches patch(Critical/High): Merge within 24SLA hours(see §5)
HIGHMinor CVE:security patchupdates: Merge within 714 days
MEDIUMMajor CVE:updates: patchPlanned migration within 3090 days
Approved licenses: MIT, Apache 2.0, BSD (2-clause, 3-clause), ISC
4.2 SAST — Static Application Security Testing
Status: Planned (Phase 2)
SAST rules in scope (when implemented):
LOWSQL CVE:injection patchdetection at(parameterized nextqueries sprintvalidation)
boundary- JWT algorithm confusion (
alg: none detection)
- Hardcoded secrets / credentials
- Insecure cryptography (MD5, SHA-1, DES, RC4)
- Path traversal / LFI
- IDOR patterns (database queries without user_id scoping)
- Missing authentication middleware
4.3 DAST — Dynamic Application Security Testing (DAST)
OWASP ZAP
Schedule:Status: MonthlyPlanned (Phase 3 — before production launch)
OutDAST ofscan scope:
SEFAll portal,24 FINAAPI portalendpoints (externalauthenticated systems)+ unauthenticated)
RailwayAuthentication infrastructureflows (login, registration, logout, session handling)
CloudflareRate WAFlimiting (managedverify by10/60s Cloudflare)limits enforced)
- CSRF protection (Origin header validation)
- Input validation (IBAN, currency, language, amount)
- Security headers presence (HSTS, CSP, X-Frame-Options, etc.)
- SSL/TLS configuration (TLS 1.3, no TLS 1.0/1.1)
- JWT handling (expiry, algorithm, revocation)
- Feature flag enforcement (cards endpoints return 404 when disabled)
4.4 Penetration Testing
ZAPStatus: Configuration:Required before Phase 3 production launch (Finanstilsynet licensing requirement)
| Property |
Value |
| Frequency |
Before production launch + annual thereafter |
| Scope |
Full application + API + AWS infrastructure |
| Methodology |
OWASP Testing Guide v4.2 + PTES |
| Provider |
External security firm (not yet selected) |
| Blocking |
Critical findings: system taken offline until remediated |
Penetration test scope:
# zap-baseline.yaml
env:
contexts:In-scope:
- name:Staging Bilko API
urls:
-pre-launch: https://staging.bilko.io/api/getdrop.no
authentication:- method:Production script(after #launch): ZAPhttps://getdrop.no, scripthttps://api.getdrop.no
to- authenticateAuthentication flows (login, registration, BankID OIDC callback — Phase 2)
- All 24 authenticated API endpoints
- Session management (JWT, cookie handling, revocation)
- Rate limiting and getCSRF JWT
rules:protection
- id:AWS 10202App #Runner Absenceconfiguration
- Cloudflare WAF configuration
Out-of-scope:
- Denial of Anti-CSRFservice tokens — note (cookies are httpOnly)
threshold: LOWattacks
- id:Social 10096engineering #of Timestampstaff Disclosurewithout —prior ignoreapproval
- AWS infrastructure itself (timestampsAWS areglobal public)responsibility)
threshold:- OFFBankID Norge AS systems
- Sumsub systems
Rules of engagement:
- Testing window: To be agreed in writing with provider
- Notify before testing: [email protected]
- Halt on critical finding: Immediately notify [email protected] + CTO
RequiredKey ZAPtest findingsareas thresholdfor (before release):Drop:
CRITICALJWT /manipulation HIGH:(algorithm 0confusion, allowedexpiry bypass, forged tokens)
MEDIUM:Session mustrevocation bebypass assessed(sessions —table known acceptable risks documentedmanipulation)
LOWIDOR /attacks INFORMATIONAL:(user_id documentscoping andvalidation prioritizeacross all 24 endpoints)
Rate limiting bypass (IP spoofing via X-Forwarded-For)
CSRF (Origin header bypass)
SQLi in all 24 endpoints (parameterized query verification)
BankID OIDC callback manipulation (Phase 2)
Feature flag bypass (cards endpoints when disabled)
Foedselsnummer exposure (ensure never in plaintext logs or API responses)
5. PenetrationVulnerability Testing
Frequency: Annual (or after significant architecture change)
Provider: External certified pentest firm (OSCP/CREST certified)
Scope:
Web application (app.bilko.io)
API endpoints
AuthenticationClassification & session management
Multi-tenant isolation (primary focus — org isolation must be tested)
Business logic flaws (VAT calculation, invoice numbering)
Third-party integrations (SEF API, HR-FISK)
Rules of engagement:
Staging environment only — no production testing without explicit CEO approval
No DoS / DDoS testing
No social engineering of employees
Penetration test agreement signed before engagement begins
Remediation SLAs
5.1 Severity Classification (post-pentestCVSS findings):
v3.1)
| Severity |
FixCVSS DeadlineScore |
Drop-Specific Definition |
CRITICALCritical |
489.0-10.0 |
hoursRCE, auth bypass without credentials, mass PII exfiltration, JWT forgery, foedselsnummer exposure |
HIGHHigh |
77.0-8.9 |
daysPrivilege escalation, IDOR (cross-user data access), auth bypass (authenticated), SQL injection |
MEDIUMMedium |
304.0-6.9 |
daysCSRF, reflected XSS, rate limit bypass, information disclosure |
LOWLow |
0.1-3.9 |
Version disclosure, weak error messages, minor misconfigurations |
| Informational |
N/A |
Best practice recommendations |
| Severity |
SLA |
Action on Breach of SLA |
| Critical |
Containment in 4h; full remediation in 24 hours |
Emergency — CISO + CTO + CEO. System taken offline if risk cannot be mitigated. |
| High |
7 calendar days |
Escalate to CISO. Engineering Lead must approve extension. |
| Medium |
30 calendar days |
Engineering Lead tracks. Exception requires Security team sign-off. |
| Low |
90 calendar days |
Tracked in backlog. Reviewed in quarterly security review. |
| Informational |
Next quartersprint (best effort) |
Not SLA-bound. |
SLA tracking: GitHub Issues with label security-finding + severity label.
6. Security Code Review Checklist
Required for every PR touching authentication, authorization, payment processing, PII, or cryptography:
Authentication & Authorization:
Input Validation:
Cryptography:
Error Handling:
Data Handling:
Dependencies:
7. Security Testing in CI/CD Pipeline
Current pipeline (MVP):
Developer Commit
+-- Pre-commit hook: npm audit (SCA)
|
v
Git Push -> PR
|
v
Vitest security tests (20+ tests)
|
v (all pass)
Merge to main
|
v
Deploy to AWS App Runner
Target pipeline (Phase 2+):
flowchart LR
COMMIT[Developer\nCommit] -->|Pre-commit| SCA_INC[npm audit\nSCA check]
SCA_INC -->|Pass| PUSH[Git Push]
PUSH --> PR[Pull Request]
PR --> VITEST[Vitest\nSecurity Tests]
PR --> SAST[SAST\nSemgrep/CodeQL]
PR --> SCA_FULL[npm audit\nFull scan]
PR --> SECRET[Secret\nScanning]
VITEST & SAST & SCA_FULL & SECRET -->|All pass| BUILD[Build\nDrop App]
BUILD --> STAGING[Deploy to\nStaging]
STAGING --> DAST[OWASP ZAP\nDAST Scan]
DAST -->|Pass| GATE{Security\nGate}
GATE -->|Pass| PROD[Deploy to\nProduction]
GATE -->|Fail| BLOCK[Block Deploy\nAlert [email protected]]
Pipeline security gate criteria:
6.8. Security CodeAudit ReviewHistory
| Date |
Type |
Provider |
Findings |
Status |
| 2026-02-12 |
Full security audit |
Internal (Security Architect) |
4C / 5H / 6M / 4L |
Complete |
| 2026-02-13 |
Hardening verification |
Internal |
0C / 0H / 2M / 4L |
Complete |
| TBD (Phase 3) |
External penetration test |
TBD |
— |
Planned — required before launch |
| TBD (Phase 3+) |
Annual pentest |
TBD |
— |
Annual thereafter |
Source: ~/ALAI/products/Drop/security/drop-security-rapport.md
Security Hardening Summary (2026-02-13)
| Finding |
ID |
Status |
Card data: only last_four + token_ref stored (no PAN/CVV) |
C1 |
Resolved |
Demo credentials gated behind NODE_ENV !== 'production' |
C2 |
Resolved |
| SHA-256 password support removed — bcrypt only |
C4 |
Resolved |
| Session revocation implemented and active |
C6/H1 |
Resolved |
| Input sanitization applied to all text fields |
H4 |
Resolved |
| Notification IDs validated (max 100, format check) |
M5 |
Resolved |
| Settings: currency/language validated against whitelists |
M6 |
Resolved |
Remaining items:
| Finding |
ID |
Type |
Plan |
CSP: unsafe-inline/unsafe-eval required by Next.js |
M1 |
Medium |
Nonce-based CSP in Phase 3 |
Proxy HOSTNAME config |
M2 |
Medium |
Resolve in Phase 2 AWS config |
9.1 Individual Finding
Finding ID: VULN-{YEAR}-{SEQUENCE}
Title: {SHORT_DESCRIPTION}
Severity: Critical / High / Medium / Low
CVSS Score: {SCORE} (v3.1)
Description:
{DETAILED_DESCRIPTION}
Affected Endpoint / File:
- {ENDPOINT_OR_FILE}: {URL_OR_LINE_NUMBER}
Proof of Concept:
{STEPS_TO_REPRODUCE}
Impact:
{WHAT_AN_ATTACKER_CAN_DO}
GDPR/AML Implications:
{IF_PERSONAL_DATA_OR_FINANCIAL_DATA_AFFECTED}
Remediation:
{SPECIFIC_FIX}
Owner: {ASSIGNED_ENGINEER}
SLA Due Date: {DATE}
Status: Open / In Progress / Resolved / Accepted Risk
10. Metrics & KPIs
| Metric |
Target |
Reporting Frequency |
| Critical findings resolved within SLA |
100% |
Monthly |
| High findings resolved within SLA |
100% |
Monthly |
| Vitest security test pass rate |
100% (blocking) |
Every PR |
| MTTR — Critical |
< 24 hours |
Per incident |
| MTTR — High |
< 7 days |
Monthly |
| Open High+ findings |
0 at launch |
Monthly |
| Annual penetration test completed |
Yes (before Phase 3) |
Annual |
| npm audit Critical CVEs |
0 in production |
Continuous |
11. Bug Bounty Program
WhenStatus: requiredPlanned (mandatoryPhase pre-merge)3 — post-launch)
Platform: Intigriti or HackerOne
Responsible disclosure (interim — before bug bounty):
Report security vulnerabilities to [email protected].
ChangesAcknowledgment: towithin authentication1 orbusiness authorization codeday
Changes to encryption utilities (encryptField, decryptField)
Changes to Prisma query patterns (potential org isolation bypass)
New external API integrations (SEF, FINA, etc.)
Changes to RBAC middleware or permission matrices
Who reviews: CTO or designated Senior Engineer with security background.
Checklist for security-sensitive PRs:
7. CI/CD Security Gates
flowchart LR
PR["Pull Request"] --> LINT["ESLint Security\nRules"]
LINT -->|"PASS"| AUDIT["npm audit\n--audit-level=high"]
AUDIT -->|"PASS"| TEST["Vitest\nSecurity Test Suite"]
TEST -->|"PASS"| SECRETS["TruffleHog\nSecret Scan"]
SECRETS -->|"PASS"| MERGE["Merge Allowed"]
LINT -->|"FAIL"| BLOCK["PR Blocked"]
AUDIT -->|"FAIL"| BLOCK
TEST -->|"FAIL"| BLOCK
SECRETS -->|"FAIL"| BLOCK
Non-negotiable gates (cannot be bypassed with --no-verify or --force):
ESLint security rules: zero error findings
npm audit: zero HIGH/CRITICAL CVEs
Vitest security tests: 100% pass — especially org isolation and RBAC tests
TypeScript strict: zero type errors
8. Vulnerability Disclosure
Process:
Security researchers may report vulnerabilities to [email protected]
Acknowledgment within 24 hours
Investigation and severity assessmentTriage: within 5 business days
RemediationSafe perharbor: SLAresearchers acting in Sectiongood 5faith are protected from legal action
Responsible disclosure: researcher notified when fix is deployed
Approval
| Role |
Name |
SignatureDate |
DateSignature |
| Author |
CTO / Security Engineer |
Architect |
2026-02-23 |
|
Reviewer (Engineering Lead)CISO |
|
|
|
ReviewerEngineering (DPO)Lead |
|
|
|
ApproverCTO |
CEO |
|
|
| Management |
|
|
|