Interlace ESLint
ESLint Interlace

require-issuer-validation

**Severity:** � Medium

Require issuer (iss) claim validation in JWT verify operations

Severity: 🟡 Medium
CWE: CWE-287

Error Message Format

The rule provides LLM-optimized error messages (Compact 2-line format) with actionable security guidance:

🔒 CWE-287 OWASP:A07 CVSS:9.8 | Improper Authentication detected | CRITICAL
   Fix: Review and apply the recommended fix | https://owasp.org/Top10/A07_2021/

Message Components

ComponentPurposeExample
Risk StandardsSecurity benchmarksCWE-287 OWASP:A07 CVSS:9.8
Issue DescriptionSpecific vulnerabilityImproper Authentication detected
Severity & ComplianceImpact assessmentCRITICAL
Fix InstructionActionable remediationFollow the remediation steps below
Technical TruthOfficial referenceOWASP Top 10

Rule Details

This rule mandates issuer validation in verify() calls. Without issuer validation, tokens from any issuer are accepted.

Examples

❌ Incorrect

jwt.verify(token, secret);
jwt.verify(token, secret, { algorithms: ['RS256'] });

✅ Correct

jwt.verify(token, secret, { issuer: 'https://auth.example.com' });
jwt.verify(token, secret, {
  algorithms: ['RS256'],
  issuer: 'https://auth.example.com',
});

Known False Negatives

The following patterns are not detected due to static analysis limitations:

Options from Variable

Why: Variable contents are not analyzed.

// ❌ NOT DETECTED - Options from variable
const opts = { algorithms: ['RS256'] }; // Missing issuer
jwt.verify(token, secret, opts);

Mitigation: Use inline options. Create TypeScript types requiring issuer.

Spread Options

Why: Spread properties hide the actual options at lint time.

// ❌ NOT DETECTED - issuer may be missing in base
const baseOpts = getVerifyOptions(); // No issuer
jwt.verify(token, secret, { ...baseOpts });

Mitigation: Always specify issuer explicitly. Avoid spreading untrusted options.

Runtime Issuer Configuration

Why: Issuer from runtime config is not visible.

// ❌ NOT DETECTED - Issuer from config
jwt.verify(token, secret, { issuer: config.issuer }); // Might be undefined

Mitigation: Validate config at startup. Use required fields in TypeScript config types.

Multi-Tenant Issuer Lists

Why: Complex issuer validation logic is not understood.

// ❌ NOT DETECTED (may be incorrectly flagged) - Dynamic issuer list
const issuers = getTenantIssuers();
jwt.verify(token, secret, { issuer: issuers });

Mitigation: Use trustedAnnotations for complex validation patterns.

Further Reading

On this page