CtrlK
BlogDocsLog inGet started
Tessl Logo

coding-agent-helpers/skeptic-verifier

Use when the user wants an adversarial double-check of a code or config change. Run the strongest checks available, try to break the claim, look for edge cases and hidden regressions, and return PASS, PARTIAL, or FAIL with evidence. Good triggers include "poke holes in this", "stress test this change", "double check this fix", and "try to break it".

84

1.30x
Quality

94%

Does it follow best practices?

Impact

81%

1.30x

Average score across 8 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

task.mdevals/scenario-2/

Double-Check the Input Sanitization Fix

Problem/Feature Description

A developer on the data ingestion team says they've fixed a bug where user-supplied column names in a CSV upload could cause the downstream SQL query builder to produce malformed queries. The claimed fix adds a sanitization step that strips or rejects problematic characters before the column names reach the query builder.

The fix passed code review and the existing test suite. However, the security team has flagged the change for a second opinion before it ships, because similar sanitization code in a different part of the system was bypassed last quarter using Unicode normalization tricks. You need to independently verify whether the sanitization actually prevents malicious column names from reaching the query builder, or whether there are bypass paths.

Output Specification

Write your findings to verification_report.md. Include your verification approach, what you actually tested, the evidence you found, and your conclusion.

Input Files

The following files are provided as inputs. Extract them before beginning.

=============== FILE: src/sanitize.py =============== import re

SAFE_COLUMN_PATTERN = re.compile(r'^[A-Za-z_][A-Za-z0-9_]*$')

def sanitize_column_name(name: str) -> str: """ Validates that a column name is safe to use in a SQL query. Raises ValueError if the name contains unsafe characters. """ if not isinstance(name, str): raise ValueError(f"Column name must be a string, got {type(name)}") stripped = name.strip() if not stripped: raise ValueError("Column name cannot be empty") if not SAFE_COLUMN_PATTERN.match(stripped): raise ValueError( f"Unsafe column name: {stripped!r}. " "Only letters, digits, and underscores are allowed, " "and the name must start with a letter or underscore." ) return stripped

def build_select_query(table: str, columns: list) -> str: """ Builds a SELECT query for the given table and list of column names. Each column name is sanitized before use. """ safe_cols = [sanitize_column_name(c) for c in columns] col_list = ", ".join(safe_cols) return f"SELECT {col_list} FROM {table}"

=============== FILE: tests/test_sanitize.py =============== import sys sys.path.insert(0, 'src') from sanitize import sanitize_column_name, build_select_query import traceback

tests_passed = 0 tests_failed = 0

def check(name, fn): global tests_passed, tests_failed try: fn() print(f"PASS: {name}") tests_passed += 1 except Exception as e: print(f"FAIL: {name} — {e}") tests_failed += 1

def test_valid_names(): assert sanitize_column_name("user_id") == "user_id" assert sanitize_column_name("Amount") == "Amount" assert sanitize_column_name("_private") == "_private"

def test_rejects_spaces(): try: sanitize_column_name("user id") assert False, "Should have raised" except ValueError: pass

def test_rejects_semicolon(): try: sanitize_column_name("id; DROP TABLE users") assert False, "Should have raised" except ValueError: pass

def test_query_building(): q = build_select_query("orders", ["user_id", "amount"]) assert "SELECT user_id, amount FROM orders" == q

check("valid names", test_valid_names) check("rejects spaces", test_rejects_spaces) check("rejects semicolon", test_rejects_semicolon) check("query building", test_query_building) print(f"\n{tests_passed} passed, {tests_failed} failed")

evals

tile.json