基于FastAPI开发REST API时如何防范HTML注入?
在FastAPI中防范HTML注入的实用方法
嗨,这个问题在Web开发里太常见了——用户提交的HTML标签存库后返回前端,一不小心就触发注入风险。结合FastAPI的特性,给你几个落地的解决方案:
1. 输出阶段转义HTML内容(最稳妥的兜底方案)
不管输入时有没有处理,在返回给客户端之前把HTML特殊字符转义成实体,浏览器就会把它们当成普通文本渲染,不会执行。Python标准库的html模块就能搞定这个:
from fastapi import FastAPI import html app = FastAPI() # 模拟从数据库获取的用户内容 user_submitted_content = "<script>alert('hacked')</script>" @app.get("/content") def get_content(): # 转义后返回 escaped_content = html.escape(user_submitted_content) return {"content": escaped_content}
转义后返回的内容会变成<script>alert('hacked')</script>,浏览器只会显示这段文本,不会执行脚本。
2. 输入阶段过滤/清理HTML(从源头减少风险)
如果业务允许,在接收用户输入时就清理掉不安全的HTML标签,只保留允许的内容。推荐用bleach库,它支持白名单机制,非常灵活:
首先安装依赖:
pip install bleach
然后在POST接口里处理:
from fastapi import FastAPI, Body import bleach app = FastAPI() # 定义允许保留的标签和属性(比如只允许<b>、<i>这类无害标签) ALLOWED_TAGS = ["b", "i", "em", "strong"] ALLOWED_ATTRIBUTES = {} @app.post("/submit-content") def submit_content(content: str = Body(...)): # 清理不安全的HTML cleaned_content = bleach.clean(content, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES) # 这里把cleaned_content存入数据库 return {"status": "success", "cleaned_content": cleaned_content}
这样用户提交的<script>、<iframe>这类危险标签会被直接移除,从源头杜绝注入可能。
3. 结合响应模型自动处理(适合结构化返回)
如果用FastAPI的Pydantic响应模型,可以在模型字段里添加转义逻辑,统一处理所有返回的用户内容:
from fastapi import FastAPI from pydantic import BaseModel, field_validator import html app = FastAPI() class ContentResponse(BaseModel): id: int content: str @field_validator("content") def escape_html(cls, v): return html.escape(v) @app.get("/content/{content_id}", response_model=ContentResponse) def get_content(content_id: int): # 模拟从数据库获取数据 db_content = {"id": content_id, "content": "<script>malicious code</script>"} return ContentResponse(**db_content)
这种方式适合有大量接口需要返回用户内容的场景,不用每个接口都手动写转义代码,统一维护更方便。
4. 前端层面配合(双重保障)
虽然这是服务端的问题,但如果前端是网页应用,在渲染用户内容时也做一次转义(比如React的JSX默认会转义,Vue的v-text也会),可以形成双重防护,进一步降低风险。
总结一下:优先用输出转义做兜底,再配合输入过滤减少不必要的风险,结合响应模型可以让代码更整洁。根据你的业务需求选择合适的方案就行~
内容的提问来源于stack exchange,提问作者samba
相关产品推荐
相关产品推荐

