[DB] SQL Injection: SELECT * FROM users WHERE username = '' OR '1'='1'; --' AND password = '' OR '1'='1';

2024. 1. 9. 10:00· Computer Science/Database
목차
  1. 💋 SQL Injection이란?
  2. 💋 SQL Injection의 종류
  3. ✔️ Classic SQL Injection
  4. ✔️ Union-based SQL Injection
  5. ✔️ Time-based Blind SQL Injection
  6. ✔️ Error-based SQL Injection
  7. 💋 SQL Injection 예방 방법
  8. ✔️ 꼼꼼한 입력 검증 (Input Validation)
  9. ✔️ Prepared Statements (Parameterized Queries)
  10. ✔️ ORM (Object-Relational Mapping) 사용
  11. ✔️ Stored Procedures 사용
  12. ✔️ 서버의 에러 메세지 노출 금지
  13. 💋 (참고) 정말로 Prepared Statements, ORM 쓰면 다 해결될까?
  14. 💋 참고자료
반응형
반응형

 

 

Computer Science 모아보기 👉🏻 https://github.com/seoul-developer/CS

 

GitHub - seoul-developer/CS: 주니어 개발자를 위한 전공 지식 모음.zip

주니어 개발자를 위한 전공 지식 모음.zip. Contribute to seoul-developer/CS development by creating an account on GitHub.

github.com

 

💋 SQL Injection이란?

SQL Injection은 악의적인 사용자가 웹 애플리케이션 또는 다른 소프트웨어를 공격하기 위해 사용되는 기법 중 하나입니다.

사용자로부터 입력받은 데이터를 통해 SQL 쿼리를 조작하여 데이터베이스에 무단으로 접근하거나 조작하는 공격을 의미합니다.

 

이미지 출처:  https://namu.wiki/w/SQL injection

 

💋 SQL Injection의 종류

✔️ Classic SQL Injection

 

예를 들어, 로그인 폼에 사용자가 입력한 아이디와 패스워드로 쿼리를 생성하는 경우를 생각해봅시다.

 

SELECT * FROM users WHERE username = '입력한아이디' AND password = '입력한패스워드';

 

여기에 아이디랑 패스워드에 ' OR '1'='1'; --를 입력하면 아래와 같은 쿼리가 생성되어 모든 사용자의 정보가 반환될 수 있습니다.

 

SELECT * FROM users WHERE username = '' OR '1'='1'; --' AND password = '' OR '1'='1';

 

✔️ Union-based SQL Injection

 

다른 테이블의 데이터를 가져오는 공격입니다. 예를 들어, URL 매개변수를 통해 페이지의 카테고리를 나타내는 경우,

 

SELECT * FROM products WHERE category_id = '입력한카테고리';

 

여기에 ' UNION SELECT null, username, password FROM users; --를 입력하면 사용자 테이블의 정보가 함께 나타날 수 있습니다.

 

✔️ Time-based Blind SQL Injection

 

딜레이 함수를 사용하여 서버의 응답 시간을 이용해 정보를 추출하는 공격입니다. 예를 들어, 아이디를 체크하는 쿼리에서 딜레이 함수를 삽입할 수 있습니다.

 

SELECT * FROM users WHERE username = '입력한아이디' AND IF(1=1, SLEEP(5), 0);

 

여기에 아이디에 ' OR IF(1=1, SLEEP(5), 0); --를 입력하면 서버는 5초 동안 응답을 지연시키면서 정보를 확인합니다.

 

✔️ Error-based SQL Injection

 

서버의 에러 메시지를 이용하여 정보를 추출하는 공격입니다. 아이디로 쿼리를 생성하는 경우,

 

SELECT * FROM users WHERE username = '입력한아이디';

 

여기에 아이디에 ' OR 1=CONVERT(int, (SELECT @@version)); --를 입력하면 에러 메시지를 통해 데이터베이스 버전을 확인할 수 있습니다.

 

💋 SQL Injection 예방 방법

✔️ 꼼꼼한 입력 검증 (Input Validation)

 

사용자의 입력을 검증하여 예상치 못한 문자열을 방지합니다.

특수문자나 SQL 예약어를 필터링하거나, 정규표현식을 사용하여 유효성을 확인할 수 있습니다.

 

# Python Flask에서의 입력 검증 예시
from flask import request

username = request.form['username']
password = request.form['password']

# 예상치 못한 문자나 SQL 예약어를 필터링
if not username.isalnum() or not password.isalnum():
	return "잘못된 입력입니다."

 

✔️ Prepared Statements (Parameterized Queries)

 

SQL 문장에 사용자 입력을 직접 삽입하는 대신, 매개변수를 사용하여 동적으로 쿼리를 생성합니다.

대부분의 프로그래밍 언어와 데이터베이스 라이브러리는 이를 지원합니다.

 

// Java에서의 Prepared Statements 사용 예시 (JDBC)
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, inputUsername);
pstmt.setString(2, inputPassword);
ResultSet result = pstmt.executeQuery();

 

✔️ ORM (Object-Relational Mapping) 사용

 

ORM 라이브러리를 사용하면 SQL 쿼리를 직접 작성하는 대신 객체와 데이터베이스 테이블 간의 매핑을 통해 데이터를 다룰 수 있습니다.

 

# Python SQLAlchemy ORM 사용 예시
from sqlalchemy import create_engine, Column, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

Base = declarative_base()

class User(Base):
	__tablename__ = 'users'
	id = Column(Integer, primary_key=True)
	username = Column(String)
	password = Column(String)

engine = create_engine('your_database_url')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

user = session.query(User)
.filter_by(username=inputUsername, password=inputPassword)
.first()

 

✔️ Stored Procedures 사용

 

데이터베이스에 저장된 프로시저를 사용하여 쿼리를 실행하면, 외부 입력에 직접 노출되지 않아 SQL 인젝션 공격을 예방할 수 있습니다.

 

-- 저장 프로시저 예시 (MySQL)
DELIMITER //
CREATE PROCEDURE AuthenticateUser(IN p_username VARCHAR(255), IN p_password VARCHAR(255))
BEGIN
	SELECT * FROM users WHERE username = p_username AND password = p_password;
END //
DELIMITER ;

 

이후에는 프로시저를 호출하여 사용자 인증을 수행합니다.

 

CALL AuthenticateUser('입력한아이디', '입력한패스워드');

 

✔️ 서버의 에러 메세지 노출 금지

에러 메시지에는 공격자에게 정보를 제공할 수 있는 내용이 들어있을 수 있기 때문에 민감한 정보를 노출하지 않도록 주의해야 합니다.

 

  1. 에러 메시지 일반화 (Generic Error Messages)
    • 에러가 발생했을 때 클라이언트에게 구체적인 내용을 보여주는 대신, 일반적이고 사용자 친화적인 에러 메시지를 표시합니다.
    • 예를 들어, "로그인에 실패했습니다"와 같은 메시지를 사용하여 구체적인 오류 내용을 감춥니다.
  2. 에러 로깅 (Error Logging)
    • 서버 측에서는 에러 로깅을 통해 시스템의 동작과 관련된 정보를 수집할 수 있습니다.
    • 사용자에게는 디버그 정보를 노출하지 않도록 조심해야 합니다.
    • 에러 로그는 시스템 관리자나 개발자에게만 접근 가능하도록 설정해야 합니다.
  3. Custom Error Pages 사용
    • 사용자가 에러를 발생시켰을 때 보여지는 페이지를 사용자 정의할 수 있습니다.
    • 일반적으로는 일반적이고 유용한 정보만을 담은 페이지로 리다이렉트하도록 설정합니다.
  4. 에러 정보 익명화 (Obfuscating Error Information)
    • 에러 메시지에 민감한 정보가 들어가지 않도록 신경 쓰는 것이 중요합니다.
    • 민감한 정보는 로깅되지 않도록 조치하고, 클라이언트에게는 일반적인 오류 메시지만을 전송하도록 설정합니다.
  5. 개발 환경에서의 디버그 모드 비활성화
    • 운영 환경에서는 디버그 모드를 꺼두어야 합니다.
    • 디버그 모드는 보다 상세한 에러 정보를 제공하는데, 공격자에게 유용한 정보가 될 수 있습니다.

 

💋 (참고) 정말로 Prepared Statements, ORM 쓰면 다 해결될까?

이 부분은 이리내씨의 댓글로 인해 문제 제기 후 추가되었습니다. 

한국 인터넷 진흥원의 자료 139~140쪽에 따르면, Prepared Statements, ORM을 사용하더라도 안전하지 않은 케이스가 있다고 하는데요...ㅋㅋㅌㅌ 

 

Prepared Statements을 사용하더라도 검증받지 않은 값을 그대로 사용할 경우에 위험합니다. 파라미터 바인딩 꼭 해야 합니당

출처: https://www.kisa.or.kr/2060204/form?postSeq=5&lang_type=KO&page=1#fnPostAttachDownload

 

꼭 안전하게 사용합시다!

 

출처: https://www.kisa.or.kr/2060204/form?postSeq=5&lang_type=KO&page=1#fnPostAttachDownload

 

💋 참고자료

  • https://www.youtube.com/watch?v=FoZ2cucLiDs
  • https://noirstar.tistory.com/264
  • https://namu.wiki/w/SQL injection
  • https://www.kisa.or.kr/2060204/form?postSeq=5&lang_type=KO&page=1#fnPostAttachDownload

 

도움이 되었다면, 공감/댓글을 달아주면 깃짱에게 큰 힘이 됩니다!🌟
비밀댓글과 메일을 통해 오는 개인적인 질문은 받지 않고 있습니다. 꼭 공개댓글로 남겨주세요!

 

반응형

'Computer Science > Database' 카테고리의 다른 글

[DB] MVCC(Multi Version Concurrency Control): 개념, 격리 수준 별 동작 방식 in MySQL & PostgreSQL  (0) 2024.01.11
[DB] Lock을 활용한 동시성 제어 (feat. 2PL Protocol)  (0) 2024.01.09
[DB] 동시성 제어(concurrency control) (2): recoverability, recoverable/cascadeless/strict schedule  (0) 2024.01.08
[DB] 동시성 제어(concurrency control) (1): serial/nonserial schedule, conflict equivalent, conflict serializable  (0) 2024.01.08
[DB] 트랜잭션 ACID란? (Atomicity, Consistency, Durability, Isolation)  (0) 2024.01.06
  1. 💋 SQL Injection이란?
  2. 💋 SQL Injection의 종류
  3. ✔️ Classic SQL Injection
  4. ✔️ Union-based SQL Injection
  5. ✔️ Time-based Blind SQL Injection
  6. ✔️ Error-based SQL Injection
  7. 💋 SQL Injection 예방 방법
  8. ✔️ 꼼꼼한 입력 검증 (Input Validation)
  9. ✔️ Prepared Statements (Parameterized Queries)
  10. ✔️ ORM (Object-Relational Mapping) 사용
  11. ✔️ Stored Procedures 사용
  12. ✔️ 서버의 에러 메세지 노출 금지
  13. 💋 (참고) 정말로 Prepared Statements, ORM 쓰면 다 해결될까?
  14. 💋 참고자료
'Computer Science/Database' 카테고리의 다른 글
  • [DB] MVCC(Multi Version Concurrency Control): 개념, 격리 수준 별 동작 방식 in MySQL & PostgreSQL
  • [DB] Lock을 활용한 동시성 제어 (feat. 2PL Protocol)
  • [DB] 동시성 제어(concurrency control) (2): recoverability, recoverable/cascadeless/strict schedule
  • [DB] 동시성 제어(concurrency control) (1): serial/nonserial schedule, conflict equivalent, conflict serializable
깃짱
깃짱
연새데학교 컴퓨터과학과 & 우아한테크코스 5기 백엔드 스타라이토 깃짱
반응형
깃짱
깃짱코딩
깃짱
전체
오늘
어제
  • 분류 전체보기
    • About. 깃짱
    • Weekly Momentum
      • 2024
    • PROJECT
      • AIGOYA LABS
      • Stamp Crush
      • Sunny Braille
    • 우아한테크코스5기
    • 회고+후기
    • Computer Science
      • Operating System
      • Computer Architecture
      • Network
      • Data Structure
      • Database
      • Algorithm
      • Automata
      • Data Privacy
      • Graphics
      • ETC
    • WEB
      • HTTP
      • Application
    • C, C++
    • JAVA
    • Spring
      • JPA
      • MVC
    • AI
    • MySQL
    • PostgreSQL
    • DevOps
      • AWS
      • 대규모 시스템 설계
    • frontend
      • HTML+CSS
    • NextJS
    • TEST
    • Industrial Engineering
    • Soft Skill
    • TIL
      • 2023
      • 2024
    • Linux
    • Git
    • IntelliJ
    • ETC
      • 日本語

블로그 메뉴

  • 홈
  • 깃허브

인기 글

최근 글

태그

  • 람다와스트림
  • 조합
  • 우아한테크코스
  • 예외
  • lamda
  • 우테코5기
  • 람다
  • 우아한테크코스5기
  • 스트림
  • 컴포지션
  • Stream
  • 함수형프로그래밍
  • 상속과조합
  • Composition
  • OOP
  • 상속
  • TDD
  • 우테코
  • Java
  • 레벨로그
hELLO · Designed By 정상우.v4.2.0
깃짱
[DB] SQL Injection: SELECT * FROM users WHERE username = '' OR '1'='1'; --' AND password = '' OR '1'='1';
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.