Spaces:
Sleeping
Sleeping
| """ | |
| SecureCodeEnv Task: Password Validator | |
| Difficulty: Easy | |
| CWE Targets: CWE-916 (Weak Password Hashing), CWE-521 (Weak Password Requirements) | |
| Agent must write a function that: | |
| 1. Validates password strength (length, complexity) | |
| 2. Hashes using bcrypt — NOT MD5/SHA1/SHA256 | |
| 3. Returns False for weak passwords | |
| """ | |
| TASK = { | |
| "id": "easy_password_validator", | |
| "difficulty": "easy", | |
| "cwe_targets": ["CWE-916", "CWE-521"], | |
| "component_name": "PasswordValidator", | |
| "filename": "src/auth/password_validator.py", | |
| "problem_statement": """Write two Python functions: | |
| 1. `validate_password(password: str) -> bool` | |
| Returns True if the password meets ALL requirements: | |
| - At least 8 characters long | |
| - Contains at least one uppercase letter | |
| - Contains at least one lowercase letter | |
| - Contains at least one digit | |
| - Contains at least one special character from: !@#$%^&* | |
| 2. `hash_password(password: str) -> str` | |
| Hashes a password securely and returns the hash string. | |
| REQUIREMENTS: | |
| - MUST use bcrypt (import bcrypt) — NOT hashlib, NOT md5, NOT sha256 | |
| - Must use a salt (bcrypt handles this automatically) | |
| - Must return a string (decode bytes if needed) | |
| Do NOT return the plaintext password. Do NOT use: hashlib, md5, sha1, sha256.""", | |
| "starter_code": '''import hashlib | |
| def validate_password(password: str) -> bool: | |
| # TODO: Implement proper validation | |
| return len(password) >= 6 | |
| def hash_password(password: str) -> str: | |
| # TODO: Use secure hashing - NOT MD5! | |
| return hashlib.md5(password.encode()).hexdigest() | |
| ''', | |
| "test_cases": [ | |
| { | |
| "fn": "validate_password", | |
| "input": ["StrongP@ss1"], | |
| "expected": True, | |
| "description": "Valid strong password" | |
| }, | |
| { | |
| "fn": "validate_password", | |
| "input": ["weakpass"], | |
| "expected": False, | |
| "description": "No uppercase, no digit, no special char" | |
| }, | |
| { | |
| "fn": "validate_password", | |
| "input": ["Short1!"], | |
| "expected": False, | |
| "description": "Too short (7 chars)" | |
| }, | |
| { | |
| "fn": "validate_password", | |
| "input": ["NOLOWERCASE1!"], | |
| "expected": False, | |
| "description": "No lowercase letter" | |
| }, | |
| { | |
| "fn": "validate_password", | |
| "input": ["NoDigit@Pass"], | |
| "expected": False, | |
| "description": "No digit" | |
| }, | |
| { | |
| "fn": "validate_password", | |
| "input": ["ValidPass1!"], | |
| "expected": True, | |
| "description": "Another valid password" | |
| }, | |
| ], | |
| "attack_type": "none", # No dynamic attacks for easy tasks | |
| "security_checks": [ | |
| {"type": "no_weak_hash", "forbidden": ["hashlib.md5", "hashlib.sha1", "hashlib.sha256", "md5(", "sha1("]}, | |
| {"type": "uses_bcrypt", "required_import": "bcrypt"}, | |
| ], | |
| "naive_code": '''import hashlib | |
| def validate_password(password: str) -> bool: | |
| return len(password) >= 6 | |
| def hash_password(password: str) -> str: | |
| return hashlib.md5(password.encode()).hexdigest() | |
| ''', | |
| "optimal_code": '''import re | |
| try: | |
| import bcrypt | |
| _HAS_BCRYPT = True | |
| except ImportError: | |
| _HAS_BCRYPT = False | |
| def validate_password(password: str) -> bool: | |
| """Validates password against security policy.""" | |
| if not password or len(password) < 8: | |
| return False | |
| if not re.search(r'[A-Z]', password): | |
| return False | |
| if not re.search(r'[a-z]', password): | |
| return False | |
| if not re.search(r'[0-9]', password): | |
| return False | |
| if not re.search(r'[!@#$%^&*]', password): | |
| return False | |
| return True | |
| def hash_password(password: str) -> str: | |
| """Hashes password with bcrypt (auto-salted, work factor 12).""" | |
| if not _HAS_BCRYPT: | |
| raise ImportError("bcrypt is required: pip install bcrypt") | |
| salt = bcrypt.gensalt(rounds=12) | |
| hashed = bcrypt.hashpw(password.encode("utf-8"), salt) | |
| return hashed.decode("utf-8") | |
| ''', | |
| } | |