Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Password policy testing evaluates the strength requirements enforced by an application during password creation and change. Weak policies allow users to create easily guessable passwords, making accounts vulnerable to brute-force and dictionary attacks. This test examines minimum length, complexity requirements, and protection against common weak passwords.
#!/bin/bash# Test password complexity requirements# Test passwords with different complexity
passwords=(
"password"# lowercase only"PASSWORD"# uppercase only"12345678"# numbers only"!!!!!!!!!"# symbols only"Password"# mixed case"password1"# lowercase + numbers"Password1"# mixed case + numbers"Password1!"# all complexity
)
for password in"${passwords[@]}"; do
response=$(curl -s -X POST "https://target.com/api/change-password" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"current_password\": \"OldPassword123!\",
\"new_password\": \"$password\"
}")
echo"$password: $response" | head -c 100
echo""done
Step 3: Test Common Passwords
#!/bin/bash# Test if common passwords are blocked
common_passwords=(
"password""password123""123456""12345678""qwerty""abc123""letmein""welcome""admin""iloveyou""monkey""dragon""master""123456789""Password1!"
)
for password in"${common_passwords[@]}"; do
response=$(curl -s -X POST "https://target.com/api/change-password" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"current_password\": \"OldPassword123!\",
\"new_password\": \"$password\"
}")
ifecho"$response" | grep -qi "success"; thenecho"[WEAK] Accepted common password: $password"elseecho"[OK] Rejected: $password"fidone
Step 4: Test Personal Information in Password
# Test if password can contain username or email
username="johndoe"
email="john.doe@example.com"
test_passwords=(
"${username}123!""${username}Password""Password${username}""john.doe123""johndoe2024"
)
for password in"${test_passwords[@]}"; do
response=$(curl -s -X POST "https://target.com/api/change-password" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"new_password\": \"$password\"
}")
echo"$password: $response" | head -c 100
echo""done
Step 5: Test Password History
#!/bin/bash# Test if previous passwords can be reused
original_password="OldPassword123!"
new_password="NewPassword456!"# Change password
curl -s -X POST "https://target.com/api/change-password" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"current_password\": \"$original_password\",
\"new_password\": \"$new_password\"
}"# Try to change back to original
response=$(curl -s -X POST "https://target.com/api/change-password" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"current_password\": \"$new_password\",
\"new_password\": \"$original_password\"
}")
ifecho"$response" | grep -qi "success"; thenecho"[WEAK] Password reuse allowed"elseecho"[OK] Password reuse prevented"fi
Step 6: Test Maximum Length
# Test maximum password length# Some systems truncate long passwords silently
lengths=(64 128 256 512 1024)
for len in"${lengths[@]}"; do
password=$(head -c $len < /dev/urandom | base64 | head -c $len)
response=$(curl -s -X POST "https://target.com/api/change-password" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"current_password\": \"OldPassword123!\",
\"new_password\": \"$password\"
}" \
-w "\nStatus: %{http_code}")
echo"Length $len: $(echo "$response" | tail -1)"done# Test if long password is truncated# Set very long password, then try to login with truncated version
Step 7: Test Registration Password Policy
# Test password policy during registration# May differ from change password policy
test_passwords=(
"123""password""test""abc123""Password1""Str0ngP@ssw0rd!"
)
for password in"${test_passwords[@]}"; do
response=$(curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d "{
\"username\": \"testuser$(date +%s)\",
\"email\": \"test$(date +%s)@example.com\",
\"password\": \"$password\"
}")
echo"$password: $response" | head -c 100
echo""done
Tools
Password Testing
Tool
Description
Usage
Burp Intruder
Payload testing
Test password variations
Custom scripts
Automated testing
Systematic policy testing
SecLists
Common passwords
Wordlist testing
Password Analysis
Tool
Description
zxcvbn
Password strength meter
Have I Been Pwned
Compromised password check
Example Commands/Payloads
Password Policy Tester
#!/usr/bin/env python3import requests
import string
import random
classPasswordPolicyTester:
def__init__(self, base_url, token):
self.base_url = base_url
self.headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
self.results = {}
deftry_password(self, password, endpoint="/api/change-password"):
"""Try to set a password and check if accepted"""try:
response = requests.post(
f"{self.base_url}{endpoint}",
headers=self.headers,
json={
"current_password": "CurrentPass123!",
"new_password": password
}
)
accepted = response.status_code == 200and \
"error"notin response.text.lower() and \
"invalid"notin response.text.lower()
return accepted, response.text[:200]
except Exception as e:
returnNone, str(e)
deftest_minimum_length(self):
"""Find minimum password length"""print("[*] Testing minimum length...")
for length inrange(1, 20):
# Create password that would pass complexity if length is ok
password = "Aa1!" + "a" * (length - 4) if length >= 4else"a" * length
accepted, _ = self.try_password(password)
if accepted:
self.results["min_length"] = length
print(f" Minimum length: {length}")
return length
self.results["min_length"] = ">20"returnNonedeftest_complexity(self):
"""Test complexity requirements"""print("[*] Testing complexity requirements...")
base_length = 12# Use length that should pass length check
tests = {
"lowercase_only": "a" * base_length,
"uppercase_only": "A" * base_length,
"numbers_only": "1" * base_length,
"symbols_only": "!" * base_length,
"lower_upper": "Aa" * (base_length // 2),
"lower_number": "a1" * (base_length // 2),
"lower_upper_number": "Aa1" + "a" * (base_length - 3),
"all_types": "Aa1!" + "a" * (base_length - 4),
}
complexity_results = {}
for name, password in tests.items():
accepted, _ = self.try_password(password)
complexity_results[name] = accepted
status = "ACCEPTED"if accepted else"REJECTED"print(f" {name}: {status}")
self.results["complexity"] = complexity_results
# Determine required complexityif complexity_results.get("lowercase_only"):
self.results["min_complexity"] = "None (lowercase only accepted)"elif complexity_results.get("lower_upper"):
self.results["min_complexity"] = "Low (mixed case only)"elif complexity_results.get("lower_upper_number"):
self.results["min_complexity"] = "Medium (letters + numbers)"elif complexity_results.get("all_types"):
self.results["min_complexity"] = "High (all character types)"else:
self.results["min_complexity"] = "Very High (all types rejected?)"deftest_common_passwords(self):
"""Test common password blocking"""print("[*] Testing common password blocking...")
common = [
"password", "password123", "123456", "qwerty",
"letmein", "welcome", "admin123", "Password1!",
"iloveyou", "sunshine", "princess", "dragon"
]
blocked = 0for pwd in common:
# Add complexity if needed
test_pwd = pwd iflen(pwd) >= 8else pwd + "123!"
accepted, _ = self.try_password(test_pwd)
ifnot accepted:
blocked += 1self.results["common_blocked"] = f"{blocked}/{len(common)}"print(f" Blocked {blocked}/{len(common)} common passwords")
deftest_password_history(self):
"""Test password reuse prevention"""print("[*] Testing password history...")
# This would require actual password changes# Simplified versionself.results["password_history"] = "Requires manual testing"defgenerate_report(self):
"""Generate policy report"""print("\n" + "=" * 50)
print("PASSWORD POLICY ANALYSIS REPORT")
print("=" * 50 + "\n")
for key, value inself.results.items():
print(f"{key}: {value}")
# Security assessmentprint("\n--- SECURITY ASSESSMENT ---")
issues = []
ifisinstance(self.results.get("min_length"), int):
ifself.results["min_length"] < 8:
issues.append("Minimum length too short (< 8)")
elifself.results["min_length"] < 12:
issues.append("Consider increasing minimum to 12+")
if"lowercase_only"instr(self.results.get("min_complexity", "")):
issues.append("No complexity requirements")
ifself.results.get("common_blocked", "0/") == "0/":
issues.append("Common passwords not blocked")
if issues:
print("\nISSUES FOUND:")
for issue in issues:
print(f" - {issue}")
else:
print("\nNo major issues found.")
# Usage
tester = PasswordPolicyTester("https://target.com", "auth_token")
tester.test_minimum_length()
tester.test_complexity()
tester.test_common_passwords()
tester.generate_report()
Remediation Guide
1. Implement Strong Password Policy
import re
from zxcvbn import zxcvbn
# Common password list (use full list in production)
COMMON_PASSWORDS = {
'password', 'password123', '123456', 'qwerty',
'letmein', 'welcome', 'admin', 'admin123'
}
classPasswordValidator:
MIN_LENGTH = 12
MAX_LENGTH = 128
HISTORY_COUNT = 10defvalidate(self, password, user=None):
"""Validate password against policy"""
errors = []
# Length checkiflen(password) < self.MIN_LENGTH:
errors.append(f"Password must be at least {self.MIN_LENGTH} characters")
iflen(password) > self.MAX_LENGTH:
errors.append(f"Password cannot exceed {self.MAX_LENGTH} characters")
# Complexity checkifnot re.search(r'[a-z]', password):
errors.append("Password must contain lowercase letters")
ifnot re.search(r'[A-Z]', password):
errors.append("Password must contain uppercase letters")
ifnot re.search(r'\d', password):
errors.append("Password must contain numbers")
ifnot re.search(r'[!@#$%^&*(),.?":{}|<>]', password):
errors.append("Password must contain special characters")
# Common password checkif password.lower() in COMMON_PASSWORDS:
errors.append("This password is too common")
# Personal info checkif user:
if user.username.lower() in password.lower():
errors.append("Password cannot contain username")
if user.email.split('@')[0].lower() in password.lower():
errors.append("Password cannot contain email")
# Strength check using zxcvbn
result = zxcvbn(password)
if result['score'] < 3:
errors.append(f"Password is too weak: {result['feedback']['warning']}")
return errors
defcheck_history(self, user, new_password):
"""Check against password history"""for old_hash in user.password_history[-self.HISTORY_COUNT:]:
if check_password_hash(old_hash, new_password):
returnFalsereturnTrue
2. Integrate HaveIBeenPwned
import hashlib
import requests
defcheck_pwned_password(password):
"""Check if password has been compromised"""
sha1_hash = hashlib.sha1(password.encode()).hexdigest().upper()
prefix = sha1_hash[:5]
suffix = sha1_hash[5:]
response = requests.get(
f'https://api.pwnedpasswords.com/range/{prefix}',
headers={'Add-Padding': 'true'}
)
if response.status_code == 200:
hashes = response.text.split('\n')
for hash_line in hashes:
parts = hash_line.split(':')
if parts[0] == suffix:
returnint(parts[1]) # Number of times seenreturn0# Usage in validationdefvalidate_password(password):
pwned_count = check_pwned_password(password)
if pwned_count > 0:
returnf"This password has been seen in {pwned_count} data breaches"returnNone