베타 Shoulder는 베타 버전입니다 — 결과가 가끔 잘못될 수 있습니다. 여러분의 피드백이 다음에 무엇을 고칠지 결정합니다. 피드백 공유
🔍

Improper Input Validation

🛡️ 13 개의 규칙이 이를 탐지합니다

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.

보급률
높음
자주 악용됨
영향
높음
6개의 높은 심각도 규칙
예방
문서화됨
13개의 수정 예시
2 예방
2 예방

이 취약점을 수정하는 방법

13개의 Shoulder 탐지 규칙을 기반으로 한 Improper Input Validation 예방 전략.

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 탐지
3 탐지

코드에서 취약점 찾기

Shoulder를 사용하여 코드에서 Improper Input Validation 패턴을 스캔하세요. 13 규칙.

터미널
# Scan with Shoulder CLI
npx @shoulderdev/cli trust --cwe=20

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

탐지 규칙 (13)

4 경고 신호
4 경고 신호

코드 리뷰에서 주의할 점

이 패턴은 잠재적인 Improper Input Validation 취약점을 나타냅니다. 코드 리뷰와 보안 감사 중에 찾아보세요.

🟠
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
🔍

코드베이스를 스캔하세요: Improper Input Validation

Shoulder CLI는 전체 코드베이스에서 취약한 패턴을 찾아냅니다.