From 12f3ff45551d67a7c5657944bf7689ac1dd0fd73 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 22 Dec 2025 09:51:51 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[Security?= =?UTF-8?q?=20Enhancement]=20Add=20security=20middleware=20to=20API=20temp?= =?UTF-8?q?late=20(#154)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add security middleware to REST API template Adds `TrustedHostMiddleware` and `CORSMiddleware` to the FastAPI template to ensure basic security protections are in place. Includes comments guiding users on how to configure these for production. - Added TrustedHostMiddleware for Host header validation - Added CORSMiddleware for Cross-Origin Resource Sharing - Added TODOs for production configuration * feat: add security middleware to REST API template Adds `TrustedHostMiddleware` and `CORSMiddleware` to the FastAPI template to ensure basic security protections are in place. Includes comments guiding users on how to configure these for production. - Added TrustedHostMiddleware for Host header validation - Added CORSMiddleware for Cross-Origin Resource Sharing - Configured safe defaults (allow_credentials=False) for the template - Added TODOs for production configuration * feat: secure API template and fix Pydantic deprecations Enhances `rest-api-template.py` with standard security middleware and updates Pydantic usage to V2 standards. - Added `TrustedHostMiddleware` and `CORSMiddleware` with safe defaults - Updated Pydantic models to use `ConfigDict` and `model_dump()` to resolve deprecation warnings - Documented security learnings in sentinel journal --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- .jules/sentinel.md | 4 +++ .../assets/rest-api-template.py | 29 +++++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 .jules/sentinel.md diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000..c9d15f8 --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2024-05-23 - Default Security Middleware in FastAPI Templates +**Vulnerability:** Missing default security headers and CORS configuration in API templates. +**Learning:** Developers often copy templates directly into production. If templates lack security headers by default, new services will be insecure. +**Prevention:** Always include `TrustedHostMiddleware` and `CORSMiddleware` in API templates with strict comments on how to configure them for production. Use safe defaults where possible, but permissive defaults with warnings (like `*`) are acceptable for templates if clearly marked with TODOs. diff --git a/plugins/backend-development/skills/api-design-principles/assets/rest-api-template.py b/plugins/backend-development/skills/api-design-principles/assets/rest-api-template.py index 13f01fe..2a78401 100644 --- a/plugins/backend-development/skills/api-design-principles/assets/rest-api-template.py +++ b/plugins/backend-development/skills/api-design-principles/assets/rest-api-template.py @@ -4,8 +4,10 @@ Includes pagination, filtering, error handling, and best practices. """ from fastapi import FastAPI, HTTPException, Query, Path, Depends, status +from fastapi.middleware.cors import CORSMiddleware +from fastapi.middleware.trustedhost import TrustedHostMiddleware from fastapi.responses import JSONResponse -from pydantic import BaseModel, Field, EmailStr +from pydantic import BaseModel, Field, EmailStr, ConfigDict from typing import Optional, List, Any from datetime import datetime from enum import Enum @@ -16,6 +18,22 @@ app = FastAPI( docs_url="/api/docs" ) +# Security Middleware +# Trusted Host: Prevents HTTP Host Header attacks +app.add_middleware( + TrustedHostMiddleware, + allowed_hosts=["*"] # TODO: Configure this in production, e.g. ["api.example.com"] +) + +# CORS: Configures Cross-Origin Resource Sharing +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], # TODO: Update this with specific origins in production + allow_credentials=False, # TODO: Set to True if you need cookies/auth headers, but restrict origins + allow_methods=["*"], + allow_headers=["*"], +) + # Models class UserStatus(str, Enum): ACTIVE = "active" @@ -40,8 +58,7 @@ class User(UserBase): created_at: datetime updated_at: datetime - class Config: - from_attributes = True + model_config = ConfigDict(from_attributes=True) # Pagination class PaginationParams(BaseModel): @@ -74,7 +91,7 @@ async def http_exception_handler(request, exc): error=exc.__class__.__name__, message=exc.detail if isinstance(exc.detail, str) else exc.detail.get("message", "Error"), details=exc.detail.get("details") if isinstance(exc.detail, dict) else None - ).dict() + ).model_dump() ) # Endpoints @@ -96,7 +113,7 @@ async def list_users( status=UserStatus.ACTIVE, created_at=datetime.now(), updated_at=datetime.now() - ).dict() + ).model_dump() for i in range((page-1)*page_size, min(page*page_size, total)) ] @@ -147,7 +164,7 @@ async def update_user(user_id: str, update: UserUpdate): existing = await get_user(user_id) # Apply updates - update_data = update.dict(exclude_unset=True) + update_data = update.model_dump(exclude_unset=True) for field, value in update_data.items(): setattr(existing, field, value)