Generate Safe, Random, Tamper-Proof IDs in JavaScript with Legid.js

Category: Javascript , Recommended | July 14, 2025
Authorshuding
Last UpdateJuly 14, 2025
LicenseMIT
Tags
Views51 views
Generate Safe, Random, Tamper-Proof IDs in JavaScript with Legid.js

legid is a JavaScript (TypeScript) library that generates safe and random URL-compatible IDs to prevent client-side manipulation.

Traditional random ID generators like UUID or simple random strings leave applications vulnerable to manipulation attacks. A malicious user can override the ID generation function through browser developer tools to create IDs like “admin” or other privileged values.

Legid addresses this by embedding cryptographic verification directly into the ID structure. This makes manipulation computationally difficult while maintaining the convenience of client-side generation.

Features:

  • Tamper-resistant ID generation – Uses SHA-1 hashing with salt to prevent manipulation
  • URL-safe character set – Only uses A-Z, a-z, 0-9 characters
  • Zero-dependency verification – Server-side validation requires no shared secrets or tokens
  • Configurable length – Approximate length control from 1 to 54 characters
  • Custom salt support – Optional salt customization for additional security
  • TypeScript support – Full type definitions included

How to use it:

1. Install the legid library and import into your project.

# NPM
npm install legid
# or
pnpm install legid
# or
yarn add legid
import { createId } from 'legid';

2. On the client, you use the createId function. It’s an async function using the Web Crypto API.

// Generate an ID with default settings
const id = await createId();
// Example output: 'eJDTjgGozr'
// Generate a longer ID with a custom salt
const longerId = await createId({
  approximateLength: 20,
  salt: 'my-app-specific-salt',
});
// Example output: 'd2s1CRvjaxwWp021XyCi'

3. On your server (e.g., in a Node.js environment), you can use the verifyId function to check if an ID is legitimate before using it.

import { verifyId } from 'legid';
const idFromClient = req.params.id;
// Verify with the default salt
const isValid = await verifyId(idFromClient);
// Or, if you used a custom salt on the client:
const isValidWithCustomSalt = await verifyId(idFromClient, {
  salt: 'my-app-specific-salt',
});
if (!isValidWithCustomSalt) {
  // Reject the request
  return res.status(400).send('Invalid ID');
}
// Proceed with creating the database record...

Remember that legid does not check for database collisions. Your server-side logic must still query the database to ensure the generated ID isn’t already in use before inserting a new record.

FAQs

Q: Is legid cryptographically secure?
A: No. The library is not intended for cryptographic applications. It is a deterrent designed to make casual ID manipulation difficult, not to secure sensitive data against a dedicated attacker.

Q: If the salt is public, what’s its purpose?
A: The salt is used to prevent rainbow table attacks. By adding a unique prefix to the value being hashed, it ensures that pre-computed hash tables cannot be used to find collisions for your specific application.

Q: How should I handle ID collisions?
A: You must handle collisions in your database. legid helps prevent maliciously crafted IDs but does not guarantee global uniqueness. Always wrap your database insertion logic in a way that can catch and handle unique constraint violations, perhaps by retrying with a new ID.

Q: Why is the ID length described as “approximate”?
A: This is due to the base conversion from hexadecimal (base-16) to the library’s custom base-62 alphabet. The final string length is not perfectly one-to-one with the internal hex length, so approximateLength is used to guide the generation process.

Q: Can I use this for session tokens or authentication?
A: No, Legid is designed for resource identifiers, not security tokens. The SHA-1 hash and base-62 encoding aren’t suitable for authentication purposes. Use proper JWT or similar tokens for authentication.

Q: Why SHA-1 instead of SHA-256?
A: SHA-1 provides sufficient security for this use case while being faster and producing shorter hashes. Since the library is not storing passwords or creating digital signatures, SHA-1’s collision resistance is adequate for preventing casual manipulation.

You Might Be Interested In:


Leave a Reply