PHP SQL 인젝션 방지

프리터코더·2025년 5월 25일
0

php 문제 해결

목록 보기
12/79

SQL 인젝션이란?

악의적인 SQL 구문을 삽입하여 데이터베이스를 비정상적으로 조작하는 공격 기법입니다.

안전한 데이터베이스 접근 방법

1. PDO Prepared Statements 사용

$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username AND password = :password");
$stmt->execute([
    'username' => $username,
    'password' => $hashedPassword
]);

2. MySQLi Prepared Statements

$stmt = $mysqli->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email);
$stmt->execute();

3. 입력값 검증

function validateInput($input) {
    return filter_var($input, FILTER_SANITIZE_STRING);
}

보안 클래스 구현

1. 데이터베이스 래퍼 클래스

class Database {
    private $pdo;
    
    public function query($sql, $params = []) {
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute($params);
        return $stmt;
    }
    
    public function select($table, $where = [], $fields = ['*']) {
        $sql = "SELECT " . implode(',', $fields) . " FROM " . $table;
        if (!empty($where)) {
            $sql .= " WHERE " . implode(' AND ', array_map(function($item) {
                return "$item = :$item";
            }, array_keys($where)));
        }
        return $this->query($sql, $where);
    }
}

실제 구현 예시

1. 로그인 처리

$stmt = $pdo->prepare("
    SELECT id, username 
    FROM users 
    WHERE username = :username 
    AND password = :password
");

$stmt->execute([
    'username' => $username,
    'password' => hash('sha256', $password)
]);

2. 데이터 삽입

$stmt = $pdo->prepare("
    INSERT INTO products 
    (name, price, description) 
    VALUES (:name, :price, :description)
");

$stmt->execute([
    'name' => $productName,
    'price' => $productPrice,
    'description' => $productDescription
]);

모범 사례

  • Prepared Statements 항상 사용
  • 입력값 검증 및 필터링
  • 최소 권한 원칙 적용
  • 에러 메시지 숨기기
  • 정기적인 보안 감사

보안 설정

// PDO 설정
$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
];

$pdo = new PDO($dsn, $username, $password, $options);
profile
일용직 개발자. freetercoder@gmail.com

0개의 댓글