본문 바로가기
보안&네트워크/보안

SQL Injection 방어 (바인딩 쿼리)

by kakk789 2023. 3. 17.

SQL Injection 방어

쿼리바인딩 과정 ( 파싱 과정을 1번만 거친다는 의미)

파싱 -> 바인드 -> 실행 -> 패치 (꺼내옴)

변수의 자리에 '?' 등을 사용, 바인딩 데이터는 SQL문법이 아닌 내부의 인터프리터나 컴파일 언어로 처리하기 때문에 문법적인 의미를 가질 수 없다. 따라서 바인딩 변수에 SQL공격 쿼리를 입력할지라도 의미있는 쿼리로 동작하지 않는 이유이다.

 Prepared Statement  사용시 쿼리 동작 방식

1. 파싱 (메모리에 올라감)

  • select 나이 from user where id = ? (물음표라는 바인딩 변수 사용)
  • 만약 Prepared Statement 사용 시 이 과정을 1번만 진행 함
    그니까, 이미 메모리에 올라가서 인간이 이해 가능한 있는 공격 문자열을 Injection 하려고 해도 의미가 없음.

2. 바인드(값을 변수로 치환)

  • 이 과정에서는 1번 파싱 때 DB 쿼리문이 이미 메모리에 올라가 있기에 매번 다른 값만 대입(바인딩)하여 사용 가능
  • 예시 ) 만약 100명의 사원정보를 출력하면 보통 사원 번호만 다를거다. 즉, 100개의 쿼리문이 생성되는데 사원번호만 다를 거기 때문에 사원번호를 바인딩해 변수로 만들고 1개의 쿼리문에 변수명만 바꾸는 것
  • 축약하면, 파싱 과정을 한번만 거친다는 의미, 원래 Prepared Statement 사용 안하면 이런 과정을 위에 예시로 예를 든다면 100번 해야함.

3. 실행

  • db 버퍼 캐시에서 데이터를 확인하고, 만약 존재하면 Fetch를하고, 없으면 버퍼캐시로 복사

4. Fetch

  • db버퍼 캐시에서 데이터 꺼내오기.

prepared statement

String sql = "INSERT INTO ROOM VALUES (?, ?, ?)";

PreparedStatement pstmt = conn.prepareStatement(sql);

// ?의 순서대로 값을 설정
// 문자열 : setString(물음표위치, 값)
//  정수  : setInt(물음표위치, 값)
pstmt.setInt(1, r_no);
pstmt.setString(2, r_type);
pstmt.setInt(3, r_fee);

pstmt.executeUpdate();
		String sql = "INSERT INTO ROOM VALUES (?, ?, ?)";

		..	
		..
		..
        
		PreparedStatement pstmt = conn.prepareStatement(sql);
		pstmt.setInt(1, r_no);
		pstmt.setString(2, r_type);
		pstmt.setInt(3, r_fee);

		int re = pstmt.executeUpdate();

 

* 참고 https://blog.naver.com/blogpyh/220675109307  https://ann-moon.tistory.com/35

반응형

'보안&네트워크 > 보안' 카테고리의 다른 글

주기적인 백도어 검사 방법  (0) 2023.03.21
대칭키의 개수 구하는 공식  (0) 2023.03.18
VDI (Virtual Desktop Infrastructure)  (0) 2022.02.11
세션 하이재킹  (0) 2022.01.24
Vitrual Address Space(VAS)  (0) 2022.01.17

댓글