The Problem: License Checks in Plain Sight
If your JavaScript product validates license keys, enforces usage limits, or checks subscription status in the browser, that logic is visible to every user who opens DevTools. Without protection, a motivated user can find your validation function, understand its logic, and patch around it — turning your paid feature into a free one.
Architecture Matters First
Before obfuscation, get your architecture right. The strongest approach is server-side license validation:
// WEAK: License validation entirely in JavaScript
function checkLicense(key) {
const validKeys = ['ABC-123', 'DEF-456']; // Visible to anyone!
return validKeys.includes(key);
}
// STRONG: License validation via API
async function checkLicense(key) {
const response = await fetch('/api/validate', {
method: 'POST',
body: JSON.stringify({ key }),
headers: { 'Content-Type': 'application/json' }
});
const { valid } = await response.json();
return valid; // Actual validation happens on your server
}
With server-side validation, the client never sees the validation logic. Even if someone deobfuscates your JavaScript, all they find is an API call — the actual check is on your server where they can't reach it.
When You Must Validate Client-Side
Sometimes client-side validation is unavoidable — offline software, embedded scripts, or cases where a network call is architecturally problematic. In these cases, obfuscation becomes critical.
Obfuscation Techniques for License Logic
Apply maximum protection to your license-checking module:
// Config for license-check specific obfuscation
const licenseObfuscatorConfig = {
compact: true,
stringArray: true,
stringArrayEncoding: ['rc4'], // Stronger than base64
rotateStringArray: true,
shuffleStringArray: true,
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.5,
selfDefending: true,
debugProtection: true,
debugProtectionInterval: 2000,
unicodeEscapeSequence: true
};
Domain Locking
The javascript-obfuscator library supports domain locking — the obfuscated code checks what domain it's running on and refuses to execute on unauthorized domains. This prevents someone from copying your obfuscated license script and embedding it in their own project:
JavaScriptObfuscator.obfuscate(code, {
domainLock: ['yoursite.com', 'www.yoursite.com'],
domainLockRedirectUrl: 'about:blank'
});
Timing and Feature Gating
Rather than a single license check that can be patched once, spread license verification throughout your code. Check license validity at feature activation, not just at startup. Use multiple independent checks. This makes bypassing much harder — patching one check doesn't unlock everything.
Detecting Tampering
Combine self-defending mode with your license checks. If someone removes the self-defending code to analyze your license logic, the self-defense detects the modification and kills execution. This creates a chicken-and-egg problem for the attacker: they need to remove self-defense to analyze the license check, but removing self-defense breaks execution.