mirror of
https://github.com/wshobson/agents.git
synced 2026-03-18 17:47:16 +00:00
🛡️ Sentinel: [Security Enhancement] Add security middleware to API template (#154)
* 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>
This commit is contained in:
committed by
GitHub
parent
a86384334b
commit
12f3ff4555
4
.jules/sentinel.md
Normal file
4
.jules/sentinel.md
Normal file
@@ -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.
|
||||||
@@ -4,8 +4,10 @@ Includes pagination, filtering, error handling, and best practices.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException, Query, Path, Depends, status
|
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 fastapi.responses import JSONResponse
|
||||||
from pydantic import BaseModel, Field, EmailStr
|
from pydantic import BaseModel, Field, EmailStr, ConfigDict
|
||||||
from typing import Optional, List, Any
|
from typing import Optional, List, Any
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
@@ -16,6 +18,22 @@ app = FastAPI(
|
|||||||
docs_url="/api/docs"
|
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
|
# Models
|
||||||
class UserStatus(str, Enum):
|
class UserStatus(str, Enum):
|
||||||
ACTIVE = "active"
|
ACTIVE = "active"
|
||||||
@@ -40,8 +58,7 @@ class User(UserBase):
|
|||||||
created_at: datetime
|
created_at: datetime
|
||||||
updated_at: datetime
|
updated_at: datetime
|
||||||
|
|
||||||
class Config:
|
model_config = ConfigDict(from_attributes=True)
|
||||||
from_attributes = True
|
|
||||||
|
|
||||||
# Pagination
|
# Pagination
|
||||||
class PaginationParams(BaseModel):
|
class PaginationParams(BaseModel):
|
||||||
@@ -74,7 +91,7 @@ async def http_exception_handler(request, exc):
|
|||||||
error=exc.__class__.__name__,
|
error=exc.__class__.__name__,
|
||||||
message=exc.detail if isinstance(exc.detail, str) else exc.detail.get("message", "Error"),
|
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
|
details=exc.detail.get("details") if isinstance(exc.detail, dict) else None
|
||||||
).dict()
|
).model_dump()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Endpoints
|
# Endpoints
|
||||||
@@ -96,7 +113,7 @@ async def list_users(
|
|||||||
status=UserStatus.ACTIVE,
|
status=UserStatus.ACTIVE,
|
||||||
created_at=datetime.now(),
|
created_at=datetime.now(),
|
||||||
updated_at=datetime.now()
|
updated_at=datetime.now()
|
||||||
).dict()
|
).model_dump()
|
||||||
for i in range((page-1)*page_size, min(page*page_size, total))
|
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)
|
existing = await get_user(user_id)
|
||||||
|
|
||||||
# Apply updates
|
# Apply updates
|
||||||
update_data = update.dict(exclude_unset=True)
|
update_data = update.model_dump(exclude_unset=True)
|
||||||
for field, value in update_data.items():
|
for field, value in update_data.items():
|
||||||
setattr(existing, field, value)
|
setattr(existing, field, value)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user