提示词典TISHICIDIAN
No.006 · 编程

代码审查:只挑会出事的问题

让模型别纠结命名和格式,只找 bug、安全和边界情况。

提示词

请审查下面的代码: 【粘贴代码】 只指出会导致错误结果、崩溃、安全问题或性能明显变差的地方。 每条写:在哪一行、为什么有问题、怎么改。 命名、格式、注释风格一律不用提。没有问题就直接说没有。

示例:填好之后,模型这样回答

填好后的提示词(示例内容为虚构)
请审查下面的代码:
def get_balance(uid):
    rows = db.query(f"SELECT balance FROM acct_tbl WHERE uid = '{uid}'")
    if not rows:
        return 0
    return rows[0]['balance']

def transfer(src, dst, amount):
    if get_balance(src) >= amount:
        db.execute(f"UPDATE acct_tbl SET balance = balance - {amount} WHERE uid = '{src}'")
        db.execute(f"UPDATE acct_tbl SET balance = balance + {amount} WHERE uid = '{dst}'")


只指出会导致错误结果、崩溃、安全问题或性能明显变差的地方。
每条写:在哪一行、为什么有问题、怎么改。
命名、格式、注释风格一律不用提。没有问题就直接说没有。
模型回答 · claude-sonnet-5-5 · 2026-10-24 实跑,未修改

问题清单

1. 第 2 行:SQL 注入
uid 被直接拼进 SQL。传入 ' OR '1'='1 之类的值就能读到任意数据。
改法:使用参数化查询。

rows = db.query("SELECT balance FROM acct_tbl WHERE uid = %s", (uid,))

占位符风格按你用的驱动调整,如 %s、?、:uid。

2. 第 9、10 行:SQL 注入,且 amount 也可被注入
src、dst、amount 全部是拼接的。amount 没有引号,注入更容易,例如 "0; UPDATE acct_tbl SET balance=999999 WHERE uid='x"。
改法:全部参数化,见文末示例。

3. 第 8–10 行:检查再更新存在竞态(TOCTOU),可能透支
并发两笔转账都可能读到足够的余额,然后都扣款,余额变成负数。
改法:把检查合并进 UPDATE 的条件里,并检查影响行数。

UPDATE acct_tbl SET balance = balance - %s WHERE uid = %s AND balance >= %s

`rowcount != 1

不同模型、不同时间的回答会有差异;想对比几个模型,可以把这段提示词拿到提示词实验室并排跑一遍。

注意

参见