BETA Shoulder is in beta — Findings may sometimes be wrong. Your feedback shapes what we fix next. Share feedback
🔍

Improper Input Validation

🛡️ 13 rules detect this

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.

Prevalence
High
Frequently exploited
Impact
High
6 high-severity rules
Prevention
Documented
13 fix examples
2 Prevention
2 Prevention

How to fix this vulnerability

Prevention strategies for Improper Input Validation based on 13 Shoulder detection rules.

FastAPI Missing Request Validation MEDIUM

Use Pydantic models with Field validators instead of raw Request objects

+12 -8 python
- 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}
  
Business Logic Input Validation MEDIUM

Validate business-critical inputs with range constraints using Pydantic or manual checks

+10 -6 python
- 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'}
  
Business Logic Input Validation MEDIUM

Parse string inputs to typed values and validate against business rules before use

+16 -5 go
  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)
  }
  
Echo Missing Input Validation MEDIUM

Use Echo struct binding with validation tags instead of untyped maps

+14 -5 go
  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)
  }
  
Fiber Missing Input Validation MEDIUM

Use Fiber BodyParser with typed structs and validation tags

+21 -7 go
  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)
  }
  
Business Logic Input Validation MEDIUM

Validate business-critical inputs with range checks before processing

+5 -2 javascript
  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);
  });
  
Unvalidated Business-Critical Values HIGH

Use server-side prices from the database and validate ranges for business-critical values

+4 -2 javascript
  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 });
  });
  
NestJS DTO Missing Validation Decorators HIGH

Add class-validator decorators to all DTO properties and enable the global ValidationPipe

+17 -13 javascript
- 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 }));
  
3 Detection
3 Detection

Find vulnerabilities in your code

Use Shoulder to scan your codebase for Improper Input Validation patterns. 13 rules.

terminal
# Scan with Shoulder CLI
npx @shoulderdev/cli trust --cwe=20

# Or scan entire project
npx @shoulderdev/cli trust .

Detection Rules (13)

4 Warning Signs
4 Warning Signs

What to watch for in code reviews

These patterns indicate potential Improper Input Validation vulnerabilities. Look for these during code reviews and security audits.

🟠
Business-critical value extracted from user input without validation. This could allow attackers to manipulate prices, d javascript-unvalidated-business-values
🟠
business-critical values from user input used without validation javascript-unvalidated-business-values
🟠
DTO class '...' used in controller but lacks class-validator decorators. Unvalidated input may lead to injection attacks nestjs-dto-missing-validation
🟠
Prisma ... uses unvalidated user input. Validate and whitelist fields before passing to Prisma. prisma-missing-input-validation
🟠
Context creation uses raw request data without validation. Verify and validate all request data before adding to context trpc-context-injection
🟠
Procedure '...' accepts user input but lacks .input() validation. Add Zod schema to validate runtime data. trpc-missing-input-validation
🟠
Entity '...' accepts user input but lacks class-validator decorators. Add validation to prevent invalid data. typeorm-entity-validation-missing
🟡
FastAPI endpoints that accept raw Request objects instead of Pydantic models fastapi-missing-validation
🔍

Scan your codebase for Improper Input Validation

Shoulder CLI finds vulnerable patterns across your entire codebase.