SQL Injection(SQL 삽입)🤔
SQL Injection은 공격자가 애플리케이션의 데이터베이스를 악용하기 위해 SQL 쿼리를 조작하는 보안 취약점입니다.
공격자가 입력 필드나 URL 매개변수를 통해 악의적인 SQL 코드를 삽입하여 데이터베이스의 민감한 정보를 탈취하거나, 데이터를 삭제 및 수정하며, 심지어 시스템을 제어하는 행위로 이어질 수 있습니다.
SQL🤔
SQL(Structured Query Language)은 관계형 데이터베이스 시스템에서 자료를 관리 및 처리하기 위해 설계된 언어입니다. SQL은 데이터베이스의 데이터를 조회, 삽입, 수정, 삭제하는 데 사용되며, 관계형 데이터베이스 관리 시스템(RDBMS)에서 핵심적인 역할을 합니다.
💥SQL Injection 유형 및 동작 원리
SQL Injection은 다양한 형태로 발생할 수 있으며, 각각 고유한 동작 방식과 피해를 발생시킵니다.
1. Error based SQL Injection
가장 일반적인 형태로 사용자 입력을 통해 악의적인 쿼리를 삽입하는 방식입니다. 이 유형의 동작 원리는 사용자가 입력한 값이 그대로 SQL 쿼리에 삽입될 때 발생합니다.
SELECT * FROM users WHERE username = 'admin' AND password = 'password';
위 쿼리가 아래와 같은 Spring 코드로 작성되었다고 생각해 봅시다👀
String username = request.getParameter("username");
String password = request.getParameter("password");
String query = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "';";
공격자는 아래와 같은 방법으로 공격할 수 있습니다.
1️⃣ username 필드에 ' OR 1=1 -- 를 입력합니다.
2️⃣ 실제 실행되는 쿼리가 다음과 같이 변경됩니다.
3️⃣ SELECT * FROM users WHERE username = ' ' OR 1=1 --AND password = ' ';
- WHERE절에 있는 싱글 쿼터('')를 닫아주게 되고, OR 1=1로 WHERE절을 참을 만듭니다.
- --를 이용해 뒤의 모든 쿼리문을 주석 처리합니다.
4️⃣ 결과적으로 SELECT * FROM users를 통해 users 테이블에 있는 모든 user 정보에 대해 접근할 수 있습니다.
2. Blind SQL Injection
공격자가 데이터베이스에서 반환된 결과를 직접 확인할 수 없을 때 발생합니다.
데이터 베이스로부터 특정한 값이나 데이터를 전달받지 않고, 단순히 참/거짓을 판단하는 쿼리를 이용하여 서버의 데이터를 추론하는 공격 기법입니다.
공격자는 테이블에 특정 컬럼이 존재하는지 확인합니다. 이를 위해 다음과 같은 참/거짓 쿼리를 사용합니다.
1️⃣ 컬럼 존재 여부 확인
SELECT * FROM users WHERE id = 1 AND EXISTS (SELECT column_name FROM information_schema.columns WHERE table_name = 'users' AND column_name = 'username');
- 결과가 참이면 username 컬럼이 존재함을 의미합니다.
- 결과가 거짓이면 username 컬럼이 없음을 나타냅니다.
2️⃣ 결과가 거짓이라면 컬럼 이름을 추론하는 과정을 아래와 같이 반복합니다.
SELECT * FROM users WHERE id = 1 AND EXISTS (SELECT column_name FROM information_schema.columns WHERE table_name = 'users' AND column_name LIKE 'a%');
- LIKE 'a%'는 컬럼 이름이 a로 시작하는지 확인합니다.
- 공격자는 알파벳을 한 글자씩 변경하며 컬럼 이름 전체를 추론합니다.
3️⃣ 컬럼 이름을 식별했다면, 다음과 같은 쿼리를 사용해 해당 컬럼의 데이터를 추출할 수 있습니다.
SELECT username FROM users WHERE id = 1;
3. Union-Based SQL Injection
UNION SQL 연산자를 사용하여 여러 쿼리의 결과를 결합하여 데이터를 추출하는 방식입니다.
UNION 하려는 두 테이블의 컬럼 수와 데이터 형식은 같아야 합니다.
SELECT username, password FROM users WHERE id = 1 UNION SELECT version(), database();
공격자는 users 테이블에서 uswername과 password 컬럼 데이터를 조회하는 SELECT 구문에 추가 정보를 요청하는 쿼리문을 겹합해 보냅니다. 이 방법을 통해 공격자는 데이터베이스의 추가 정보를 포함한 결과를 획득할 수 있습니다.
💣SQL Injection 방어 방법
1. 입력값 검증
모든 사용자 입력값을 철저히 검증하여 허용된 값만 처리되도록 합니다.
- /, –, ‘, “, ?, #, (, ), ;, @, =, + 와 같은 특수 기호 필터링
- DB Query에 동적으로 영향을 주는 union, select 같은 명령어 필터링
2. 최소 권한 액세스 시행
사용자에게 역할에 필요한 만큼의 최소한의 권한만 부여해 SQL Injection 피해를 최소화합니다.
3. Prepared Statement 및 매개변수화된 쿼리 사용
Prepared Statement는 SQL 쿼리의 구조와 값을 분리하여 쿼리를 실행하는 방식입니다. 이를 통해 사용자 입력값이 SQL 코드로 해석되지 않도록 방지합니다.
동작 방식
- SQL 쿼리와 값의 분리: 쿼리 작성 시 ?와 같은 플레이스홀더를 사용하여 입력값이 삽입될 위치를 지정합니다.
- 입력값 바인딩: 플레이스홀더에 입력값을 매개변수로 바인딩합니다. 이 과정에서 입력값은 SQL 코드가 아닌 데이터로 처리됩니다.
- 쿼리 실행: 바인딩된 값이 포함된 쿼리를 안전하게 실행합니다.
'개발 공부 일지 > CS' 카테고리의 다른 글
[CS] CSRF(Cross-Site Request Forgery)란? (0) | 2025.01.11 |
---|---|
[CS] 반사형 XSS (Reflected Cross-Site-Scripting) (0) | 2025.01.10 |
[CS] 저장형 XSS (Stored Cross-Site-Scripting) (0) | 2025.01.09 |
[CS] XSS(Cross Site Scripting)란? (0) | 2025.01.09 |
주소창에 www.google.com을 검색하면 일어나는 일 (4) | 2024.12.23 |