SQL 인젝션 101: SQLi란 무엇이며 공격을 방지하는 방법
2022년 8월 06일 • 보안
SQL 인젝션이란 무엇인가
SQL 인젝션(SQLi)은 범죄자가 취약한 웹 애플리케이션에 대해 악의적인 SQL 문을 실행할 수 있게 하는 공격 유형입니다. 공격자는 애플리케이션 보안 조치를 우회하여 고객 정보, 개인 데이터, 영업 비밀 등과 같은 민감한 데이터에 접근할 수 있습니다. 여기에서는 SQL 인젝션, 작동 방식, 공격을 방지하는 방법에 대해 논의할 것입니다.
SQL 인젝션 공격은 SQL 데이터베이스를 사용하는 모든 웹사이트에서 발생할 수 있습니다. 이 유형의 공격은 공격자가 중요한 데이터에 접근할 수 있게 합니다. 그들은 소비자 정보, 개인 데이터, 영업 비밀 및 지적 재산을 볼 수 있습니다. 이는 OWASP에 따르면 웹 애플리케이션에 대한 가장 심각한 공격 유형 중 하나입니다.
SQL 인젝션의 유형

인밴드 SQLi
In-band SQL injection is an attack where the attacker uses the same channel to send and receive queries. In-band means that the response is obtained using the same communications medium. The attacker’s goal is to get the response in a web browser immediately, if possible when carrying out the attack manually with a web browser.
인밴드 SQL 인젝션의 예
The most common way for an attacker to do an in-band SQL injection is to change the request so they can see the personal information of the current user. This can be done by changing the value sent as part of the request. For example, if the statement was supposed to display the user’s name, the attacker could change it so that their name is displayed instead.
SELECT * FROM 사용자 WHERE 사용자_아이디 LIKE '현재_사용자'
오류 기반 SQLi와 유니온 기반 SQLi는 인밴드 SQL 인젝션의 두 가지 가장 빈번한 형태입니다.
오류 기반 SQLi
An error-based SQLi technique is an in-band SQL injection approach that takes advantage of database server error messages to discover the database’s architecture. Error-based SQL injection is the most common type of in-band SQL injection.
오류 기반 SQLi의 예:
공격자가 다음 자격 증명을 사용하여 로그인하려고 시도하는 경우:
사용자 이름: ' OR 'a'='a비밀번호: anything
데이터베이스는 문법적으로 잘못된 문장 때문에 오류를 반환합니다. 오류 메시지는 공격자가 이점을 활용할 수 있는 데이터베이스에 대한 정보를 드러낼 것입니다.
유니온 기반 SQLi:
인밴드 SQL 인젝션은 두 개 이상의 SELECT 문 출력물을 결합하기 위해 UNION 연산자를 사용하는 웹사이트에서 정보를 얻는 방법입니다.
블라인드 SQL 인젝션
블라인드 SQL 인젝션은 공격자가 참 또는 거짓 응답을 유도하는 질문을 하여 데이터베이스에서 답변을 얻으려고 하는 공격입니다. 공격자는 특정 코드가 사용될 때 애플리케이션이 다르게 응답하는지 확인하기 위해 오류 메시지를 사용합니다.
해커가 SQL 인젝션을 사용할 때, 웹 애플리케이션은 SQL 쿼리 구문이 잘못되었다는 중요한 데이터베이스 경고 메시지를 표시할 수 있습니다. 블라인드 SQL 인젝션은 전통적인 SQL 인젝션과 동일한 방식으로 작동하지만 데이터베이스에서 데이터를 얻는 방법이 다릅니다. 데이터베이스에 공격자가 악용할 수 있는 충분한 정보가 없는 경우, 공격자는 데이터를 얻기 위해 일련의 질문을 해야 합니다.
블라인드 SQL 인젝션은 블라인드-불리언 기반 SQLi와 블라인드-시간 기반 SQLi로 나뉩니다.
불리언 기반 블라인드 SQLi
불리언 기반 블라인드 SQL 인젝션은 공격자가 참 또는 거짓 응답을 유도하는 질문을 하여 데이터베이스에서 답변을 얻으려고 하는 공격입니다. 공격자는 특정 코드가 사용될 때 애플리케이션이 다르게 응답하는지 확인하기 위해 오류 메시지를 사용합니다.
불리언 기반 블라인드 SQLi의 예:
공격자가 데이터베이스 유형을 알아내고 싶다면 다음 문장을 사용할 것입니다:
SELECT * FROM 사용자 WHERE 사용자_아이디 LIKE '현재_사용자' AND 데이터베이스() LIKE '%유형%'
데이터베이스가 MySQL인 경우 출력은 다음과 비슷할 것입니다:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘and database() like ‘%type%” at line
시간 기반 블라인드 SQL 인젝션
시간 기반 블라인드 공격은 쿼리가 더 느리게 실행되도록 하는 코드와 함께 SQL 명령이 서버에 전송될 때 발생합니다.
Time-based Blind attacks allow attackers to extract data based on access time. Such an attack is known as a blind or inferential injection assault. This is a type of assault in which no data flows between the attacker and the database, but because there is no response, it’s also known as a blind injection attack.
응답 시간은 답변이 올바른지 여부를 나타냅니다. 응답이 부정적이면 침입자는 다른 요청을 할 것입니다. 이 공격 기법은 해커가 특히 대규모 데이터베이스를 공격할 때 각 문자를 개별적으로 처리해야 하기 때문에 느립니다.
블라인드 SQLi의 예
이 예에서 공격자는 데이터베이스에 id=999인 사용자가 존재하는지 확인하려고 합니다. 이를 위해 다음 문장을 사용합니다:
IF(SUBSTRING((SELECT 비밀번호 FROM 사용자 WHERE 사용자_아이디=999),0, LEN('비밀'))='비밀', SLEEP(30), '거짓')
데이터베이스에 id 999인 사용자가 존재하고 비밀번호가 secret인 경우 애플리케이션은 30초 동안 대기할 것입니다. 데이터베이스에 사용자가 존재하지 않으면 애플리케이션은 false를 반환합니다.
아웃오브밴드 SQLi
데이터를 훔치려는 사람은 서버와 다른 컴퓨터 간의 일반적인 통신의 일부가 아닌 방식으로 데이터베이스 서버에 SQL 코드를 보낼 수 있습니다. 이는 DNS 또는 HTTP 요청을 통해 서버에 정보를 보내는 방식으로 수행될 수 있습니다.
The app’s response will not be affected by whether or not any data is returned, whether or not there is a problem with the database, or how long it takes to execute the query. Out-of-band can be used in network interactions to fire events at will. Depending on an injected condition, these may be activated conditionally to gain knowledge one bit at a time.
Data can also leak via several networking protocols from network interactions. The visual represents the request sent from the web application to the app’s database.
아웃오브밴드 SQLi의 예
이 예에서 공격자는 특정 사용자가 데이터베이스에 존재하는지 확인하려고 합니다. 이를 위해 다음 문장을 사용합니다:
SELECT user_id FROM users WHERE username='$username' AND password='$password' LIMIT 0,0 UNION SELECT NULL,'' INTO OUTFILE '/var/opt/databases/$filename.php'; --
데이터베이스에 사용자가 존재하면 애플리케이션은 사용자 ID를 반환합니다. 데이터베이스에 사용자가 존재하지 않으면 애플리케이션은 시스템 명령을 실행할 수 있는 PHP 코드가 포함된 파일을 생성합니다. 공격자는 이 파일을 사용하여 서버에서 명령을 실행할 수 있습니다.
SQL 인젝션 방지 방법
The best way to protect against SQL injection attacks is to use input validation, prepared statements, and parametrized queries. The code should never make direct use of the user’s input. Developers must sanitize all input instead of simply web form inputs such as login forms. Single quotes should be eliminated from any questionable code components. It’s also a good idea to hide database problems on live sites to avoid inadvertently revealing them. SQL injection may provide information about a database system that attackers can use to their advantage.
If you find a problem with your website, you should take it offline immediately and contact your hosting provider. They can help you determine whether or not your site has been compromised and what steps you need to take to fix the problem. In the meantime, ensure that all of your website’s users know about the problem and change their passwords as soon as possible.
SQL 인젝션을 피하기 위한 예방 팁
프로그래밍 언어와 데이터베이스 설정에서 SQL 인젝션 취약성을 피하는 몇 가지 방법이 있습니다. 이러한 기술은 XML과 같은 대부분의 데이터베이스에서 사용할 수 있습니다. 이러한 기술을 사용하여 데이터베이스를 더 안전하게 만들 수 있습니다.
1) 적절하게 구성된 저장 프로시저 사용
초보자는 변수로 문장을 생성하는 방법을 배우는 것으로 시작해야 합니다. 이는 동적 쿼리를 생성하는 것보다 쉽고 이해하기 쉽습니다. 매개변수화된 쿼리는 개발자가 모든 SQL 코드를 생성한 다음 나중에 각 매개변수를 제공하는 방법입니다. 이 방법은 데이터베이스가 소스 코드와 정보를 구별할 수 있게 합니다.
Prepared statements help ensure that a query’s goal is not changed, even if someone tries to give SQL instructions.
2) 허용 목록 입력 유효성 검사
SQL queries use bind variables in specific places for data. For example, if you’re using Python, you would use the %s 플레이스홀더. 정규 표현식을 사용하여 각 바인드 변수에 허용되는 문자에 대한 허용 목록과 사용자 입력을 검증할 수 있습니다.
If you’re using JavaScript, you can use \w 알파벳과 밑줄 문자를 일치시킵니다.
허용 목록은 오탐지를 피하기 위해 가능한 한 구체적이어야 합니다.
For example, if you’re looking for a US phone number, you would use the following regular expression:
/^\d{11}$/
This would match a string of 11 digits that could be a phone number. If someone tried to submit something like ‘abcdef‘, it would not match, and the input would be invalid.
This will help make sure your data is safe and sound. If you need to use values from code instead of user parameters, that’s okay too!
그러나 사용자 매개변수 값이 특정 테이블 및 열 이름을 대상으로 하는 경우, 매개변수 값은 검증되지 않은 사용자 입력이 쿼리에 들어가지 않도록 해당 테이블 및 열 이름에 매핑되어야 합니다.
3) 화이트리스트 사용
나쁜 문자의 블랙리스트를 기반으로 사용자 입력을 필터링하지 마십시오. 특정 필드에서 예상되는 좋은 문자의 허용 목록을 사용하는 것이 훨씬 더 효과적입니다. 이렇게 하면 SQL 인젝션 공격을 시작하기 전에 중지할 수 있습니다.
예를 들어, 전화번호를 기대하는 경우 입력 필드에 숫자와 대시만 허용하십시오. 이메일 주소를 기대하는 경우 이메일 주소에서 유효한 문자만 허용하십시오.
4) 최신 플랫폼 사용
PHP는 이전 웹 개발 플랫폼에서 SQLi 보호 기능이 없습니다. 사용 가능한 프로그래밍 환경, 언어 및 관련 기술의 최신 버전을 사용하십시오. 이 예에서는 PHP 대신 PDO를 사용하십시오.
5) 웹 애플리케이션을 정기적으로 스캔하십시오
SQL 인젝션은 매우 발견하기 어려울 수 있습니다. 정기적으로 웹 애플리케이션의 취약성을 스캔하는 것이 중요합니다.
6) 최소 권한 강제
최소 권한 원칙은 사용자가 작업을 수행하는 데 필요한 최소한의 액세스로 제한하는 보안 개념입니다. 여기에는 사용자가 가지고 있는 계정 수와 해당 계정이 가진 권한을 제한하는 것이 포함됩니다.
기능에 대한 최소 제한(LRF)은 사용자 권한, 계정 및 컴퓨팅 프로세스를 기본적이고 허용 가능한 작업에 필요한 리소스로만 제한하는 관행 및 개념입니다. 이는 사람들이 작업을 효과적으로 수행하는 데 필요한 최소한의 사용자 권한 또는 권한 수준을 유지하는 데 도움이 됩니다.
최소 권한은 애플리케이션, 시스템 및 장치가 특정 작업을 수행하는 데 필요한 권한만 가지도록 요구하는 보안 원칙입니다. 이렇게 하면 누군가가 취약점을 악용하여 피해를 입힐 경우 영향을 제한할 수 있습니다. 이는 사용자가 필요 이상으로 많은 권한을 부여받는 것과 대조되며, 이는 SQL 공격에서 심각한 피해의 위험을 증가시킵니다.
SQL Injection – Frequently asked questions
인밴드 SQL 삽입은 가장 일반적인 유형의 SQL 삽입 공격입니다. 공격자가 동일한 통신 채널을 사용하여 페이로드를 전달하고 결과를 수집할 수 있을 때 발생합니다.
SQL 삽입에 대한 최고의 방어는 매개변수화된 쿼리를 사용하는 것입니다. 이 유형의 쿼리는 매개변수에 대한 자리 표시자 값을 사용하며, 이는 나중에 제공됩니다. 이 방법은 데이터베이스가 소스 코드와 정보를 구별할 수 있도록 합니다.
SQL 인젝션은 여러 가지 방법으로 탐지할 수 있습니다. 한 가지 방법은 웹 애플리케이션 방화벽(WAF)을 사용하는 것입니다. WAF는 웹 애플리케이션과 인터넷 사이에 위치한 하드웨어 또는 소프트웨어입니다. 이는 악의적인 활동을 검사하고 SQL 인젝션 공격을 차단할 수 있습니다.
2차 SQL 인젝션은 공격자가 웹 애플리케이션에 의해 저장된 페이로드를 주입하고 나중에 실행될 수 있을 때 발생합니다. 이 유형의 공격은 저장된 페이로드의 실행을 트리거할 수 있는 방법이 필요하기 때문에 달성하기가 더 어렵습니다.
블라인드 SQL 인젝션은 공격자가 자신의 페이로드 결과를 직접 보지 않고 수행하는 공격입니다. 대신, 참 또는 거짓 문장을 사용하여 데이터베이스에서 정보를 추론해야 합니다. 이 유형의 공격은 실행하기 더 어려울 수 있지만 다른 유형의 SQL 인젝션만큼 위험할 수 있습니다.
스택 쿼리는 공격자가 여러 쿼리를 사용하여 데이터베이스에서 정보를 추출하는 SQL 인젝션의 한 유형입니다. 이 유형의 공격은 실행하기 더 어렵지만 성공하면 매우 위험할 수 있습니다.
오류 기반 SQL 인젝션은 공격자가 데이터베이스 오류를 사용하여 데이터베이스에서 정보를 추론하는 공격입니다. 이 공격은 실행하기 더 어려울 수 있지만 성공하면 매우 위험할 수 있습니다.
보안
admin은 정부 기술의 선임 스태프 작가입니다. 이전에는 PYMNTS와 베이 스테이트 배너에 글을 썼으며 카네기 멜론에서 문예창작 학사 학위를 받았습니다. 현재 보스턴 외곽에 거주하고 있습니다.