Password Strength & Vulnerability Checker
Project Information
- Category: Cybersecurity Tool
- Technologies: JavaScript, HTML5, CSS3
- Date: November 2025
- Project Type: Web Application
- Live Demo: Try it now →
Comprehensive Security Analysis Tool
A professional password security analyzer that evaluates password strength using real-world data from NordPass's 2025 breach database. The tool performs 8 comprehensive security checks and includes a secure password generator.
Key Features
- Real-time strength analysis with visual feedback
- Detection against 200+ common passwords from recent breaches
- Pattern recognition (sequential, keyboard, substitutions)
- Vulnerability identification with educational messages
- Secure password generator with customizable options
- Crack time estimation for brute-force attacks
- Clean, professional UI without AI-generated elements
HTML Structure (password_checker.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Password Strength & Vulnerability Checker</title>
<link rel="stylesheet" href="password_checker.css">
</head>
<body>
<div class="container">
<h1>PASSWORD STRENGTH & VULNERABILITY CHECKER</h1>
<div class="input-section">
<h2>CHECK YOUR PASSWORD</h2>
<div class="password-input-wrapper">
<input type="password" id="password" placeholder="Enter your password">
<span class="toggle-password" id="togglePassword" onclick="togglePassword()">Show</span>
</div>
<div class="strength-meter">
<div class="strength-bar" id="strengthBar"></div>
</div>
<p class="strength-text" id="strengthText">Enter a password to check its strength</p>
</div>
<div class="checks-section">
<h2>SECURITY CHECKS</h2>
<div class="check-item" id="lengthCheck">
<span class="check-icon">○</span>
<span>At least 8 characters</span>
</div>
<div class="check-item" id="uppercaseCheck">
<span class="check-icon">○</span>
<span>Contains uppercase letters</span>
</div>
<div class="check-item" id="lowercaseCheck">
<span class="check-icon">○</span>
<span>Contains lowercase letters</span>
</div>
<div class="check-item" id="numberCheck">
<span class="check-icon">○</span>
<span>Contains numbers</span>
</div>
<div class="check-item" id="specialCheck">
<span class="check-icon">○</span>
<span>Contains special characters</span>
</div>
<div class="check-item" id="commonCheck">
<span class="check-icon">○</span>
<span>Not a common password</span>
</div>
<div class="check-item" id="sequentialCheck">
<span class="check-icon">○</span>
<span>No sequential characters</span>
</div>
<div class="check-item" id="repeatCheck">
<span class="check-icon">○</span>
<span>No repeated characters</span>
</div>
</div>
<div class="generator-section">
<h2>PASSWORD GENERATOR</h2>
<div class="generator-controls">
<div class="slider-control">
<label>Length: <span id="lengthValue">16</span></label>
<input type="range" id="lengthSlider" min="8" max="32" value="16">
</div>
<div class="checkbox-group">
<label><input type="checkbox" id="includeUppercase" checked> Uppercase</label>
<label><input type="checkbox" id="includeLowercase" checked> Lowercase</label>
<label><input type="checkbox" id="includeNumbers" checked> Numbers</label>
<label><input type="checkbox" id="includeSpecial" checked> Special Characters</label>
</div>
</div>
<button onclick="generatePassword()">Generate Password</button>
<div class="generated-password-container" id="generatedPasswordContainer" style="display: none;">
<div class="generated-password" id="generatedPassword"></div>
<button class="copy-btn" onclick="copyGeneratedPassword()">Copy to Clipboard</button>
</div>
</div>
<div class="vulnerabilities-section" id="vulnerabilitiesSection">
<h2>VULNERABILITIES DETECTED</h2>
<div id="vulnerabilitiesList"></div>
</div>
<div class="info-section">
<h2>PASSWORD SECURITY TIPS</h2>
<ul>
<li>Use a unique password for each account</li>
<li>Avoid personal information (names, birthdays, addresses)</li>
<li>Use a password manager to store complex passwords</li>
<li>Enable two-factor authentication when available</li>
<li>Change passwords regularly, especially after breaches</li>
</ul>
</div>
</div>
<script src="password_checker.js"></script>
</body>
</html>
JavaScript Logic (password_checker.js) - Part 1
// Common passwords list - NordPass Top 200 Most Common Passwords (2025)
const commonPasswords = [
'123456', 'admin', '12345678', '123456789', '1234', 'password', 'Aa123456',
'1234567890', 'Pass@123', 'admin123', '1234567', '123123', '111111',
'123456789', 'P@ssw0rd', 'Password', 'Aa@123456', 'admintelecom', 'Admin@123',
'112233', '102030', '654321', 'abcd1234', 'abc123', 'qwerty123', 'Abcd@1234',
'Pass@1234', '1qaz2wsx', 'qwerty', 'password123', '1q2w3e4r', 'qwertyuiop',
'1q2w3e', 'Abcd1234', 'P@ssw0rd123', 'google', 'P@ssword', '123qwe', 'aa123456',
'secret', 'welcome', 'monkey', 'dragon', '111111111', 'superman', 'iloveyou',
'master', 'sunshine', 'ashley', 'bailey', 'passw0rd', 'shadow', 'qazwsx',
'michael', 'football', 'welcome', 'jesus', 'ninja', 'mustang', 'password1',
'adobe123', 'azerty', 'loveme', 'whatever', 'donald', 'batman', 'computer',
'starwars', 'summer', 'princess', 'qwertyuiop', 'solo', 'lakers', 'hunter',
'flower', 'hottie', 'freedom', 'andrew', 'chocolate', 'jordan', 'michelle',
'liverpool', 'cheese', 'letmein', 'trustno1', 'baseball', '000000', '1111',
'2222', '3333', '4444', '5555', '6666', '7777', '8888', '9999', 'aaaaaa',
'abc123456', 'access', 'admin1', 'admin12', 'admin123', 'administrator',
'asd123', 'asdf', 'asdfgh', 'asdfghjkl', 'backup', 'charlie', 'cheese',
'demo', 'killer', 'letmein', 'login', 'master', 'monkey123', 'passw0rd',
'passwd', 'password1234', 'picture1', 'princess', 'qazwsx123', 'root',
'sample', 'security', 'super', 'superuser', 'superman', 'support',
'temp', 'temp123', 'test', 'test123', 'testing', 'trustno1', 'user',
'welcome123', 'zxcvbnm', 'football', 'baseball', 'basketball', 'soccer',
'hockey', 'tennis', 'golf', 'cricket', 'matrix', 'abcdef', 'a1b2c3',
'1a2b3c', '123abc', '123321', '121212', '111222', '222333', 'qwe123',
'asd123', 'zxc123', '1q2w3e4r5t', 'qwer1234', 'pass123', '123pass',
'temp1234', 'admin1234', 'test1234', 'guest', 'guest123', 'user123',
'default', 'changeme', 'password!', 'Password1', 'Password123', 'P@ssw0rd!',
'Welcome1', 'Welcome123', 'Welcome@123', 'Admin1', 'Admin123!', 'Root123',
'silver', 'diamond', 'golden', 'purple', 'orange', 'yellow', 'green',
'qweasd', 'qweasdzxc', 'zaq12wsx', 'xsw23edc', 'cde34rfv', 'pakistan123',
'skibidi', 'assword', 'india123'
];
// Dictionary words to check against
const commonWords = [
'love', 'hate', 'good', 'best', 'work', 'life', 'home', 'time', 'year',
'user', 'admin', 'test', 'demo', 'temp', 'pass', 'word', 'secret', 'login'
];
// Common names database
const commonNames = [
'michael', 'david', 'john', 'james', 'robert', 'mary', 'jennifer', 'lisa',
'sarah', 'karen', 'jessica', 'daniel', 'matthew', 'chris', 'ashley', 'emily',
'emma', 'olivia', 'sophia', 'william', 'benjamin', 'alexander', 'thomas'
];
// Pet names
const petNames = [
'buddy', 'max', 'charlie', 'bella', 'lucy', 'daisy', 'molly', 'bailey',
'maggie', 'sophie', 'jack', 'rocky', 'duke', 'bear', 'toby', 'zeus'
];
// Animal names
const animalNames = [
'dog', 'cat', 'tiger', 'lion', 'bear', 'wolf', 'eagle', 'hawk', 'panda',
'bunny', 'rabbit', 'kitten', 'puppy', 'horse', 'dragon', 'phoenix', 'unicorn'
];
// Sports teams
const sportsTeams = [
'lakers', 'yankees', 'cowboys', 'patriots', 'celtics', 'bulls', 'giants',
'packers', 'steelers', 'eagles', 'warriors', 'heat', 'knicks', 'dodgers',
'redsox', 'liverpool', 'arsenal', 'chelsea', 'united', 'barcelona', 'madrid'
];
// Pop culture references
const popCulture = [
'starwars', 'batman', 'superman', 'spiderman', 'ironman', 'avengers',
'pokemon', 'minecraft', 'fortnite', 'zelda', 'mario', 'sonic', 'gameofthrones',
'harrypotter', 'disney', 'marvel', 'netflix', 'spotify', 'youtube'
];
// Common foods
const foods = [
'pizza', 'burger', 'coffee', 'chocolate', 'cookie', 'cheese', 'apple',
'banana', 'orange', 'strawberry', 'chicken', 'bacon', 'taco', 'sushi'
];
// Common places
const places = [
'paris', 'london', 'newyork', 'tokyo', 'miami', 'vegas', 'california',
'texas', 'florida', 'chicago', 'boston', 'seattle', 'atlanta'
];
// School/mascots
const schools = [
'eagles', 'tigers', 'bulldogs', 'wildcats', 'panthers', 'raiders',
'mustangs', 'vikings', 'spartans', 'trojans', 'warriors', 'knights'
];
// Car models
const cars = [
'ford', 'chevy', 'honda', 'toyota', 'bmw', 'tesla', 'mustang',
'camaro', 'corvette', 'civic', 'accord', 'mazda', 'nissan'
];
// Slang/common words
const slangWords = [
'cool', 'awesome', 'super', 'great', 'dude', 'buddy', 'boss',
'chief', 'king', 'queen', 'legend', 'rockstar', 'ninja', 'master'
];
const passwordInput = document.getElementById('password');
let lastGeneratedPassword = '';
passwordInput.addEventListener('input', function() {
const password = this.value;
analyzePassword(password);
});
// Update length slider value display
document.getElementById('lengthSlider').addEventListener('input', function() {
document.getElementById('lengthValue').textContent = this.value;
});
function togglePassword() {
const input = document.getElementById('password');
const icon = document.getElementById('togglePassword');
if (input.type === 'password') {
input.type = 'text';
icon.textContent = 'Hide';
} else {
input.type = 'password';
icon.textContent = 'Show';
}
}
JavaScript Logic (password_checker.js) - Part 2
function analyzePassword(password) {
// Initialize checks
const checks = {
length: password.length >= 8,
uppercase: /[A-Z]/.test(password),
lowercase: /[a-z]/.test(password),
number: /[0-9]/.test(password),
special: /[!@#$%^&*(),.?":{}|<>]/.test(password),
common: !isCommonPassword(password),
sequential: !hasSequentialChars(password),
repeat: !hasRepeatedChars(password)
};
// Update check items
updateCheckItem('lengthCheck', checks.length);
updateCheckItem('uppercaseCheck', checks.uppercase);
updateCheckItem('lowercaseCheck', checks.lowercase);
updateCheckItem('numberCheck', checks.number);
updateCheckItem('specialCheck', checks.special);
updateCheckItem('commonCheck', checks.common);
updateCheckItem('sequentialCheck', checks.sequential);
updateCheckItem('repeatCheck', checks.repeat);
// Calculate strength
const passedChecks = Object.values(checks).filter(v => v).length;
let strength = 0;
let strengthText = '';
let strengthColor = '';
if (password.length === 0) {
strengthText = 'Enter a password to check its strength';
strengthColor = '#ddd';
} else if (passedChecks <= 3) {
strength = 20;
strengthText = 'Very Weak';
strengthColor = '#d32f2f';
} else if (passedChecks <= 4) {
strength = 40;
strengthText = 'Weak';
strengthColor = '#f57c00';
} else if (passedChecks <= 6) {
strength = 60;
strengthText = 'Fair';
strengthColor = '#fbc02d';
} else if (passedChecks <= 7) {
strength = 80;
strengthText = 'Strong';
strengthColor = '#7cb342';
} else {
strength = 100;
strengthText = 'Excellent';
strengthColor = '#388e3c';
}
// Update strength meter
const strengthBar = document.getElementById('strengthBar');
const strengthTextElement = document.getElementById('strengthText');
strengthBar.style.width = strength + '%';
strengthBar.style.backgroundColor = strengthColor;
strengthTextElement.textContent = strengthText;
strengthTextElement.style.color = strengthColor;
// Show crack time estimate
if (password.length > 0) {
const crackTime = estimateCrackTime(password);
strengthTextElement.textContent += ` - ${crackTime}`;
}
// Check for vulnerabilities
if (password.length > 0) {
displayVulnerabilities(password);
} else {
document.getElementById('vulnerabilitiesSection').style.display = 'none';
}
}
function updateCheckItem(id, passed) {
const item = document.getElementById(id);
const icon = item.querySelector('.check-icon');
if (passed) {
item.classList.add('passed');
icon.textContent = '✓';
} else {
item.classList.remove('passed');
icon.textContent = '○';
}
}
function isCommonPassword(password) {
const lowerPassword = password.toLowerCase();
// Check against common passwords
if (commonPasswords.some(common => lowerPassword === common.toLowerCase())) {
return true;
}
// Check if it's only numbers
if (/^\d+$/.test(password)) {
return true;
}
// Check against dictionary words
if (commonWords.some(word => lowerPassword.includes(word))) {
return true;
}
// Check against names
if (commonNames.some(name => lowerPassword.includes(name))) {
return true;
}
// Check against pet names
if (petNames.some(name => lowerPassword.includes(name))) {
return true;
}
// Check against animal names
if (animalNames.some(name => lowerPassword.includes(name))) {
return true;
}
// Check against sports teams
if (sportsTeams.some(team => lowerPassword.includes(team))) {
return true;
}
// Check against pop culture
if (popCulture.some(ref => lowerPassword.includes(ref))) {
return true;
}
// Check against foods
if (foods.some(food => lowerPassword.includes(food))) {
return true;
}
// Check against places
if (places.some(place => lowerPassword.includes(place))) {
return true;
}
// Check against schools
if (schools.some(school => lowerPassword.includes(school))) {
return true;
}
// Check against cars
if (cars.some(car => lowerPassword.includes(car))) {
return true;
}
// Check against slang
if (slangWords.some(slang => lowerPassword.includes(slang))) {
return true;
}
// Check for keyboard patterns
const keyboardPatterns = ['qwerty', 'asdf', 'zxcv', '1qaz2wsx', 'qwertyuiop'];
if (keyboardPatterns.some(pattern => lowerPassword.includes(pattern))) {
return true;
}
return false;
}
function hasSequentialChars(password) {
// Check for sequential numbers (123, 234, etc.)
for (let i = 0; i < password.length - 2; i++) {
const char1 = password.charCodeAt(i);
const char2 = password.charCodeAt(i + 1);
const char3 = password.charCodeAt(i + 2);
if (char2 === char1 + 1 && char3 === char2 + 1) {
return true;
}
}
return false;
}
function hasRepeatedChars(password) {
// Check for 3 or more repeated characters
return /(.)\1{2,}/.test(password);
}
function estimateCrackTime(password) {
let charsetSize = 0;
if (/[a-z]/.test(password)) charsetSize += 26;
if (/[A-Z]/.test(password)) charsetSize += 26;
if (/[0-9]/.test(password)) charsetSize += 10;
if (/[^a-zA-Z0-9]/.test(password)) charsetSize += 32;
const combinations = Math.pow(charsetSize, password.length);
const guessesPerSecond = 1000000000; // 1 billion guesses per second
const seconds = combinations / guessesPerSecond;
if (seconds < 1) return "Less than a second to crack";
if (seconds < 60) return Math.round(seconds) + " seconds to crack";
if (seconds < 3600) return Math.round(seconds / 60) + " minutes to crack";
if (seconds < 86400) return Math.round(seconds / 3600) + " hours to crack";
if (seconds < 31536000) return Math.round(seconds / 86400) + " days to crack";
if (seconds < 3153600000) return Math.round(seconds / 31536000) + " years to crack";
return "Centuries to crack";
}
JavaScript Logic (password_checker.js) - Part 3
function displayVulnerabilities(password) {
const vulnerabilities = findVulnerabilities(password);
const section = document.getElementById('vulnerabilitiesSection');
const list = document.getElementById('vulnerabilitiesList');
if (vulnerabilities.length > 0) {
section.style.display = 'block';
list.innerHTML = vulnerabilities.map(v => `
${v.type}: ${v.message}
`).join('');
} else {
section.style.display = 'none';
}
}
function findVulnerabilities(password) {
const vulnerabilities = [];
const lowerPassword = password.toLowerCase();
// Check if password is only numbers (like a phone number or date)
if (/^\d+$/.test(password)) {
vulnerabilities.push({
type: 'Numbers Only',
message: 'Your password contains only numbers. This makes it vulnerable to brute-force attacks. Add letters and special characters.'
});
// Check for phone number patterns
if (password.length === 10 || password.length === 11) {
vulnerabilities.push({
type: 'Possible Phone Number',
message: 'This looks like a phone number. Phone numbers are easily guessable and should never be used as passwords.'
});
}
// Check for date patterns
if (password.length === 8 && password.match(/^\d{8}$/)) {
vulnerabilities.push({
type: 'Possible Date',
message: 'This might be a date (like a birthday). Dates are common and easily guessable.'
});
}
}
// Check for keyboard patterns
const keyboardPatterns = [
{ pattern: 'qwerty', name: 'QWERTY keyboard pattern' },
{ pattern: 'asdf', name: 'ASDF keyboard pattern' },
{ pattern: 'zxcv', name: 'ZXCV keyboard pattern' },
{ pattern: '1qaz2wsx', name: 'Vertical keyboard pattern' },
{ pattern: 'qwertyuiop', name: 'Top row keyboard pattern' }
];
keyboardPatterns.forEach(kb => {
if (lowerPassword.includes(kb.pattern)) {
vulnerabilities.push({
type: 'Keyboard Pattern',
message: `Contains "${kb.name}" which is easy to guess.`
});
}
});
// Check for common substitutions
const substitutions = detectCleverSubstitutions(password);
if (substitutions.length > 0) {
vulnerabilities.push({
type: 'Common Substitutions',
message: `Uses predictable character substitutions: ${substitutions.join(', ')}. Hackers' tools check for these patterns.`
});
}
// Check against common password databases
if (commonPasswords.some(common => lowerPassword === common.toLowerCase())) {
vulnerabilities.push({
type: 'Common Password',
message: 'This password appears in the NordPass 2025 list of most common passwords found in data breaches.'
});
}
// Check for names
const foundNames = commonNames.filter(name => lowerPassword.includes(name));
if (foundNames.length > 0) {
vulnerabilities.push({
type: 'Contains Name',
message: `Contains the common name "${foundNames[0]}". Personal information is easy to guess.`
});
}
// Check for pet names
const foundPetNames = petNames.filter(name => lowerPassword.includes(name));
if (foundPetNames.length > 0) {
vulnerabilities.push({
type: 'Pet Name',
message: `Contains "${foundPetNames[0]}" which is a common pet name. Avoid using pet names.`
});
}
// Check for sports teams
const foundTeams = sportsTeams.filter(team => lowerPassword.includes(team));
if (foundTeams.length > 0) {
vulnerabilities.push({
type: 'Sports Team',
message: `Contains "${foundTeams[0]}" sports team name. Team names are commonly used and easily guessed.`
});
}
// Check for pop culture
const foundPopCulture = popCulture.filter(ref => lowerPassword.includes(ref));
if (foundPopCulture.length > 0) {
vulnerabilities.push({
type: 'Pop Culture Reference',
message: `Contains "${foundPopCulture[0]}". Pop culture references are popular but predictable password choices.`
});
}
// Check for foods
const foundFoods = foods.filter(food => lowerPassword.includes(food));
if (foundFoods.length > 0) {
vulnerabilities.push({
type: 'Food Name',
message: `Contains "${foundFoods[0]}". Food names are common password components.`
});
}
// Check for places
const foundPlaces = places.filter(place => lowerPassword.includes(place));
if (foundPlaces.length > 0) {
vulnerabilities.push({
type: 'Location Name',
message: `Contains "${foundPlaces[0]}". Location names are frequently used in passwords.`
});
}
// Check for car brands/models
const foundCars = cars.filter(car => lowerPassword.includes(car));
if (foundCars.length > 0) {
vulnerabilities.push({
type: 'Car Brand/Model',
message: `Contains "${foundCars[0]}". Car-related words are common in weak passwords.`
});
}
return vulnerabilities;
}
function detectCleverSubstitutions(password) {
const substitutions = [];
const commonSubs = {
'@': 'a', '4': 'a', '3': 'e', '1': 'i', '!': 'i',
'0': 'o', '$': 's', '7': 't', '+': 't', '5': 's'
};
for (const [symbol, letter] of Object.entries(commonSubs)) {
if (password.includes(symbol)) {
substitutions.push(`${symbol} for ${letter}`);
}
}
return substitutions;
}
function generatePassword() {
const length = parseInt(document.getElementById('lengthSlider').value);
const includeUppercase = document.getElementById('includeUppercase').checked;
const includeLowercase = document.getElementById('includeLowercase').checked;
const includeNumbers = document.getElementById('includeNumbers').checked;
const includeSpecial = document.getElementById('includeSpecial').checked;
let charset = '';
if (includeUppercase) charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (includeLowercase) charset += 'abcdefghijklmnopqrstuvwxyz';
if (includeNumbers) charset += '0123456789';
if (includeSpecial) charset += '!@#$%^&*()_+-=[]{}|;:,.<>?';
if (charset === '') {
alert('Please select at least one character type');
return;
}
let password = '';
const array = new Uint32Array(length);
crypto.getRandomValues(array);
for (let i = 0; i < length; i++) {
password += charset[array[i] % charset.length];
}
lastGeneratedPassword = password;
document.getElementById('generatedPassword').textContent = password;
document.getElementById('generatedPasswordContainer').style.display = 'block';
// Auto-analyze the generated password
document.getElementById('password').value = password;
analyzePassword(password);
}
function copyGeneratedPassword() {
const password = lastGeneratedPassword;
navigator.clipboard.writeText(password).then(() => {
const btn = event.target;
const originalText = btn.textContent;
btn.textContent = 'Copied!';
btn.style.backgroundColor = '#28a745';
setTimeout(() => {
btn.textContent = originalText;
btn.style.backgroundColor = '';
}, 2000);
});
}