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.
Como corrigir esta vulnerabilidade
Estratégias de prevenção para Improper Input Validation baseadas em 13 regras de detecção do 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 }));
Encontre vulnerabilidades no seu código
Use o Shoulder para escanear seu código em busca de padrões Improper Input Validation. 13 regras.
# Scan with Shoulder CLI npx @shoulderdev/cli trust --cwe=20 # Or scan entire project npx @shoulderdev/cli trust .
Regras de Detecção (13)
O que observar nas revisões de código
Estes padrões indicam vulnerabilidades potenciais de Improper Input Validation. Procure-os durante revisões de código e auditorias de segurança.
Escaneie seu código para Improper Input Validation
O Shoulder CLI encontra padrões vulneráveis em todo o seu código.