Skip to content

Fix modulo bias in referral code generation #532

Description

@DeFiVC

Bug Description

The generateReferralCode method in src/modules/courses/course.service.ts (lines 938-945) uses modulo bias when generating referral codes. The method uses b % alphabet.length where b is a random byte (0-255) and alphabet.length is 62, which introduces bias.

Location

src/modules/courses/course.service.ts lines 938-945

private generateReferralCode(): string {
    const alphabet =
        "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    const bytes = crypto.randomBytes(10);
    let code = "";
    for (const b of bytes) code += alphabet[b % alphabet.length];
    return code;
}

The Problem

  • Random byte range: 0-255 (256 values)
  • Alphabet length: 62 characters
  • 256 / 62 = 4.13, so characters 0-9 (indices 0-9) appear slightly more often than others
  • Characters at indices 0-9 (digits) have a 5/256 chance vs 4/256 for others

The bias is small but detectable with statistical tests. For a security-sensitive token (referral codes), this is undesirable.

Recommended Fix

Use rejection sampling or crypto.randomInt:

private generateReferralCode(): string {
    const alphabet =
        "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    let code = "";
    for (let i = 0; i < 10; i++) {
        code += alphabet[crypto.randomInt(alphabet.length)];
    }
    return code;
}

Or use crypto.randomUUID() and encode it in base62.

Acceptance Criteria

  • Replace modulo bias with unbiased random selection
  • Use crypto.randomInt() or rejection sampling
  • Verify referral codes are uniformly distributed

Severity

low - Minor cryptographic weakness. The bias is small and referral codes are not high-security tokens.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions