Spaces:
Sleeping
Sleeping
| """ | |
| SecureCodeEnv Task: Secure Token Generator | |
| Difficulty: Easy | |
| CWE Targets: CWE-338 (Use of Cryptographically Weak PRNG), CWE-330 (Insufficient Randomness) | |
| """ | |
| TASK = { | |
| "id": "easy_token_generator", | |
| "difficulty": "easy", | |
| "cwe_targets": ["CWE-338", "CWE-330"], | |
| "component_name": "TokenGenerator", | |
| "filename": "src/auth/token_generator.py", | |
| "problem_statement": """Write two Python functions: | |
| 1. `generate_token(length: int = 32) -> str` | |
| Generates a cryptographically secure random token. | |
| - MUST use secrets module (NOT random, NOT os.urandom directly, NOT time-based seeds) | |
| - Token must be URL-safe (use secrets.token_urlsafe or secrets.token_hex) | |
| - Length must be respected (the output must be at least `length` characters) | |
| - Must handle length < 1 by using 32 as default | |
| 2. `generate_session_id() -> str` | |
| Generates a secure session ID suitable for HTTP cookies. | |
| - Must be at least 32 characters long | |
| - Must use secrets module | |
| - Must be hex or URL-safe base64 format | |
| Do NOT use: random.random(), random.randint(), math.random, time.time() for randomness.""", | |
| "starter_code": '''import random | |
| import time | |
| def generate_token(length: int = 32) -> str: | |
| # TODO: Use cryptographically secure randomness | |
| chars = "abcdefghijklmnopqrstuvwxyz0123456789" | |
| random.seed(time.time()) # INSECURE: time-based seed | |
| return "".join(random.choice(chars) for _ in range(length)) | |
| def generate_session_id() -> str: | |
| # TODO: Secure session ID | |
| return str(int(time.time() * 1000)) # INSECURE: predictable | |
| ''', | |
| "test_cases": [ | |
| {"fn": "generate_token", "input": [32], "expected_min_len": 32, "description": "Token is at least 32 chars"}, | |
| {"fn": "generate_token", "input": [64], "expected_min_len": 64, "description": "Token is at least 64 chars"}, | |
| {"fn": "generate_token", "input": [0], "expected_min_len": 32, "description": "Length 0 defaults to 32"}, | |
| {"fn": "generate_token", "input": [-1], "expected_min_len": 32, "description": "Negative length defaults to 32"}, | |
| {"fn": "generate_session_id", "input": [], "expected_min_len": 32, "description": "Session ID at least 32 chars"}, | |
| {"fn": "generate_token", "input": [32], "unique": True, "description": "Two calls produce different tokens"}, | |
| ], | |
| "attack_type": "weak_random", | |
| "security_checks": [ | |
| {"type": "no_weak_random", "forbidden": ["random.random(", "random.randint(", "random.seed("]}, | |
| {"type": "uses_secrets", "required_import": "secrets"}, | |
| ], | |
| "naive_code": '''import random | |
| def generate_token(length: int = 32) -> str: | |
| chars = "abcdefghijklmnopqrstuvwxyz0123456789" | |
| return "".join(random.choice(chars) for _ in range(max(length, 32))) | |
| def generate_session_id() -> str: | |
| return str(random.getrandbits(128)) | |
| ''', | |
| "optimal_code": '''import secrets | |
| def generate_token(length: int = 32) -> str: | |
| """Generates a cryptographically secure URL-safe random token.""" | |
| if length < 1: | |
| length = 32 | |
| # token_urlsafe(n) produces ceil(n * 4/3) chars, so nbytes = length * 3 // 4 | |
| return secrets.token_urlsafe(max(length, 32))[:max(length, 32)] | |
| def generate_session_id() -> str: | |
| """Generates a secure 64-char hex session ID.""" | |
| return secrets.token_hex(32) # 32 bytes = 64 hex chars | |
| ''', | |
| } | |