Corrections/reversals logged separately with approval chain
Why it matters
When a financial correction or reversal is handled by deleting or modifying the original log record, the audit trail loses continuity — an examiner reviewing the log will see the final state but not the error and its correction, which is exactly the information they need to evaluate whether the process is operating with integrity. SOX §404 requires that corrections to financial records follow a controlled, documented process. NIST 800-53 AU-10 (Non-Repudiation) requires that the organization protect against individuals falsely denying having performed particular actions — an undocumented reversal creates the ability to deny that an original transaction ever occurred. FINRA Rule 4511 requires that corrections be documented as corrections, not as silent replacements. CWE-284 (Improper Access Control) covers the case where any operator can issue a reversal without a separate approver checking the request.
Severity rationale
Low because correction logging is a process-integrity control — its absence enables unilateral reversals without a second-party check, but the financial impact depends on the specific transaction value involved.
Remediation
Implement corrections as a two-record pattern in src/services/corrections.ts: one record for the approval event, one for the reversal transaction, neither touching the original row:
async function approveAndReverseTransaction(
correctionId: string, approverUserId: string
) {
const correction = await db('corrections').where({ id: correctionId }).first();
await db('transaction_logs').insert([
{
user_id: approverUserId,
operation_type: 'correction_approved',
details: JSON.stringify({
correction_id: correctionId,
original_transaction_id: correction.original_transaction_id,
reason: correction.reason,
requested_by: correction.requested_by
}),
timestamp: new Date().toISOString()
},
{
user_id: approverUserId,
operation_type: 'reversal',
details: JSON.stringify({
original_transaction_id: correction.original_transaction_id,
approved_by: approverUserId,
approved_at: new Date().toISOString()
}),
timestamp: new Date().toISOString()
}
]);
}
Verify requester_id !== approver_id before calling this function — a single person should never be able to self-approve a correction.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Financial Audit Trail Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-284 — Improper Access Control — reversal without authorization
- nist:rev5 · AU-10 — Non-Repudiation — correction approval chain
- sox · Section 404 — Management Assessment of Internal Controls — approval workflows for adjustments
- external · FINRA-Rule-4511 — FINRA Rule 4511 — corrections must be documented separately from originals
Taxons
History
- 2026-04-18·v1.0.0·Initial import from finserv-audit-trail·automated