Skip to content

FastAPI Security Cheat Sheet / FastAPI 安全速查表

Introduction / 介绍

FastAPI is a Python web framework using the Asynchronous Server Gateway Interface (ASGI). This cheat sheet covers authentication dependencies, input and output models, and deployment controls, building on the FastAPI security documentation.

FastAPI 是一个使用异步服务器网关接口 (ASGI) 的 Python 网络框架。此速查表涵盖了身份验证依赖项、输入和输出模型以及部署控制,基于 FastAPI 安全文档。

See the REST Security Cheat Sheet for general API controls.

查看 REST 安全速查表 以获取一般 API 控制。

Code snippets illustrate individual controls, not complete applications. They assume an existing FastAPI application and application-specific user and persistence functions; adapt and test them for your application.

代码片段说明了单个控制,而不是完整的应用程序。它们假设存在一个现有的 FastAPI 应用程序和特定于应用程序的用户和持久化函数;请根据您的应用程序进行修改和测试。

Dependency Injection and Access Control / 依赖注入和访问控制

Use FastAPI's dependency injection system, through Depends(), to enforce authentication and authorization consistently. Missing or insufficient dependencies can leave sensitive operations accessible to unauthorized users. See the FastAPI dependencies tutorial.

使用 FastAPI 的依赖注入系统,通过 Depends(),来一致地执行身份验证和授权。缺少或不充分的依赖项可能会使敏感操作对未经授权的用户可访问。请参阅 FastAPI 依赖项教程。

OAuth2PasswordBearer Does Not Validate Tokens / OAuth2PasswordBearer 不验证令牌

The helper class OAuth2PasswordBearer checks the authorization scheme and extracts the bearer token from the Authorization header. It does not validate the token or verify its signature. An authentication dependency must verify the token and reject invalid credentials before returning a user. See the OAuth2PasswordBearer reference.

辅助类 OAuth2PasswordBearer 检查授权方案并从 Authorization 标头中提取承载令牌。它 不验证令牌或验证其签名。身份验证依赖项必须在返回用户之前验证令牌并拒绝无效凭据。请参阅 OAuth2PasswordBearer 参考。

Scoping Authorization Dependencies / 作用域授权依赖

Authentication alone does not authorize an operation. Endpoints requiring elevated privileges, such as admin tasks, must also check the user's permissions. In this example, get_current_user is an authentication dependency that rejects invalid credentials.

仅认证本身并不能授权操作。需要高级权限的端点,例如管理员任务,也必须检查用户的权限。在这个例子中,get_current_user 是一个认证依赖,它会拒绝无效的凭据。

from fastapi import Depends, HTTPException, status

async def get_admin_user(current_user: User = Depends(get_current_user)):
    if not current_user.is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Operation not permitted"
        )
    return current_user

@app.post("/admin/settings")
def update_settings(admin: User = Depends(get_admin_user)):
    return {"status": "success"}

Router-Level Deny-by-Default / 路由器级别默认拒绝

Apply authentication dependencies to an entire APIRouter so new endpoints in that router inherit the check. This covers only that router's routes; sensitive operations still need permission checks.

将认证依赖应用于整个 APIRouter,以便该路由器中的新端点继承检查。这仅覆盖该路由器的路由;敏感操作仍需要权限检查。

from fastapi import APIRouter, Depends

# Enforce authentication for all routes registered under this router by default
router = APIRouter(
    prefix="/items",
    dependencies=[Depends(get_current_user)]
)

Secure Authentication and JWT Implementation / 安全认证和JWT实现

When using JSON Web Tokens (JWTs), developers are responsible for token verification and key management. The FastAPI OAuth2 with JWT tutorial demonstrates verification with PyJWT.

当使用JSON Web Tokens (JWT) 时,开发者负责令牌验证和密钥管理。FastAPI OAuth2与JWT教程展示了使用PyJWT的验证方法。

Cryptographic Library Choice / 加密库选择

  • Use PyJWT: Delegate token verification to the library rather than writing custom parsing or cryptographic logic. Configure verification using the PyJWT decoding API.
    中文:使用 PyJWT: 将令牌验证委托给库,而不是编写自定义解析或加密逻辑。使用 PyJWT 解码 API 进行配置。

Key Claims Verification / 密钥声明验证

  • Validate Required Claims: Verify the signature and require exp (expiration), iss (issuer), and aud (audience) for authentication tokens. In PyJWT, use options={"require": ["exp", "iss", "aud"]} and supply the expected issuer and audience. Requiring a claim only checks its presence; keep the corresponding verification enabled. Validate nbf (not before) when present, and require it if your token profile calls for it.
  • Explicit Algorithms: Configure the expected algorithm during decoding, for example algorithms=["HS256"] for tokens issued with that algorithm. Do not derive the accepted algorithms from the token's header.
  • Revocation and Replay: Expiration bounds a token's lifetime. Checking a revocation blocklist rejects revoked tokens, but a stolen, still-active bearer token remains reusable. See the JWT replay-protection guidance for controls beyond expiration and revocation.
    中文:撤销和重放攻击: 令牌的有效期限制了其生命周期。检查撤销黑名单可以拒绝已撤销的令牌,但被盗的仍然活跃的载体令牌仍然可重复使用。参见 JWT 重放保护指南,了解除过期和撤销之外的控制措施。
  • Cookie Attributes: If you store refresh tokens in cookies, set HttpOnly, Secure, and SameSite=Lax or Strict where compatible with your authentication flow. HttpOnly prevents JavaScript from reading the cookie; it does not prevent injected scripts from making authenticated requests.
  • CSRF Mitigations: Browsers attach cookies automatically, introducing Cross-Site Request Forgery (CSRF) risk. Protect refresh and other state-changing endpoints with the defenses in the CSRF Prevention Cheat Sheet, such as validated CSRF tokens. Treat SameSite as defense in depth.
    中文:CSRF 缓解措施: 浏览器会自动附加cookie,引入跨站请求伪造(CSRF)风险。使用 CSRF 防范备忘单 中的防御措施来保护刷新和其他状态更改端点,例如验证的CSRF令牌。将 SameSite 视为多层次防御。

Signing Key Management

Never hardcode signing secrets or provide a default development key in production. Supply keys from deployment-managed secret storage; prefer a mounted secret file or retrieval from a secret manager, and use environment variables only when safer injection methods are unavailable. Pydantic Settings can read deployment-supplied configuration. Keep local .env files containing secrets out of source control. Follow the Secrets Management Cheat Sheet for provisioning and rotation.

Pydantic Validation and Input Hardening

Pydantic schemas validate data, but they do not replace authorization checks or prevent injection vulnerabilities. See the Pydantic models documentation.

Reject Unrecognized Fields / 拒绝未识别的字段

By default, Pydantic ignores undeclared input fields. Use extra="forbid" when the API should reject requests containing such fields instead of ignoring them:

默认情况下,Pydantic 会忽略未声明的输入字段。当 API 应该拒绝包含此类字段的请求而不是忽略它们时,请使用 extra="forbid":

from pydantic import BaseModel, ConfigDict

class UserCreate(BaseModel):
    model_config = ConfigDict(extra="forbid")
    username: str
    password: str

Prevent Mass Assignment / 防止大量赋值

Use separate, restricted input schemas (UserCreate, UserUpdate) that exclude server-controlled fields like is_admin or id. Persist only validated, allowed fields, not the raw request dictionary. extra="forbid" does not prevent clients from setting a sensitive field that you declared in the input schema. See the Mass Assignment Cheat Sheet.

使用单独的、受限的输入模式(UserCreate,UserUpdate),排除服务器控制的字段,如 is_admin 或 id。仅持久化经过验证的允许字段,而不是原始请求字典。extra="forbid" 不能阻止客户端设置在输入模式中声明的敏感字段。请参阅大量赋值作弊表。

Prevent Sensitive Data Exposure / 防止敏感数据泄露

Explicitly specify response_model in path decorators to filter database objects and exclude sensitive fields (e.g., password_hash) from responses. See FastAPI Response Model documentation.

在路径装饰器中显式指定 response_model 以过滤数据库对象,并从响应中排除敏感字段(例如,password_hash)。请参阅FastAPI 响应模型文档。

class UserResponse(BaseModel):
    username: str

@app.post("/users", response_model=UserResponse)
def create_user(user: UserCreate):
    # Application function must hash the password before storing it.
    return save_user_to_db(user)

Strict Typing / 严格的类型检查

Pydantic can convert input values to the declared types, such as "123" to 123 for an int field. Where security decisions require an exact input type, use strict types such as StrictInt and StrictBool to reject unintended conversions.

Pydantic 可以将输入值转换为声明的类型,例如,对于 int 字段,将 "123" 转换为 123。当安全决策需要确切的输入类型时,请使用严格的类型,如 StrictInt 和 StrictBool 以拒绝意外的转换。

Injection Countermeasure / 注入防护措施

Input validation does not prevent SQL injection. Use parameterized queries, including through Object-Relational Mapper (ORM) APIs that bind parameters. Never build raw SQL queries using string formatting with user input. See the SQL Injection Prevention Cheat Sheet.

输入验证不能防止SQL注入。使用参数化查询,包括通过绑定参数的对象关系映射器(ORM)API。切勿使用字符串格式化构建原始SQL查询,包括使用用户输入。请参阅SQL注入防护备忘单。

Cross-Origin Resource Sharing (CORS) Configuration / 跨源资源共享(CORS)配置

Incorrect CORS settings can expose private API responses to untrusted websites in a user's browser. CORS does not replace endpoint authorization or restrict non-browser clients. See the FastAPI CORS documentation.

不正确的CORS设置可能会将用户的浏览器中不受信任的网站暴露给私有API响应。CORS不代替端点授权或限制非浏览器客户端。请参阅FastAPI CORS文档。

Restrictive CORS Settings / 限制性CORS设置

  • Explicit Origins: When using allow_credentials=True, explicitly list trusted origins in allow_origins. Do not combine credentialed requests with allow_origins=["*"].
    中文:显式来源: 当使用 allow_credentials=True 时,在 allow_origins 中明确列出受信任的来源。不要将认证请求与 allow_origins=["*"] 结合使用。
  • Restrict Headers and Methods: Limit allow_methods and allow_headers to only the verbs and headers your client application uses.
    中文:限制头和方法: 将 allow_methods 和 allow_headers 限制为客户端应用程序使用的动词和头。
  • For complete CORS design patterns, refer to the OWASP HTML5 Security Cheat Sheet.
    中文:对于完整的CORS设计模式,请参阅 OWASP HTML5 安全备忘单。

OpenAPI and Swagger UI Exposure / OpenAPI和Swagger UI暴露

FastAPI exposes interactive documentation at /docs and /redoc, with the schema at /openapi.json. Decide whether this information should be public. The conditional OpenAPI guidance explains why hiding documentation does not secure the API operations themselves.

FastAPI在/docs和/redoc路径暴露交互式文档,并使用/openapi.json作为模式。决定是否公开这些信息。条件OpenAPI指南解释了隐藏文档并不能保证API操作本身的安全。

Hardening Documentation in Production / 在生产环境中加固文档

If the documentation is private, restrict access to both the documentation pages and schema, or disable them with FastAPI(openapi_url=None). This prevents disclosure through those routes; authorization must still protect every API operation.

如果文档是私有的,则限制对文档页面和模式的访问,或者使用FastAPI(openapi_url=None)禁用它们。这可以防止通过这些路径泄露信息;授权仍然需要保护每个API操作。

Async Event Loop and Background Tasks / 异步事件循环和后台任务

Blocking a worker's event loop prevents it from handling other requests, creating a Denial of Service (DoS) risk. See the FastAPI async tutorial.

阻止工作者的事件循环会阻止其处理其他请求,从而产生拒绝服务(DoS)风险。请参阅FastAPI异步教程。

Event Loop Blocking / 事件循环阻塞

  • Use asynchronous database and network clients inside async def routes. For synchronous libraries, use def routes or dependencies, which FastAPI runs in a thread pool. Ordinary helper functions called directly inside async def are not automatically moved to that pool.
    中文:在async def路由中使用异步数据库和网络客户端。对于同步库,使用def路由或依赖项,FastAPI将在线程池中运行。直接在async def内部调用的普通辅助函数不会自动移动到该池中。
  • Move CPU-heavy or long-running work to a separate worker system, such as Celery. BackgroundTasks still runs in the application process; see the background-task caveat.
    中文:将CPU密集型或长时间运行的工作移动到单独的worker系统,例如Celery。BackgroundTasks 仍在应用程序进程中运行;请参阅 后台任务注意事项。

Exception Handling and Information Leakage / 异常处理和信息泄露

Control which error details reach clients and logs. FastAPI supports custom exception handlers for sanitizing validation responses.

控制哪些错误详情发送给客户端和日志。FastAPI 支持自定义异常处理器 [https://fastapi.tiangolo.com/tutorial/handling-errors/#override-request-validation-exceptions],用于清理验证响应。

Validation Error Leakage / 验证错误泄露

Request validation errors can include submitted values and custom error details. Avoid reflecting passwords or tokens into responses or recording them in logs. In a RequestValidationError handler, return only safe field locations and error descriptions, or a generic message where necessary. Do not return str(exc) or the entire request body; these can include sensitive input or internal context.

请求验证错误可能包括提交的值和自定义错误详情。避免将密码或令牌反映到响应中或在日志中记录它们。在 RequestValidationError 处理器中,仅返回安全字段位置和错误描述,或在必要时返回通用消息。不要返回 str(exc) 或整个请求体;这些可能包含敏感输入或内部上下文。

File Upload Security / 文件上传安全

FastAPI parses multipart uploads into UploadFile objects, which spool larger files to temporary disk storage. See the UploadFile documentation.

FastAPI 将多部分上传解析为 UploadFile 对象,将大文件轮询到临时磁盘存储。请参阅 UploadFile 文档。

Upload Protections / 上传保护

  • Limit Payloads Before Parsing: Set a request-body limit at the reverse proxy or gateway, for example Nginx's client_max_body_size. Ensure clients cannot bypass that layer. FastAPI parses the form before running dependencies; checking UploadFile.size in a dependency or endpoint does not protect against the resources already consumed during parsing.
    中文:在解析前限制有效载荷: 在反向代理或网关处设置请求体限制,例如Nginx的 client_max_body_size。确保客户端无法绕过该层。FastAPI 在运行依赖项之前解析表单;在依赖项或端点中检查 UploadFile.size 并不能防止在解析过程中已经消耗的资源。
  • Treat Metadata as Untrusted: Do not use UploadFile.filename directly as a storage path or trust content_type as proof of file type. Apply the filename, content-validation, and storage controls in the File Upload Cheat Sheet.
    中文:将元数据视为不可信: 不要直接使用 UploadFile.filename 作为存储路径或信任 content_type 作为文件类型的证明。在 文件上传备忘单 中应用文件名、内容验证和存储控制。

Rate Limiting / 速率限制

Apply request limits to reduce abuse of sensitive or expensive endpoints.

应用请求限制以减少对敏感或昂贵的端点的滥用。

Mitigation Options / 缓解选项

  • Use a dedicated library like slowapi to implement route-specific rate limiting in code.
    中文:使用如 slowapi 这样的专用库在代码中实现特定路由的速率限制。
  • With multiple workers or replicas, use a shared counter store, such as Redis, so limits apply across instances instead of independently in each process.
    中文:在多个工作者或副本的情况下,使用共享计数存储,例如 Redis,以便限制适用于实例而不是每个进程独立应用。
  • Implement rate limiting at the reverse proxy (Nginx, HAProxy) or API gateway layer.
    中文:在反向代理(Nginx、HAProxy)或 API 网关层实现速率限制。

ASGI Server Hardening / ASGI 服务器加固

Configure the ASGI server's proxy trust explicitly so clients cannot spoof the client address or request scheme using forwarding headers. See the Uvicorn HTTP settings.

显式配置 ASGI 服务器的代理信任,以便客户端无法使用转发头欺骗客户端地址或请求方案。参见 Uvicorn HTTP 设置。

Deployment Configuration / 部署配置

  • Limit Proxy Forwarding: Set --forwarded-allow-ips to the addresses of trusted reverse proxies and configure those proxies to overwrite untrusted forwarding headers. Avoid --forwarded-allow-ips="*", which trusts every connecting client. Disable proxy-header handling with --no-proxy-headers if it is not needed.
    中文:限制代理转发: 将 --forwarded-allow-ips 设置为受信任反向代理的地址,并配置这些代理覆盖不受信任的转发头。避免使用 --forwarded-allow-ips="*",因为这信任了每个连接的客户端。如果不需要,使用 --no-proxy-headers 禁用代理头处理。
  • Disable Server Header: Use --no-server-header to suppress Uvicorn's default Server header. This removes one identifying header; it does not prevent other forms of server fingerprinting.
    中文:禁用服务器头: 使用 --no-server-header 来抑制 Uvicorn 的默认 Server 头。这移除了一个标识头;它不会阻止其他形式的服务器指纹识别。

References / 参考