You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask+SQLAlchemy+SQLite3数据库搜索防SQL注入的代码改造方案咨询

防范SQL注入的改造方案

针对你的场景,核心要解决两个SQL注入风险点:用户可控的字段名和用户输入的搜索内容。下面结合你的Flask-SQLAlchemy模型和表单,给出具体的改造步骤和代码:

1. 先做字段名的白名单验证

因为SQL参数化查询无法参数化字段名(比如WHERE {column} LIKE ...里的column),所以必须先验证用户选择的字段是否是你预先定义的合法字段,避免恶意字段名注入。

首先,基于你的My_library模型,定义一个允许搜索的字段白名单:

ALLOWED_SEARCH_FIELDS = {
    "title", "authors", "published_date", "isbn_or_identifier", "language"
}

2. 使用Flask-SQLAlchemy ORM构建安全查询

直接使用ORM的查询API,既能避免手动拼接SQL,又能自动处理参数化,比原生text语句更简洁安全。

改造你的搜索函数:

# 假设你已经初始化了db,比如db = SQLAlchemy(app)

def search_in_database(column, searched_data):
    # 第一步:验证字段是否在白名单内
    if column not in ALLOWED_SEARCH_FIELDS:
        raise ValueError("Invalid search field")
    
    # 第二步:获取模型对应的字段对象
    model_field = getattr(My_library, column)
    
    # 第三步:构建模糊查询,使用ORM的like方法,参数化搜索内容
    query = My_library.query.filter(model_field.like(f"%{searched_data}%"))
    
    # 获取结果,返回id列表
    return [item.id for item in query.all()]

为什么这样安全?

  • 字段名通过白名单验证,只有你允许的字段才能被查询,杜绝了column参数的注入(比如用户传入title; DROP TABLE...会被直接拦截)。
  • 搜索内容的like查询由SQLAlchemy自动参数化,searched_data里的特殊字符(比如'、;)会被自动转义,不会被解析为SQL语句的一部分。

3. 结合搜索表单优化用户输入处理

你现有的表单是用于添加记录的,建议新增一个专门的搜索表单,让用户直观选择字段和输入内容:

from flask_wtf import FlaskForm
from wtforms import SelectField, StringField, SubmitField
from wtforms.validators import DataRequired

class SearchForm(FlaskForm):
    # 下拉框列出允许搜索的字段,对应白名单
    search_field = SelectField(
        "Search by",
        choices=[
            ("title", "Title"),
            ("authors", "Authors"),
            ("published_date", "Published Date"),
            ("isbn_or_identifier", "ISBN"),
            ("language", "Language")
        ],
        validators=[DataRequired()]
    )
    search_content = StringField("Search content", validators=[DataRequired()])
    submit = SubmitField("Search")

然后在视图函数里处理表单提交:

@app.route("/search", methods=["GET", "POST"])
def search():
    form = SearchForm()
    results = []
    if form.validate_on_submit():
        try:
            results = search_in_database(form.search_field.data, form.search_content.data)
        except ValueError as e:
            # 处理非法字段的情况,比如返回错误提示
            flash(str(e))
    return render_template("search.html", form=form, results=results)

4. 额外的安全建议

  • 保持你现有的表单验证逻辑,比如对published_date、isbn_or_identifier等字段做类型验证,进一步过滤非法输入。
  • 绝对避免直接把用户输入的内容拼接到SQL语句中(不管是字段名还是值),始终依赖ORM或参数化查询。
  • 可以给数据库用户配置最小权限(比如只允许SELECT操作),即使发生意外注入,也能降低破坏程度。

内容的提问来源于stack exchange,提问作者Golab368

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 14:57:40