Without a defined refund window, refunds can theoretically be issued for orders cancelled two years ago — a refund policy violation that a simple date comparison prevents. Beyond fraud prevention, the absence of a configured timeframe means your refund policy (stated in terms and conditions) and your code are inconsistent: the policy says '30 days', the system enforces no limit. CWE-285 applies when a time-based access control exists in policy but not in code. The fix is a single numeric constant — REFUND_WINDOW_DAYS in lib/orders/config.ts — that makes the policy machine-enforceable and auditable.
Low because the practical risk requires a customer to request a refund long after the window and the system to process it, which is unlikely but not impossible without the guard.
Define the refund window as a named constant in lib/orders/config.ts and enforce it with a date comparison at the start of the refund handler at app/api/orders/[id]/refund/route.ts.
// lib/orders/config.ts
export const REFUND_WINDOW_DAYS = 30
// app/api/orders/[id]/refund/route.ts
import { REFUND_WINDOW_DAYS } from '@/lib/orders/config'
const daysSinceCancellation = Math.floor(
(Date.now() - order.cancelledAt!.getTime()) / (1000 * 60 * 60 * 24)
)
if (daysSinceCancellation > REFUND_WINDOW_DAYS) {
return Response.json(
{ error: `Refund window of ${REFUND_WINDOW_DAYS} days has passed.` },
{ status: 409 }
)
}
ID: ecommerce-order-management.cancellation-refunds.refund-timeframe
Severity: low
What to look for: Check for refund processing logic that enforces or references a defined timeframe for refund eligibility (e.g., "refunds must be initiated within 30 days of cancellation"). Look for at least 1 date comparison in refund handlers — something like if (daysSinceCancellation > 30) throw new Error(...). Also check for a configuration constant that defines the refund window duration (at least 1 numeric constant). Quote the exact timeframe value if one exists. Count the number of refund handlers that enforce this window.
Pass criteria: The refund logic includes or references a defined timeframe (at least 1 numeric constant, e.g., REFUND_WINDOW_DAYS = 30) for refund initiation after cancellation. The refund handler validates the order's cancellation date against this window and rejects out-of-window refund requests with an error message. At least 1 date comparison exists in the refund path.
Fail criteria: No timeframe concept exists in the codebase (0 date comparisons in refund handlers) — refunds can theoretically be initiated for any order regardless of when it was cancelled. No date validation logic exists.
Skip (N/A) when: The project does not support refunds. Or the project's refund policy is "all cancellations are immediately refunded" and refunds are processed as part of the cancellation flow, making a separate timeframe concept unnecessary. No separate refund endpoint exists.
Detail on fail: "No refund timeframe validation found. The refund handler at src/app/api/orders/[id]/refund/route.ts contains 0 date comparisons. Refunds could theoretically be issued for orders cancelled years ago."
Remediation: Add timeframe configuration in lib/orders/config.ts and validation in the refund handler:
// lib/orders/config.ts
export const REFUND_WINDOW_DAYS = 30
// In refund handler (app/api/orders/[id]/refund/route.ts):
import { REFUND_WINDOW_DAYS } from '@/lib/orders/config'
const cancelledAt = order.cancelledAt
if (!cancelledAt) {
return Response.json({ error: 'Order is not cancelled' }, { status: 409 })
}
const daysSinceCancellation = Math.floor(
(Date.now() - cancelledAt.getTime()) / (1000 * 60 * 60 * 24)
)
if (daysSinceCancellation > REFUND_WINDOW_DAYS) {
return Response.json(
{ error: `Refund window of ${REFUND_WINDOW_DAYS} days has passed.` },
{ status: 409 }
)
}