안녕하세요! 오늘은 SQL Injection에 대해서 알아보겠습니다. SQL Injection은 웹 응용 프로그램에서 발생할 수 있는 보안 취약점으로써 유저의 입력값으로 쿼리를 생성할 때 발생합니다. 그럼 어떠한 취약점과 해결법이 있는지 찾아볼까요?😯
학습자료 : 코딩애플 - SQL injection 공격
SQL Injection 공격 👿
🚨 절대로 따라 하시면 안됩니다. 이는 법적 준수와 윤리적 접근에 위반되는 행위입니다.
SQL Injection은 보통 사용자의 입력을 신뢰하는 웹에서 발생합니다. SQL Injection 공격이 가능한 사이트는 공통적인 반응이 있는데요, 로그인(ID, PASSWORD) 입력 창에서 ID 부분에 (임의의 사용자ID + ')를 입력한다면 syntax error와 같은 구문 오류 메시지가 발생합니다.
보통 관계형 DB에서 유저의 계정은 아래와 같은 쿼리문으로 작성될 것입니다.
SELECT * FROM accounts
WHERE id = '유저의 input id' AND pw = '유저의 input pw'
1. 강제 로그인
해당 웹사이트에서 한 유저의 ID를 알고있다고 가정했을 때 ID 입력부분에 해당 유저의 ID + '-- 를 입력하면 강제 로그인이 가능합니다. 이 원리는 아래의 쿼리문과 같습니다.
SELECT * FROM accounts
WHERE id = 'admin'--' AND pw = '유저의 input pw'
2. 관리자 권한
이번엔 ID 입력창에 유저의 ID' OR 1=1 -- 를 입력해 줍니다.
SELECT * FROM accounts
WHERE id = 'admin' OR 1=1 --' AND pw = '유저의 input pw'
1=1은 항상 True의 기능을 수행하기에 결과론적으로는 계정 테이블의 모든 내용을 조회할 수 있습니다. 이러한 상황에서 서버는 제일 첫번째 행의 계정 정보로 로그인을 하게 됩니다. 보통 첫번째 행의 계정은 개발자들의 관리 혹은 테스트 계정이며 이로 인해 관리자 권한의 기능을 수행할 수 있게 됩니다.
SQL Injection 예방 💊
SQL Injection을 예방하기 위한 방법으로는 여러가지가 있지만 대표적인 방법 3가지를 알아보겠습니다.
1. parameterized query
Parameterized Query는 SQL Injection 공격을 방어하기 위한 가장 효과적인 방법 중 하나입니다. 이 방법은 사용자 입력 값을 직접 SQL 쿼리에 삽입하는 대신, 매개 변수를 사용하여 쿼리를 실행합니다. 매개 변수는 사용자 입력을 처리하는 동안 자동으로 이스케이프됩니다. 이것은 SQL Injection에 대한 강력한 방어 기법으로, 다음과 같이 사용될 수 있습니다.
pool.query('SELECT FROM users WHERE id=' + 유저 input 값) -- X
pool.query('SELECT FROM users WHERE id?', [유저 input 값]) -- O
pool.execute('SELECT FROM users WHERE id=' + 유저 input 값) -- X
pool.execute('SELECT FROM users WHERE id?', [유저 input 값]) -- O
2. stored procedure
Stored Procedure는 데이터베이스에서 미리 정의된 프로시저 또는 함수로, SQL Injection 공격을 방어하는 데 도움이 됩니다. 애플리케이션 코드에서 데이터베이스에 SQL 쿼리를 직접 삽입하는 대신, 데이터베이스 내에서 저장 프로시저를 호출하도록 설계합니다. 저장 프로시저는 데이터베이스 서버에서 실행되므로 사용자 입력이 직접 쿼리로 들어가지 않아 SQL Injection을 예방할 수 있습니다.
※ 프로시저(Procedure) : 일련의 명령문을 하나로 그룹화한, 재사용 가능한 코드 블록
CREATE PROCEDURE citycount (IN country CHAR(3), OUT cities INT)
BEGIN
SELECT * FROM users WHERE CountryCode = country;
END
3. ORM
ORM은 SQL을 대신 작성해주는 라이브러리로, SQL Injection 공격을 방어하는 데 도움이 됩니다. ORM은 개발자가 직접 SQL 쿼리를 작성하는 대신, 객체 지향 방식으로 데이터베이스 조작을 처리합니다. ORM은 자동으로 SQL 쿼리를 생성하고 실행하며, 사용자 입력을 이스케이프하여 특정 문자나 문자열을 다른 의미나 역할을 가진 문자로 해석되지 않도록 처리하며 SQL Injection을 방지합니다.
ORM 종류로는 SQL Alchemy, JPA/Hibernate, Sequelize, TypeORM, prisma, Drizzle등이 있습니다.
SQL Injection 공격은 악의적인 공격으로 절대로 따라해서도 안되고 그로 인해 피해를 입어서도 안됩니다. 위 내용들은 기본적인 공격 및 예방법이라 생각되며 개개인의 정보는 매우 중요하기에 데이터베이스의 취약점을 발생시키지 않기 위해 수많은 노력이 필요하다는 생각이 들었습니다. SQL Injection을 이해하기 쉽게 설명해주신 코딩애플 유튜브에게 감사함을 느끼며 다른 분들도 도움이 되셨으면 좋겠습니다. 감사합니다!😉