文章标题:
在FastAPI中构建坚不可摧的Web安全防护策略
第一章:基础安全框架认知
一、Web 安全三要素
1.1 机密性(Confidentiality)
原理阐述
数据在传输过程以及存储阶段,仅能被授权的主体所查看,这是通过加密算法来达成数据保护的目的。FastAPI默认支持HTTPS协议,利用TLS对通信信道实施加密。
FastAPI实践示例
# 安装依赖
# uvicorn[standard]==0.17.6
# cryptography==38.0.4
from fastapi import FastAPI
import ssl
app = FastAPI()
# HTTPS配置示例
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain("domain.crt", keyfile="domain.key")
@app.get("/secure-data")
async def get_secure_data():
return {"message": "此数据通过HTTPS加密传输"}
1.2 完整性(Integrity)
实现途径
借助哈希校验和数字签名来确保数据没有被篡改。FastAPI依靠Pydantic模型来进行请求数据的验证。
数据验证示例
# pydantic==1.10.7
from pydantic import BaseModel
class Transaction(BaseModel):
amount: float
recipient: str
signature: str # 数字签名字段
@app.post("/transfer")
async def fund_transfer(tx: Transaction):
# 验证签名逻辑
if not validate_signature(tx.signature):
raise HTTPException(400, "交易签名无效")
return {"status": "已完成"}
1.3 可用性(Availability)
防护策略
通过对请求的速率进行限制来保障服务的稳定运行。采用Redis来实现分布式的限流功能。
# fastapi-limiter==0.1.5
# redis==4.5.4
from fastapi import Request
from fastapi_limiter import Limiter
from fastapi_limiter.depends import RateLimiter
limiter = Limiter(key_func=lambda: "global")
app.state.limiter = limiter
@app.get("/api/data")
@limiter.limit("10/minute")
async def get_data(request: Request):
return {"data": "重要资源"}
二、HTTPS 传输层加密
2.1 TLS 握手流程
participant Client
participant Server
Client->>Server: ClientHello (支持的加密套件)
Server->>Client: ServerHello (选定加密套件) + 证书
Client->>Server: 验证证书 + 生成预主密钥
Server->>Client: 完成握手
Note over Client,Server: 开始加密通信
2.2 证书配置实战
# 生成自签名证书
openssl req -x509 -newkey rsa:4096 -nodes -out domain.crt -keyout domain.key -days 365
三、安全威胁防御
3.1 XSS 防护
场景示例
当用户输入包含<script>alert(1)</script>
的评论时的防护办法
from fastapi import HTTPException
from html import escape
@app.post("/comments")
async def create_comment(content: str):
# 自动转义HTML字符
sanitized_content = escape(content)
save_to_db(sanitized_content)
return {"status": "已创建"}
3.2 CSRF 防护
令牌验证实现
# fastapi-csrf-protect==0.1.1
from fastapi_csrf_protect import CsrfProtect
@CsrfProtect.load_config
def get_csrf_config():
return {"secret_key": "SECRET_KEY"}
@app.post("/transfer")
async def bank_transfer(
request: Request,
csrf_protect: CsrfProtect = Depends()
):
csrf_protect.validate(request)
# 执行具体业务逻辑
3.3 SQL 注入防护
ORM 安全实践
# SQLAlchemy==1.4.39
from sqlalchemy import text
# 危险写法(易受注入攻击)
stmt = text(f"SELECT * FROM users WHERE name = '{name}'")
# 安全写法(参数化查询)
safe_stmt = text("SELECT * FROM users WHERE name = :name").bindparams(name=name)
课后Quiz
问题1
当收到包含<img src=x onerror=alert(1)>
的用户输入时,哪种处理方式最安全?
A) 直接存入数据库
B) 使用HTML转义
C) 截断超过50字符的内容
答案解析
正确答案为B。通过运用html.escape()将特殊字符转换为实体(例如<
),能够有效避免浏览器执行恶意脚本。
常见报错解决
报错422 Validation Error
产生原因 :
请求体不符合Pydantic模型定义的数据类型
解决方案 :
- 检查请求头
Content-Type: application/json
- 使用Swagger文档测试接口
- 打印模型校验错误详情:
@app.exception_handler(RequestValidationError)
async def validation_handler(request, exc):
print(f"验证错误:{exc.errors()}")
(注:原文中涉及广告推广等无关内容已过滤,仅保留技术相关内容)
文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/12899.html