Improper Input Validation
The product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly.
Input validation is a frequently-used technique for checking potentially dangerous inputs in order to ensure that the inputs are safe for processing within the code, or when communicating with other components. When software does not validate input properly, an attacker is able to craft the input in a form that is not expected by the rest of the application.
Comment corriger cette vulnérabilité
Stratégies de prévention pour Improper Input Validation basées sur 13 règles de détection Shoulder.
Use Pydantic models with Field validators instead of raw Request objects
- from fastapi import FastAPI, Request - - app = FastAPI() - - @app.post("/users") - async def create_user(request: Request): - data = await request.json() - return {"user": data["username"]} + from fastapi import FastAPI + from pydantic import BaseModel, EmailStr, Field + + app = FastAPI() + + class UserCreate(BaseModel): + username: str = Field(min_length=3, max_length=50) + email: EmailStr + + @app.post("/users") + async def create_user(user: UserCreate): + return {"user": user.username}
Validate business-critical inputs with range constraints using Pydantic or manual checks
- from flask import request - - @app.route('/apply-discount', methods=['POST']) - def apply_discount_route(): - discount = float(request.form['discount']) - apply_discount(discount) + from pydantic import BaseModel, Field + from fastapi import FastAPI + + class DiscountRequest(BaseModel): + discount: float = Field(..., ge=0, le=100) + quantity: int = Field(..., gt=0) + + @app.post('/apply-discount') + async def apply_discount_route(req: DiscountRequest): + apply_discount(req.discount) return {'status': 'applied'}
Parse string inputs to typed values and validate against business rules before use
package main - import "net/http" - - func applyDiscount(w http.ResponseWriter, r *http.Request) { - discount := r.FormValue("discount") - // discount is a raw string, used without parsing or validation + import ( + "net/http" + "strconv" + ) + + func applyDiscount(w http.ResponseWriter, r *http.Request) { + discountStr := r.FormValue("discount") + discount, err := strconv.ParseFloat(discountStr, 64) + if err != nil { + http.Error(w, "Invalid discount format", http.StatusBadRequest) + return + } + if discount < 0 || discount > 100 { + http.Error(w, "Discount must be between 0 and 100", http.StatusBadRequest) + return + } total := price * (1 - discount/100) processOrder(total) }
Use Echo struct binding with validation tags instead of untyped maps
package main import "github.com/labstack/echo/v4" - func handler(c echo.Context) error { - var input map[string]interface{} - c.Bind(&input) - name := input["name"].(string) - return c.String(200, name) + type UserInput struct { + Name string `json:"name" validate:"required,min=2"` + Email string `json:"email" validate:"required,email"` + } + + func handler(c echo.Context) error { + var input UserInput + if err := c.Bind(&input); err != nil { + return c.JSON(400, map[string]string{"error": err.Error()}) + } + if err := c.Validate(&input); err != nil { + return c.JSON(400, map[string]string{"error": err.Error()}) + } + return c.String(200, input.Name) }
Use Fiber BodyParser with typed structs and validation tags
package main - import "github.com/gofiber/fiber/v2" - - func handler(c *fiber.Ctx) error { - var input map[string]interface{} - c.BodyParser(&input) - name := input["name"].(string) - return c.SendString(name) + import ( + "github.com/gofiber/fiber/v2" + "github.com/go-playground/validator/v10" + ) + + var validate = validator.New() + + type UserInput struct { + Name string `json:"name" validate:"required,min=2"` + Email string `json:"email" validate:"required,email"` + } + + func handler(c *fiber.Ctx) error { + var input UserInput + if err := c.BodyParser(&input); err != nil { + return c.Status(400).JSON(fiber.Map{"error": err.Error()}) + } + if err := validate.Struct(&input); err != nil { + return c.Status(400).JSON(fiber.Map{"error": err.Error()}) + } + return c.SendString(input.Name) }
Validate business-critical inputs with range checks before processing
app.post('/apply-discount', (req, res) => { - const discount = req.body.discount; - applyDiscount(discount); + const value = parseFloat(req.body.discount); + if (isNaN(value) || value < 0 || value > 100) { + return res.status(400).json({ error: 'Discount must be 0-100' }); + } + applyDiscount(value); });
Use server-side prices from the database and validate ranges for business-critical values
app.post('/api/orders', (req, res) => { - const { productId, quantity, price } = req.body; - const total = price * quantity; + const { productId, quantity } = req.body; + const product = products.get(productId); + if (!product) return res.status(404).json({ error: 'Product not found' }); + const total = product.price * quantity; orders.push({ total }); });
Add class-validator decorators to all DTO properties and enable the global ValidationPipe
- export class CreateUserDTO { - username: string; - email: string; - age: number; - } - - @Controller('users') - export class UserController { - @Post() - create(@Body() dto: CreateUserDTO) { - return this.userService.create(dto); - } - } + import { IsString, IsEmail, IsInt, Min, Max, MinLength } from 'class-validator'; + + export class CreateUserDTO { + @IsString() + @MinLength(3) + username: string; + + @IsEmail() + email: string; + + @IsInt() + @Min(0) + @Max(150) + age: number; + } + + // In main.ts: app.useGlobalPipes(new ValidationPipe({ whitelist: true }));
Trouvez les vulnérabilités dans votre code
Utilisez Shoulder pour scanner votre code à la recherche de patterns Improper Input Validation. 13 règles.
# Scan with Shoulder CLI npx @shoulderdev/cli trust --cwe=20 # Or scan entire project npx @shoulderdev/cli trust .
Règles de Détection (13)
Ce qu'il faut surveiller lors des revues de code
Ces patterns indiquent des vulnérabilités potentielles Improper Input Validation. Recherchez-les lors des revues de code et des audits de sécurité.
Scannez votre base de code pour Improper Input Validation
Shoulder CLI trouve les motifs vulnérables dans toute votre base de code.