Executive Summary#
This research analyzes a voucher enumeration risk observed in the integration between Cibus and the Victory retail chain. Victory vouchers distributed via Cibus rely on predictable, low-entropy, sequential numeric identifiers protected only by a Luhn checksum, while being delivered to end users through cryptographically strong, high-entropy URLs.
Long-term observation indicates that Victory voucher identifiers are generated merchant-side by Victory and provisioned to Cibus in advance, rather than being generated dynamically per sale. This design introduces a critical dependency: the moment at which a voucher becomes redeemable.
If vouchers are redeemable upon provisioning (prior to end-user sale), this architecture enables deterministic theft of unissued vouchers. Future vouchers can be derived offline with high accuracy and redeemed before legitimate customers ever receive them.
If, however, vouchers require an explicit post-sale activation step, the issue degrades into a high-risk probabilistic enumeration problem rather than a deterministic one. The distinction is architectural—not cryptographic—and defines the severity boundary.
Scope Note: This research is strictly limited to Victory-issued vouchers (prefix
93039000). Vouchers issued for other merchants (e.g., Shufersal) were observed to follow non-predictable schemes and are out of scope.
Severity: HIGH / CRITICAL ¹
- Vulnerability Class: Predictable Object Identifiers / Business Logic / Supply-Chain Risk
- Attack Vector: Offline Enumeration + Opportunistic Physical Redemption
- Impact: Theft of financial assets
¹ Conditional Risk Level:
| Risk Level | Condition | Exploitability | Notes |
|---|---|---|---|
| Critical | Vouchers valid at provisioning | Near-100% | Single voucher allows local enumeration of the active allocation window |
| High | Vouchers require activation trigger | Probabilistic | Success depends on issued-but-not-redeemed identifiers; temporal density matters |
Terminology#
To avoid ambiguity, the following terms are used consistently throughout this document:
- Generated: Voucher identifier created by Victory’s voucher system
- Provisioned: Voucher allocated to Cibus inventory but not yet sold
- Sold: Voucher assigned to an end user via the Cibus application
- Redeemed: Voucher consumed at a Victory point-of-sale
High-Entropy Delivery Masking Low-Entropy Assets#
Cibus delivers vouchers using cryptographically secure, high-entropy URLs intended to prevent unauthorized access or guessing.
However, these URLs function purely as a transport wrapper. The redeemable asset itself—the barcode presented at the point of sale—is a static numeric identifier whose structure can be fully derived offline.
If vouchers were generated dynamically by Cibus, the secure URL would provide meaningful security guarantees. Instead, the presence of a strong delivery wrapper around a predictable identifier strongly suggests that voucher secrecy—not voucher generation—is delegated to the URL layer, a common pattern when assets are pre-generated by an upstream merchant.
Observed Voucher Structure (Victory)#
Victory vouchers follow a fixed 20-digit numeric structure:
93039000xxxxxx00400y
- Prefix (
93039000): Static, merchant-specific identifier - Enumerable Component (
xxxxxx): 6-digit, non-random integer - Infix (
00400): Static - Checksum (
y): Luhn Mod 10
The checksum enforces syntactic integrity only and provides no resistance against intentional generation.
def calculate_luhn(prefix):
"""Calculates the Luhn Mod 10 check digit for a voucher prefix."""
digits = [int(d) for d in prefix]
total_sum = 0
for i, digit in enumerate(digits[::-1]):
if i % 2 == 0:
doubled = digit * 2
total_sum += doubled - 9 if doubled > 9 else doubled
else:
total_sum += digit
return (10 - (total_sum % 10)) % 10
prefix = "9303900012345600400"
print(calculate_luhn(prefix)) # output: 7Longitudinal Evidence of Merchant-Side Issuance#
Voucher identifiers were tracked over approximately 18 months (June 2024 to January 2026) through repeated legitimate purchases.
Key observations:
- The enumerable component increased from approximately 360,000 to 580,000 (~11,000 vouchers/month)
- Values advance monotonically when observed over long time horizons
- Identifiers are not randomly permuted
- Vouchers purchased on the same day may appear out of numerical order, yet consistently fall within a narrow numerical window (typically a few thousand identifiers)

Across 95 observations, the average growth rate was approximately 11k vouchers per month, with moderate variance. The observed behavior rules out both global random issuance across the full keyspace and strict per-transaction sequential issuance, and instead shows identifiers being consistently drawn from a narrow, contiguous window of the keyspace that advances over time.
This pattern is inconsistent with a single globally incremented counter or uniform random selection from the entire identifier space. Instead, it is consistent with windowed or batch-based provisioning, where identifiers are allocated to Cibus in bounded ranges and later consumed in non-deterministic order.
This model also explains why vouchers issued for other merchants exhibit materially stronger, non-sequential identifiers: voucher generation appears to be merchant-specific, not platform-wide.
Finite Keyspace and Predictability#
The enumerable component is limited to 6 digits, yielding a maximum space of 1,000,000 vouchers.
This creates three critical properties:
Hard Upper Bound The identifier space is finite and exhaustible, forcing rollover, reuse, or format expansion unless explicitly redesigned.
Complete Derivability Given the format and checksum, all possible identifiers—past and future—can be derived offline with trivial effort.
Irreversible Exposure Once identifiers are provisioned to downstream systems, their predictability cannot be retroactively mitigated.
The behavior of the system once the enumerable component reaches its upper bound (999,999) is unknown. Possible outcomes include rollover, identifier reuse, or format expansion, each of which introduces additional security and operational risk if not explicitly designed and documented.
State-Based Threat Model#
The practical risk depends entirely on when a voucher transitions to a redeemable state.
Voucher States#
| State | Predictable | Redeemable | Risk |
|---|---|---|---|
| Sold to user | Yes | Yes | Theft |
| Sold & redeemed | Yes | No | Noise |
| Provisioned to Cibus (unsold) | Yes | Depends on activation semantics | Deterministic or Probabilistic |
If vouchers are redeemable upon provisioning, exploitation becomes deterministic: density and timing are irrelevant, and attackers can redeem future vouchers before legitimate issuance.
If vouchers require explicit activation, the attack becomes probabilistic but remains high-risk due to clustered issuance and a small effective search window.
Why Traditional Mitigations Do Not Apply#
- Rate Limiting: Retail redemption environments require high throughput and cannot reliably distinguish distributed abuse from legitimate traffic.
- Sequential Detection: Sequential voucher usage is normal (e.g., group purchases, gift distribution).
- Physical Presence Assumptions: Monetization via resale markets, QR forwarding, or intermediaries makes abuse indistinguishable from legitimate consumer behavior.
Architectural Remediation#
Because voucher length and numeric format are constrained by legacy POS systems, remediation must focus on issuance and activation boundaries, not presentation.
1. Eliminate Predictability at the Trust Boundary#
Before vouchers become redeemable, identifiers should be cryptographically remapped using format-preserving techniques (e.g., Feistel-based permutations) or merchant-side indirection tables.
2. Enforce Explicit Activation#
Vouchers must not be redeemable until explicitly activated and bound to a completed sale. Provisioning alone must not confer validity.
3. Canary Voucher Detection#
Unused portions of the identifier space can be reserved as canary vouchers. Redemption attempts against these identifiers provide high-confidence detection of enumeration without impacting legitimate users.
The Pool Window Blind Spot Detection based on “out-of-range” identifiers provides a false sense of security. An adaptive attacker can anchor enumeration by purchasing a single legitimate voucher and restricting searches to the active allocation window, remaining indistinguishable from legitimate behavior.
Responsible Disclosure#
This issue was responsibly disclosed to Victory on January 28, 2026. At the time of publication, no confirmation of remediation has been received.
Conclusion#
This issue illustrates a failure mode common in distributed voucher ecosystems: predictable assets combined with early validity collapse the security boundary entirely.
When redeemability precedes ownership, security does not degrade gradually—it fails catastrophically. In such systems, secrecy of delivery URLs cannot compensate for predictable identifiers.
Security must be enforced at the moment of validity, not merely at the moment of transport.
Looking for a research position? Let’s connect on LinkedIn.




