Skip to main content Skills Marketplace Discover and explore AI skills built by the community.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Copy promptShow prompt details A direct command skips the review prompt. Inspect the source before running it.
npx skills add https://github.com/CyberStrikeus/CyberStrike --skill wstg-idnt-05The command stays on one line. Scroll horizontally to inspect it before copying.
Prefer a local copy? Download the files currently available to SkillsMP.
Download Zip Downloading... name wstg-idnt-05 description Test Username Policy category identity-management owasp_id WSTG-IDNT-05 version 1.0.0 author cyberstrike-official tags ["identity","user-enum","roles","wstg","idnt"] tech_stack [] cwe_ids [] chains_with [] prerequisites [] severity_boost {}
wstg-idnt-05
Test ID
WSTG-IDNT-05
Test Name
Testing for Weak or Unenforced Username Policy
High-Level Description
Username policy testing evaluates the rules and restrictions applied to username creation and management. Weak username policies can lead to account enumeration, impersonation attacks, and user confusion. This test examines whether the application enforces appropriate restrictions on username format, length, allowed characters, and uniqueness while preventing predictable or malicious usernames.
What to Check
Username Policy Elements
Security Considerations
Aspect Risk Predictable usernames Account enumeration Similar usernames User confusion/impersonation No reserved words Admin impersonation Case insensitive Duplicate accounts Special chars allowed XSS/Injection
How to Test
Step 1: Test Username Length Limits
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d '{
"username": "a",
"email": "short1@test.com",
"password": "TestPass123!"
}'
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d '{
"username": "ab",
"email": "short2@test.com",
"password": "TestPass123!"
}'
curl -s -X POST \
-H \
-d $(python3 -c )) ,
: ,
:
} {
:
"https://target.com/api/register"
"Content-Type: application/json"
'{
"username": "'
"print('a'*100)"
'"'
"email"
"long1@test.com"
"password"
"TestPass123!"
'
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d '
"username"
"'$(python3 -c "print('a'*1000)" ) )'"
',
"email": "long2@test.com",
"password": "TestPass123!"
}'
Step 2: Test Reserved/Restricted Usernames #!/bin/bash
RESERVED_NAMES=(
"admin" "administrator" "root" "system"
"support" "help" "info" "security"
"moderator" "mod" "staff" "official"
"webmaster" "postmaster" "hostmaster"
"null" "undefined" "anonymous" "guest"
"api" "www" "mail" "ftp" "smtp"
)
for name in "${RESERVED_NAMES[@]} " ; do
response=$(curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d "{
\"username\": \"$name \",
\"email\": \"${name} @test.com\",
\"password\": \"TestPass123!\"
}" )
echo "$name : $response "
done
Step 3: Test Case Sensitivity
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d '{
"username": "testuser",
"email": "case1@test.com",
"password": "TestPass123!"
}'
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d '{
"username": "TestUser",
"email": "case2@test.com",
"password": "TestPass123!"
}'
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d '{
"username": "TESTUSER",
"email": "case3@test.com",
"password": "TestPass123!"
}'
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d '{
"username": "tEsTuSeR",
"email": "case4@test.com",
"password": "TestPass123!"
}'
Step 4: Test Special Characters #!/bin/bash
SPECIAL_CHARS=(
"test<script>"
"test'user"
"test\"user"
"test;user"
"test--user"
"test/*user"
"test../user"
"test%00user"
"test\nuser"
"test\tuser"
"test user"
"test@user"
"test#user"
"test&user"
"test=user"
"test+user"
)
for username in "${SPECIAL_CHARS[@]} " ; do
response=$(curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d "{
\"username\": \"$username \",
\"email\": \"special$(date +%s) @test.com\",
\"password\": \"TestPass123!\"
}" 2>/dev/null)
echo "Testing: $username "
echo "Response: $response "
echo "---"
done
Step 5: Test Unicode/Homograph Attacks
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d '{
"username": "аdmin",
"email": "unicode1@test.com",
"password": "TestPass123!"
}'
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d '{
"username": "ɑdmin",
"email": "unicode2@test.com",
"password": "TestPass123!"
}'
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d '{
"username": "admin\u200b",
"email": "unicode3@test.com",
"password": "TestPass123!"
}'
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d '{
"username": "admin\u00a0",
"email": "unicode4@test.com",
"password": "TestPass123!"
}'
Step 6: Test Similar Username Prevention
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d '{
"username": "company-admin",
"email": "similar1@test.com",
"password": "TestPass123!"
}'
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d '{
"username": "company.admin",
"email": "similar2@test.com",
"password": "TestPass123!"
}'
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d '{
"username": "companyadmin",
"email": "similar3@test.com",
"password": "TestPass123!"
}'
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d '{
"username": "company__admin",
"email": "similar4@test.com",
"password": "TestPass123!"
}'
Step 7: Test Numeric/Sequential Usernames
for num in 1 12 123 1234 12345; do
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d "{
\"username\": \"$num \",
\"email\": \"num$num @test.com\",
\"password\": \"TestPass123!\"
}"
done
for user in user1 user2 user3 test1 test2 test3; do
curl -s -X POST "https://target.com/api/register" \
-H "Content-Type: application/json" \
-d "{
\"username\": \"$user \",
\"email\": \"$user @test.com\",
\"password\": \"TestPass123!\"
}"
done
Tools
Manual Testing Tool Description Usage Burp Suite Request manipulation Test various username formats curl Command-line HTTP Scripted testing Unicode tools Character lookup Homograph testing
Automated Testing Tool Description Burp Intruder Fuzzing usernames Custom scripts Comprehensive testing Regex testers Validate patterns
Example Commands/Payloads
Username Policy Test Payloads # Length tests
a
ab
abc
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa (very long)
# Reserved names
admin
administrator
root
system
support
null
undefined
# Case variations
Admin
ADMIN
aDmIn
# Special characters
user<script>
user'test
user"test
user;test
user--test
user/../admin
user%00admin
# Unicode/Homograph
аdmin (Cyrillic a)
ɑdmin (Latin alpha)
admin (zero-width space)
admin (with invisible chars)
# Similar patterns
company_admin
company-admin
company.admin
companyadmin
# Numeric
123456
user123
1user
Comprehensive Policy Tester
import requests
import json
import unicodedata
class UsernamePolicyTester :
def __init__ (self, register_url ):
self .url = register_url
self .results = []
def test_username (self, username, description ):
"""Test a single username"""
try :
response = requests.post(
self .url,
json={
"username" : username,
"email" : f"test_{hash (username)} @test.com" ,
"password" : "TestPass123!"
},
timeout=10
)
result = {
"username" : username,
"description" : description,
"status" : response.status_code,
"accepted" : response.status_code in [200 , 201 ],
"response" : response.text[:200 ]
}
except Exception as e:
result = {
"username" : username,
"description" : description,
"error" : str (e)
}
self .results.append(result)
return result
def run_all_tests (self ):
"""Run comprehensive policy tests"""
self .test_username("a" , "1 character" )
self .test_username("ab" , "2 characters" )
self .test_username("abc" , "3 characters" )
self .test_username("a" * 50 , "50 characters" )
self .test_username("a" * 100 , "100 characters" )
self .test_username("a" * 500 , "500 characters" )
reserved = ["admin" , "administrator" , "root" , "system" ,
"support" , "null" , "undefined" , "api" , "www" ]
for name in reserved:
self .test_username(name, f"Reserved: {name} " )
self .test_username("TestCase" , "Mixed case" )
self .test_username("testcase" , "Lower case" )
self .test_username("TESTCASE" , "Upper case" )
specials = [
("test<tag>" , "HTML tag" ),
("test'quote" , "Single quote" ),
("test\"quote" , "Double quote" ),
("test;semi" , "Semicolon" ),
("test--sql" , "SQL comment" ),
("test../path" , "Path traversal" ),
("test user" , "Space" ),
("test\tuser" , "Tab" ),
]
for username, desc in specials:
self .test_username(username, desc)
self .test_username("аdmin" , "Cyrillic 'a'" )
self .test_username("admin\u200b" , "Zero-width space" )
self .test_username("admin\u00a0" , "Non-breaking space" )
self .test_username("123456" , "Pure numeric" )
self .test_username("user123" , "Alphanumeric" )
return self .results
def print_report (self ):
"""Print test results"""
print ("\n=== USERNAME POLICY TEST RESULTS ===\n" )
accepted = [r for r in self .results if r.get("accepted" )]
rejected = [r for r in self .results if not r.get("accepted" ) and "error" not in r]
errors = [r for r in self .results if "error" in r]
print (f"Accepted: {len (accepted)} " )
print (f"Rejected: {len (rejected)} " )
print (f"Errors: {len (errors)} " )
print ("\n--- ACCEPTED (Potential Issues) ---" )
for r in accepted:
print (f" {r['description' ]} : {r['username' ][:30 ]} " )
print ("\n--- REJECTED (Expected) ---" )
for r in rejected:
print (f" {r['description' ]} : {r['username' ][:30 ]} " )
tester = UsernamePolicyTester("https://target.com/api/register" )
tester.run_all_tests()
tester.print_report()
Remediation Guide
1. Comprehensive Username Validation import re
import unicodedata
def validate_username (username ):
"""Validate username against security policy"""
errors = []
if len (username) < 3 :
errors.append("Username must be at least 3 characters" )
if len (username) > 30 :
errors.append("Username must be 30 characters or less" )
if not re.match (r'^[a-zA-Z0-9_]+$' , username):
errors.append("Username can only contain letters, numbers, and underscores" )
if not re.match (r'^[a-zA-Z]' , username):
errors.append("Username must start with a letter" )
if '__' in username:
errors.append("Username cannot contain consecutive underscores" )
reserved = ['admin' , 'administrator' , 'root' , 'system' , 'support' ,
'null' , 'undefined' , 'api' , 'www' , 'mail' , 'ftp' ]
if username.lower() in reserved:
errors.append("This username is reserved" )
normalized = unicodedata.normalize('NFKC' , username)
if normalized != username:
errors.append("Username contains invalid characters" )
if contains_confusables(username):
errors.append("Username contains potentially confusing characters" )
return errors
def contains_confusables (username ):
"""Check for homograph/confusable characters"""
try :
username.encode('ascii' )
return False
except UnicodeEncodeError:
return True
2. Case-Insensitive Uniqueness from sqlalchemy import func
def is_username_available (username ):
"""Check username availability (case-insensitive)"""
normalized = username.lower()
existing = User.query.filter (
func.lower(User.username) == normalized
).first()
return existing is None
def create_user (username, email, password ):
if not is_username_available(username):
raise ValueError("Username already taken" )
user = User(
username=username,
username_normalized=username.lower(),
email=email
)
3. Similar Username Detection def is_similar_to_existing (username ):
"""Check if username is too similar to existing ones"""
normalized = normalize_for_comparison(username)
similar_users = User.query.filter (
User.username_normalized.like(f"%{normalized} %" )
).all ()
for user in similar_users:
if calculate_similarity(normalized, user.username_normalized) > 0.8 :
return True
return False
def normalize_for_comparison (username ):
"""Normalize username for similarity comparison"""
normalized = re.sub(r'[-_.]' , '' , username.lower())
normalized = re.sub(r'[0-9]' , '' , normalized)
return normalized
4. Display Name vs Username
class User :
username = Column(String(30 ))
display_name = Column(String(50 ))
@validates('username' )
def validate_username (self, key, username ):
errors = validate_username(username)
if errors:
raise ValueError('; ' .join(errors))
return username
Risk Assessment
CVSS Score Finding CVSS Severity Reserved names allowed (admin) 7.5 High Unicode homograph allowed 6.5 Medium Case sensitivity issues 5.3 Medium XSS via username 6.1 Medium Weak length requirements 3.7 Low
CWE Categories CWE ID Title Description CWE-20 Improper Input Validation Weak username validation CWE-79 Cross-site Scripting XSS via username CWE-178 Improper Handling of Case Case sensitivity issues
References
Checklist [ ] Minimum length requirement tested
[ ] Maximum length limit tested
[ ] Reserved username protection tested
[ ] Case sensitivity verified
[ ] Special character handling tested
[ ] Unicode/homograph attacks tested
[ ] SQL injection in username tested
[ ] XSS in username tested
[ ] Similar username prevention tested
[ ] Numeric-only usernames tested
[ ] Sequential pattern prevention tested
[ ] Whitespace handling tested
[ ] Findings documented
[ ] Remediation recommendations provided
More from this repository
Related occupations SOC
Based on SOC occupation classification