File size: 4,074 Bytes
7257069
 
 
 
 
 
 
 
 
 
ef93755
 
7257069
ef93755
 
7257069
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ef93755
 
7257069
 
 
 
 
 
 
 
ef93755
7257069
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ef93755
7257069
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ef93755
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
"""
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")
''',
}