Skip to main content

Security Testing Policy

Security Testing Policy

Project / Organization: ALAI Holding AS — Drop Payment App Policy Number: POL-SEC-TEST-001 Version: 1.0 Date: 2026-02-23 Author: Security Architect Status: Draft Reviewers: CISO, Engineering Lead, CTO Next Review: 2027-02-23 Classification: Confidential

Document History

Version Date Author Changes
0.1 2026-02-23 Security Architect Initial draft — Drop security testing methodology

1. Purpose & Scope

Purpose: This policy defines the security testing methodology, tools, frequency, and remediation requirements for all systems operated by ALAI Holding AS for the Drop payment app. Security testing is mandatory — 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 production APIs and endpoints (getdrop.no, api.getdrop.no)
  • All AWS infrastructure (App Runner, S3, KMS, Secrets Manager)
  • All CI/CD pipelines and build systems
  • All third-party integrations (BankID, 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 Methodology

Approach: Shift-left security — testing integrated throughout development, not bolted on at the end.

Testing layers:

Development Phase
    +-- Unit security tests — Vitest (current: 20+ security-specific tests)
    +-- SCA — npm audit (every commit, automated)
    +-- Secret scanning — detect leaked credentials (every commit)

Build / CI Phase
    +-- SAST — static code analysis (every PR — planned Phase 2)
    +-- SCA — dependency vulnerability check (every 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 — manual expert testing (before Phase 3 launch)
    +-- Post-incident review — regression tests after any security incident

3. Current Security Test Coverage

3.1 Vitest Unit Security Tests

Status: Implemented — 20+ security-specific tests Source: src/drop-app/src/__tests__/

Test Category Test Source
Authentication JWT secret required in production auth.test.ts
Authentication Cookie: httpOnly=true, secure=true, sameSite=strict auth.test.ts
Authentication JWT contains setIssuedAt() auth.test.ts
Authentication Session 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 — Software Composition Analysis

Status: Implemented (npm audit)

Property Value
Tool npm audit (built-in) + GitHub Dependabot (planned)
Frequency Every commit (pre-commit hook) + every PR
Blocking YES — Critical CVE blocks merge

Current dependency security status (2026-02-13 audit):

Package Version Risk Status
jose ^6.1.3 Low No known CVEs
bcryptjs ^3.0.3 Low No known CVEs
better-sqlite3 ^12.6.2 Low No known CVEs
next 16.1.6 Low Recent version
react 19.2.3 Low Latest major
radix-ui ^1.4.3 Low UI only — no known CVEs

Source: ~/ALAI/products/Drop/security/drop-security-rapport.md

Dependency update policy:

  • Security patches (Critical/High): Merge within SLA (see §5)
  • Minor security updates: Merge within 14 days
  • Major updates: Planned migration within 90 days

Approved licenses: MIT, Apache 2.0, BSD (2-clause, 3-clause), ISC


4.2 SAST — Static Application Security Testing

Status: Planned (Phase 2)

Property Value
Tool Semgrep or CodeQL (via GitHub Advanced Security)
Frequency Every PR (full scan)
Languages TypeScript, JavaScript
Blocking YES — Critical or High findings block merge

SAST rules in scope (when implemented):

  • SQL injection detection (parameterized queries validation)
  • 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

Status: Planned (Phase 3 — before production launch)

Property Value
Tool OWASP ZAP (planned)
Frequency Every deployment to staging + weekly full scan
Target https://staging.getdrop.no — NEVER production without CISO written approval
Blocking YES — deployment halted if Critical finding discovered

DAST scan scope:

  • All 24 API endpoints (authenticated + unauthenticated)
  • Authentication flows (login, registration, logout, session handling)
  • Rate limiting (verify 10/60s 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

Status: 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:

In-scope:
- Staging pre-launch: https://staging.getdrop.no
- Production (after launch): https://getdrop.no, https://api.getdrop.no
- Authentication flows (login, registration, BankID OIDC callback — Phase 2)
- All 24 authenticated API endpoints
- Session management (JWT, cookie handling, revocation)
- Rate limiting and CSRF protection
- AWS App Runner configuration
- Cloudflare WAF configuration

Out-of-scope:
- Denial of service attacks
- Social engineering of staff without prior approval
- AWS infrastructure itself (AWS global responsibility)
- BankID 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

Key test areas for Drop:

  1. JWT manipulation (algorithm confusion, expiry bypass, forged tokens)
  2. Session revocation bypass (sessions table manipulation)
  3. IDOR attacks (user_id scoping validation across all 24 endpoints)
  4. Rate limiting bypass (IP spoofing via X-Forwarded-For)
  5. CSRF (Origin header bypass)
  6. SQLi in all 24 endpoints (parameterized query verification)
  7. BankID OIDC callback manipulation (Phase 2)
  8. Feature flag bypass (cards endpoints when disabled)
  9. Foedselsnummer exposure (ensure never in plaintext logs or API responses)

5. Vulnerability Classification & Remediation SLAs

5.1 Severity Classification (CVSS v3.1)

Severity CVSS Score Drop-Specific Definition
Critical 9.0-10.0 RCE, auth bypass without credentials, mass PII exfiltration, JWT forgery, foedselsnummer exposure
High 7.0-8.9 Privilege escalation, IDOR (cross-user data access), auth bypass (authenticated), SQL injection
Medium 4.0-6.9 CSRF, reflected XSS, rate limit bypass, information disclosure
Low 0.1-3.9 Version disclosure, weak error messages, minor misconfigurations
Informational N/A Best practice recommendations

5.2 Remediation SLAs

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 sprint (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:

  • No hardcoded credentials, JWT secrets, or API keys
  • Password hashing uses bcrypt (cost >= 12) — SHA-256 explicitly rejected (fix C4)
  • JWT validation: signature, expiry, iat claim verified via jose
  • Session revocation: all protected endpoints check sessions table for revoked = 0
  • No role flags from user-supplied input
  • All protected endpoints have authentication middleware applied
  • Logout revokes sessions server-side (not just clears cookie)

Input Validation:

  • All user inputs validated using Drop validators (validateAmount, validateIBAN, validateCurrency, validateLanguage, sanitizeText)
  • All database operations use parameterized ? queries — no string concatenation
  • User data queries include AND user_id = ? scoping (IDOR prevention)
  • No eval(), exec(), or shell command interpolation with user input

Cryptography:

  • No MD5, SHA-1, DES, RC4 (per data-encryption-policy.md §2.2)
  • Random values use crypto.randomBytes() — not Math.random()
  • IVs/nonces are random (96-bit minimum) and never reused
  • No cryptographic keys in source code, logs, or error messages

Error Handling:

  • No stack traces or internal paths in API error responses
  • Generic messages for authentication failures (no user enumeration)
  • Errors logged to Sentry internally but not exposed in API responses

Data Handling:

  • Foedselsnummer not logged in plaintext (never in Sentry, BetterStack, console.log)
  • Sensitive data not in query parameters (use POST body)
  • Feature flags checked before any cards-related endpoint
  • AML retention: user data deletion respects 5-year retention (Hvitvaskingsloven § 30)

Dependencies:

  • New dependencies reviewed with npm audit before adding
  • No end-of-life packages introduced
  • License compatible (MIT, Apache 2.0, BSD, ISC)

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:

Gate Tool Blocking Criteria
Pre-commit npm audit Critical CVE
PR gate 1 Vitest security tests Any test failure
PR gate 2 SAST (Phase 2) Critical or High finding
PR gate 3 npm audit full Critical CVE
PR gate 4 Secret scanning Any detected secret
Post-staging DAST (Phase 3) Critical or High dynamic finding

8. Security Audit History

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. Reporting Format

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

Status: Planned (Phase 3 — post-launch) Platform: Intigriti or HackerOne

Responsible disclosure (interim — before bug bounty): Report security vulnerabilities to [email protected].

  • Acknowledgment: within 1 business day
  • Triage: within 5 business days
  • Safe harbor: researchers acting in good faith are protected from legal action

Approval

Role Name Date Signature
Author Security Architect 2026-02-23
CISO
Engineering Lead
CTO
Management