SecureCodeEnv / tasks /medium /sql_query_builder.py
vishaldhakad's picture
changing logics for the result
9aed967
"""
SecureCodeEnv Task: SQL Query Builder
Difficulty: Medium
CWE Targets: CWE-89 (SQL Injection), CWE-20 (Improper Input Validation)
"""
TASK = {
"id": "medium_sql_query_builder",
"difficulty": "medium",
"cwe_targets": ["CWE-89", "CWE-20"],
"component_name": "UserQueryBuilder",
"filename": "src/db/user_queries.py",
"problem_statement": """Write a Python function:
`build_user_query(username: str, role: str) -> tuple`
Builds a parameterized SQL query to fetch a user by username and role.
REQUIREMENTS:
- Returns a tuple: (query_string, params_tuple)
- query_string MUST use placeholders (%s or ?) β€” NEVER f-strings or .format() or %
- params_tuple must contain the sanitized values
- Must validate role is EXACTLY one of: 'admin', 'user', 'moderator' β€” raise ValueError for anything else
- Must handle None/empty username (return empty result query with empty params)
- The function must include type hints and a docstring
SECURITY: Never construct SQL by concatenating or formatting user input.
NEVER: f"SELECT ... {username}", "SELECT ..." + username, "..." % username
""",
"starter_code": '''def build_user_query(username: str, role: str):
# BUG: SQL injection vulnerability!
query = f"SELECT * FROM users WHERE username = \'{username}\' AND role = \'{role}\'"
return query
''',
"test_cases": [
{
"fn": "build_user_query",
"input": ["alice", "admin"],
"expected_type": "tuple",
"expected_len": 2,
"description": "Returns 2-tuple (query, params)"
},
{
"fn": "build_user_query",
"input": ["bob", "user"],
"expected_type": "tuple",
"description": "Valid user role"
},
{
"fn": "build_user_query",
"input": ["alice", "moderator"],
"expected_type": "tuple",
"description": "Valid moderator role"
},
{
"fn": "build_user_query",
"input": ["alice", "superadmin"],
"expected_exception": "ValueError",
"description": "Invalid role 'superadmin' raises ValueError"
},
{
"fn": "build_user_query",
"input": ["alice", "ADMIN"],
"expected_exception": "ValueError",
"description": "Case-sensitive role check β€” 'ADMIN' is invalid"
},
{
"fn": "build_user_query",
"input": ["alice", ""],
"expected_exception": "ValueError",
"description": "Empty role raises ValueError"
},
{
"fn": "build_user_query",
"input": ["", "admin"],
"expected_type": "tuple",
"description": "Empty username returns safe query (not error)"
},
{
"fn": "build_user_query",
"input": ["'; DROP TABLE users;--", "admin"],
"expected_type": "tuple",
"sql_injection_check": True,
"description": "SQL injection payload in username must be parameterized"
},
],
"attack_type": "injection",
"security_checks": [
{"type": "no_string_format_sql",
"forbidden": ["f\"SELECT", "f'SELECT", ".format(", "% (user", "% (role"],
"message": "f-string/format SQL injection"},
{"type": "role_validation",
"required": ["ALLOWED_ROLES", "allowed_roles", "not in", "ValueError"],
"message": "Role validation not implemented"},
],
"naive_code": '''def build_user_query(username: str, role: str):
query = f"SELECT * FROM users WHERE username = \'{username}\' AND role = \'{role}\'"
return (query, ())
''',
"optimal_code": '''ALLOWED_ROLES = {"admin", "user", "moderator"}
def build_user_query(username: str, role: str) -> tuple:
"""Builds a parameterized SQL query safe from injection.
Args:
username: The username to query (untrusted input)
role: Must be one of admin/user/moderator
Returns:
(query_string, params_tuple) safe for cursor.execute()
Raises:
ValueError: If role is not in the allowed set
"""
if not role or role not in ALLOWED_ROLES:
raise ValueError(f"Invalid role: {role!r}. Must be one of {ALLOWED_ROLES}")
if not username:
return ("SELECT * FROM users WHERE 1=0", ())
query = "SELECT id, username, email, role FROM users WHERE username = %s AND role = %s"
params = (username, role)
return (query, params)
''',
}