[SK shieldus Rookies 19기][애플리케이션 보안] SQL Injection 개요

Sungwuk·2024년 3월 26일
1

SQL Injection이란?

SQL 인젝션은 악의적인 사용자가 애플리케이션의 입력 필드를 통해 SQL 코드를 조작하거나 삽입할 수 있는 보안 취약점이다. 이 삽입은 무단 SQL 명령을 실행하거나 데이터베이스 데이터를 변경할 수 있다. SQL 인젝션 공격은 SQL 데이터베이스를 사용하는 웹 애플리케이션에 대한 가장 일반적인 공격 형태 중 하나이다.


출처: https://owasp.org/www-project-top-ten/

OWASP TOP 10에 의하면 2017-2021사이 가장 많이 발생한 웹 애플리케이션 취약점은 SQL Injection이므로 애플리케이션 보안에 기초라고 할 수 있다.

유형


Error Based SQL Injection

에러 기반 SQL 인젝션은 웹 응용 프로그램의 SQL 쿼리에서 발생하는 오류를 악용하여 데이터베이스의 구조에 관한 정보를 수집하는 공격 유형. 이 기술은 악의적인 SQL 코드를 입력 필드나 매개변수에 삽입하여 응용 프로그램이 데이터베이스에 대해 오류를 생성하도록 유도.

예)

에러 메세지를 토대로 공격자는 새로운 공격 쿼리를 만들 수 있다.

방어

DB 에러 메세지를 노출 시키지 않는다.


SQL Injection Based on ""="" is Always True

SQL Query를 항상 참으로 만들어준다.

예)

select * from members where id = 123 or 1 = 1

Union Based SQL Injection

기존 쿼리에 공격자가 원하는 UNION 구문 재조합하여 실행

예)

select * from members id = 123 and 1 = 2 UNION select 1, 2, 3, 4 from tables

여기서 UNION 뒤에 있는 쿼리는 공격자가 원하는 정보이다. and 1 = 2로 인해 앞 쿼리는 출력되지 않고 공격자가 원하는 쿼리만 출력된다.

Stored Procedure

sql에서 제공하는 프로그래밍 기능을 악용하여 정보를 조회한다.

예)

select * from members id = 123 ; exec xp_cmdshell 'cmd.exe /c dir'

이 구문 입력하면 c 드라이브에서 파일 탐색기가 열린다.

Blind SQL Injection

Blind SQL Injection은 참(True)인 쿼리문과 거짓(False)인 쿼리문 입력 시 반환되는 서버의 응답이 다른 것을 이용하여 이를 비교하여 데이터를 추출하는 공격이다. Blind SQL Injection은 다른 유형의 SQL Injection과 달리 추출하려는 실제 데이터가 눈에 보이지 않는다. 따라서 참 또는 거짓의 입력값에 따른 서버의 응답을 통해 값을 유추해야 한다.

작동 방식

취약한 예)

입력 필드


<!-- 로그인 폼 -->
<form action="login.php" method="post">
    <input type="text" name="username" placeholder="사용자명">
    <input type="password" name="password" placeholder="비밀번호">
    <button type="submit">로그인</button>
</form>

SQL Query


<?php
// 사용자가 제출한 로그인 폼에서 전달된 데이터 받기
$username = $_POST['username'];
$password = $_POST['password'];

// SQL 쿼리 생성 및 실행
//외부 입력값에 쿼리 조작 문자열 포함 여부를 확인하지 않고 문자열 결합 방식의 쿼리문 생성하고 있다.
$query = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$result = mysqli_query($connection, $query);
// 결과 처리
?>

SQL Injection 공격


username: ' OR '1'='1 
password: ' OR '1'='1

방어기법

  • 입력값에 쿼리 조작 문자열 포함 여부를 확인하고 사용

  • 오류 처리

  • 제거하고 사용

  • 안전한 형태로 변경해서 사용

  • PreparedStatement(Query Parameters)와 같은 구조화된 쿼리 실행(파라미터화된 쿼리 실행)을 보장하는 것을 사용

  • 오류 메시지에 상세한 내용(데이터베이스 및 쿼리 구조, 쿼리 실행과 관련한 프로그램 구조 등)이 포함되지 않도록 처리

  • 어플리케이션에서 사용하는 DB 사용자의 권한을 필요한 만큼의 최소한으로 부여


PreparedStatement를 통한 방어

<?php
// 사용자가 제출한 로그인 폼에서 전달된 데이터 받기
$username = $_POST['username'];
$password = $_POST['password'];

// 매개변수화된 쿼리 생성 및 실행
//변수 부분을 ?로 표시 (데이터 타입을 고려하지 않음 = 따움표를 포함하지 않음)
$query = "SELECT * FROM users WHERE username=? AND password=?";
//PreparedStatement 객체를 이용해서 미리 정의한 구조로 쿼리가 실해되는 것을 보장
//구조화된 쿼리 실행 또는 파라미터화된 쿼리 실행
$stmt = mysqli_prepare($connection, $query);
mysqli_stmt_bind_param($stmt, "ss", $username, $password);
mysqli_stmt_execute($stmt);
// 결과 처리
?>

이제 차근차근 String SQL Injection, Numberic SQL Injection, Blind SQL Injection, Blind String SQL Injection, UNION Based SQL Injection, Command Injection에 대해 알아보자

profile
https://github.com/John-Jung

0개의 댓글

관련 채용 정보