feat: Payment Compliance Pack — Semgrep + CodeQL + State Machine + Schema

Ausfuehrbares Pruefpaket fuer Payment-Terminal-Systeme:

1. Semgrep-Regeln (25 Regeln in 5 Dateien):
   - Logging: Sensitive Daten, Tokens, Debug-Flags
   - Crypto: MD5/SHA1/DES/ECB, Hardcoded Secrets, Weak Random, TLS
   - API: Debug-Routes, Exception Leaks, IDOR, Input Validation
   - Config: Test-Endpoints, CORS, Cookies, Retry
   - Data: Telemetrie, Cache, Export, Queue, Testdaten

2. CodeQL Query-Specs (5 Briefings):
   - Sensitive Data → Logs
   - Sensitive Data → HTTP Response
   - Tenant Context Loss
   - Sensitive Data → Telemetry
   - Cache/Export Leak

3. State-Machine-Tests (10 Testfaelle):
   - 11 Zustaende, 15 Events, 8 Invarianten
   - Duplicate Response, Timeout+Late Success, Decline
   - Invalid Reversal, Cancel, Backend Timeout
   - Parallel Reversal, Unknown Response, Reconnect
   - Late Response after Cancel

4. Finding Schema (JSON Schema):
   - Einheitliches Format fuer alle Engines
   - control_id, engine, status, confidence, evidence, verdict_text

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-04-13 14:59:49 +02:00
parent 5c1a514b52
commit 8dfab4ba14
15 changed files with 567 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
# Terminal State Machine Invariants
## Invariant 1
APPROVED darf ohne expliziten Reversal-Pfad nicht in WAITING_FOR_TERMINAL zurueckgehen.
## Invariant 2
DECLINED darf keinen Buchungserfolg oder Success-Report erzeugen.
## Invariant 3
duplicate_response darf keinen zweiten Commit und keine zweite Success-Bestaetigung erzeugen.
## Invariant 4
DESYNC muss Audit-Logging und Klaerungsstatus ausloesen.
## Invariant 5
REVERSAL_PENDING darf nicht mehrfach parallel ausgeloest werden.
## Invariant 6
invalid_command darf nie zu APPROVED fuehren.
## Invariant 7
terminal_timeout darf nie stillschweigend als Erfolg interpretiert werden.
## Invariant 8
Late responses nach finalem Zustand muessen kontrolliert behandelt werden.

View File

@@ -0,0 +1,47 @@
# Terminal Payment State Machine
## States
- IDLE
- SESSION_OPEN
- PAYMENT_REQUESTED
- WAITING_FOR_TERMINAL
- APPROVED
- DECLINED
- CANCELLED
- REVERSAL_PENDING
- REVERSED
- ERROR
- DESYNC
## Events
- open_session
- close_session
- send_payment
- terminal_ack
- terminal_approve
- terminal_decline
- terminal_timeout
- backend_timeout
- reconnect
- cancel_request
- reversal_request
- reversal_success
- reversal_fail
- duplicate_response
- invalid_command
## Transitions
| From | Event | To |
|------|-------|----|
| IDLE | open_session | SESSION_OPEN |
| SESSION_OPEN | send_payment | PAYMENT_REQUESTED |
| PAYMENT_REQUESTED | terminal_ack | WAITING_FOR_TERMINAL |
| WAITING_FOR_TERMINAL | terminal_approve | APPROVED |
| WAITING_FOR_TERMINAL | terminal_decline | DECLINED |
| WAITING_FOR_TERMINAL | terminal_timeout | DESYNC |
| WAITING_FOR_TERMINAL | cancel_request | CANCELLED |
| APPROVED | reversal_request | REVERSAL_PENDING |
| REVERSAL_PENDING | reversal_success | REVERSED |
| REVERSAL_PENDING | reversal_fail | ERROR |
| * | invalid_command | ERROR |
| * | backend_timeout | DESYNC |

View File

@@ -0,0 +1,92 @@
[
{
"test_id": "ZVT-SM-001",
"name": "Duplicate approved response",
"initial_state": "WAITING_FOR_TERMINAL",
"events": ["terminal_approve", "duplicate_response"],
"expected_final_state": "APPROVED",
"invariants": ["Invariant 3"],
"mapped_controls": ["TRANS-004", "TRANS-009", "ZVT-RESP-005"]
},
{
"test_id": "ZVT-SM-002",
"name": "Timeout then late success",
"initial_state": "WAITING_FOR_TERMINAL",
"events": ["terminal_timeout", "terminal_approve"],
"expected_final_state": "DESYNC",
"invariants": ["Invariant 4", "Invariant 7", "Invariant 8"],
"mapped_controls": ["TRANS-005", "TRANS-007", "TERMSYNC-009", "TERMSYNC-010"]
},
{
"test_id": "ZVT-SM-003",
"name": "Decline must not produce booking",
"initial_state": "WAITING_FOR_TERMINAL",
"events": ["terminal_decline"],
"expected_final_state": "DECLINED",
"invariants": ["Invariant 2"],
"mapped_controls": ["TRANS-011", "TRANS-025", "ZVT-RESP-002"]
},
{
"test_id": "ZVT-SM-004",
"name": "Invalid reversal before approval",
"initial_state": "PAYMENT_REQUESTED",
"events": ["reversal_request"],
"expected_final_state": "ERROR",
"invariants": ["Invariant 6"],
"mapped_controls": ["ZVT-REV-001", "ZVT-STATE-002", "ZVT-CMD-001"]
},
{
"test_id": "ZVT-SM-005",
"name": "Cancel during waiting",
"initial_state": "WAITING_FOR_TERMINAL",
"events": ["cancel_request"],
"expected_final_state": "CANCELLED",
"invariants": ["Invariant 7"],
"mapped_controls": ["TRANS-006", "ZVT-CMD-001", "ZVT-STATE-003"]
},
{
"test_id": "ZVT-SM-006",
"name": "Backend timeout after terminal ack",
"initial_state": "WAITING_FOR_TERMINAL",
"events": ["terminal_ack", "backend_timeout"],
"expected_final_state": "DESYNC",
"invariants": ["Invariant 4", "Invariant 7"],
"mapped_controls": ["TERMSYNC-010", "TRANS-012", "ZVT-SESSION-003"]
},
{
"test_id": "ZVT-SM-007",
"name": "Parallel reversal requests",
"initial_state": "APPROVED",
"events": ["reversal_request", "reversal_request"],
"expected_final_state": "REVERSAL_PENDING",
"invariants": ["Invariant 5"],
"mapped_controls": ["ZVT-REV-003", "TRANS-016", "TRANS-019"]
},
{
"test_id": "ZVT-SM-008",
"name": "Unknown response code",
"initial_state": "WAITING_FOR_TERMINAL",
"events": ["terminal_ack", "invalid_command"],
"expected_final_state": "ERROR",
"invariants": ["Invariant 6"],
"mapped_controls": ["ZVT-RESP-003", "ZVT-COM-005", "ZVT-STATE-005"]
},
{
"test_id": "ZVT-SM-009",
"name": "Reconnect and resume controlled",
"initial_state": "SESSION_OPEN",
"events": ["send_payment", "terminal_timeout", "reconnect"],
"expected_final_state": "WAITING_FOR_TERMINAL",
"invariants": ["Invariant 7"],
"mapped_controls": ["ZVT-SESSION-004", "TRANS-007", "ZVT-RT-004"]
},
{
"test_id": "ZVT-SM-010",
"name": "Late response after cancel",
"initial_state": "WAITING_FOR_TERMINAL",
"events": ["cancel_request", "terminal_approve"],
"expected_final_state": "DESYNC",
"invariants": ["Invariant 4", "Invariant 8"],
"mapped_controls": ["TERMSYNC-008", "TERMSYNC-009", "TRANS-018"]
}
]