AST-aware, stdlib-only static checks: swallowed-exception-around-write (C1), undefined-name (C2), hardcoded-secret-literal (C3), fail-open-flag (C4), rotated-secret-captured-once (C5). Tests + CI + examples included. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
42 lines
1.4 KiB
Python
42 lines
1.4 KiB
Python
"""Intentionally-buggy fixture demonstrating each bug class. Run:
|
|
|
|
python -m bugclass_detectors examples/buggy_sample.py
|
|
|
|
Every flagged line is a real silent-failure shape this tool catches.
|
|
"""
|
|
import os
|
|
import redis
|
|
|
|
r = redis.Redis(host=os.environ.get("CACHE_HOST", "localhost"))
|
|
|
|
# --- C3: hardcoded secret literal -----------------------------------------
|
|
DB_PASSWORD = "s3cr3t_inline_password_value" # noqa (should read from env)
|
|
|
|
|
|
# --- C1: swallowed exception around a primary write -----------------------
|
|
def record_metric(name, value):
|
|
try:
|
|
r.hset("metrics", name, value) # the function's ONLY output
|
|
except Exception:
|
|
pass # producer looks alive, data lost, no log
|
|
|
|
|
|
# --- C2: undefined name ---------------------------------------------------
|
|
def compute_total(items):
|
|
for item in items:
|
|
running += item # `running` never initialized -> NameError
|
|
return running
|
|
|
|
|
|
# --- C4: fail-open feature/kill flag --------------------------------------
|
|
def is_killed():
|
|
client = redis.from_url(os.environ.get("FLAG_REDIS_URL", "redis://localhost"))
|
|
return client.get("kill_switch") # on a repointed store this reads None and fails OPEN
|
|
|
|
|
|
# --- C5: rotated secret captured once at module scope ---------------------
|
|
API_TOKEN = os.environ.get("API_TOKEN") # captured once
|
|
|
|
def daemon():
|
|
while True:
|
|
call_api(API_TOKEN) # stale after rotation; never re-read
|