OWASP Juice Shop [SQL Injection]

2025. 12. 11. 13:21·취약점 진단

1. SQL Injection 취약점이란?


사용자 입력 데이터 값에 대해 검증 절차 미흡으로 인해 특정 SQL 명령어를 삽입하거나

변조할 경우 Database 내의 data를 조회할 수 있는 취약점을 말한다.
 
 
 
 

2. 취약점 예시


OWASP Juice Shop으로 로그인 후, 메인 페이지를 접근하면 

특정 URL 뒤에 [q] 파라미터를 전달하는 요청 패킷이 history에 남는 것을 볼 수 있다.

burp suite packet 분석

 

 

해당 파라미터에 임의의 값을 넣어보기도 하고 Jusice Shop에서 판매하는 품목 이름을

무작위로 입력해보니 응답 패킷이 돌아오는 것을 볼 수 있었다.

반환된 응답 패킷 결과

 

 

추가적으로 임의의 특수문자 값을 삽입하니 SQLite error 구문이 반환되는 것을 통해

해당 파라미터 내에 SQL injection을 구현하면 공격 가능한 부분이 있을 것 같아보인다.

SQL error 구문 반환

 

현재 [q] 파라미터 내에 입력된 값이 SQL query 문의 name 이라는 column 내에서 값을 받고 있으며

이 때 like 문을 통해 해당 값이 들어간 모든 구문에 대해 검색이 가능한 query문이 들어간 것을 볼 수 있다.

그렇다면 UNION SQL injection 구문을 통해 SELECT query문 뒤에 추가적인 구문을 이어넣어보도록 하자

 

 

 

위의 SQLite error 구문을 통해 사용하고 있는 DB table 이름이 Products 인 것을 알 수 있고 

현재 table 내 column의 개수가 몇개인지 파악되지 않은 상태이므로 UNION SELECT 구문 내에 

column 값을 무작위로 삽입하여 응답 패킷의 결과를 확인해본다.

apple'))UNION%20SELECT%201,2,3,4,5,6,7,8,9%20FROM%20Products--

 

 

UNION SELECT query문 Injection

 

위의 예시를 바탕으로 현재 연결된 데이터베이스에 존재하는 모든 table, index, view에 대한 정보를

하나의 특수한 시스템 테이블에 저장하는 sqlite_matser table의 정보를 확인해보도록 한다.

 

[sqlite_master 주요 column]

- type: 저장된 객체의 종류

- name: 객체의 이름

- tbl_name: 객체가 속한 테이블 이름

- sql: 객체 생성 시 사용된 CREATE 문

 

 

apple'))UNION%20SELECT%20sql,type,name,tbl_name,5,6,7,8,9%20FROM%20sqlite_master--

SQL injection을 통한 Users table 정보 유출

 

 

위에서 노출된 정보들을 바탕으로 사용자 table에 저장되 사용자 목록 정보들을 열람할 수 있는 것을 확인했다.

사용자 id, 이메일, 암호화된 password, OTP secret 정보 노출

 

 

 

3. 조치방안


취약한 code 확인

export function searchProducts () {
  return (req: Request, res: Response, next: NextFunction) => {
    let criteria: any = req.query.q === 'undefined' ? '' : req.query.q ?? ''
    criteria = (criteria.length <= 200) ? criteria : criteria.substring(0, 200)
    models.sequelize.query(`SELECT * FROM Products WHERE ((name LIKE '%${criteria}%' OR description LIKE '%${criteria}%') AND deletedAt IS NULL) ORDER BY name`)
      .then(([products]: any) => {
        const dataString = JSON.stringify(products)
        for (let i = 0; i < products.length; i++) {
          products[i].name = req.__(products[i].name)
          products[i].description = req.__(products[i].description)
        }
        res.json(utils.queryResultToJson(products))
      }).catch((error: ErrorWithParent) => {
        next(error.parent)
      })
  }
}

 

현재 취약한 부분은 SELECT query문 내에  '%${criteria}%' 부분이라는 것을 알 수 있다.
 
 

최종 조치 code

	export function searchProducts () {
		  return (req: Request, res: Response, next: NextFunction) => {
		    let criteria: any = req.query.q === 'undefined' ? '' : req.query.q ?? ''
		    criteria = (criteria.length <= 200) ? criteria : criteria.substring(0, 200)
	    models.sequelize.query(
	        `SELECT * FROM Products WHERE ((name LIKE '%:criteria%' OR description LIKE '%:criteria%') AND deletedAt IS NULL) ORDER BY name`,
	        { replacements: { criteria } }
	      ).then(([products]: any) => {
		        const dataString = JSON.stringify(products)
		        for (let i = 0; i < products.length; i++) {
		          products[i].name = req.__(products[i].name)
		          products[i].description = req.__(products[i].description)
		        }
		        res.json(utils.queryResultToJson(products))
		      }).catch((error: ErrorWithParent) => {
		        next(error.parent)
		      })
		  }
		}

 

 

위의 코드를 보면 Sequelize의 내장된 바인딩 메커니즘을 사용하여, DB에 query를 실행하기 전에

query 구조를 미리 템플릿처럼 정의하여 전송할 수 있게 된다.

 

다시 말해, 입력 받는 파라미터 내에 입력 구조를 선제적으로 구조화하는 것을 뜻한다. (Prepared Statement)

위의 {replacements: { criteria }} 라고 추가된 code를 통해 Sequelize는 이 입력값을 SQL 구문이 아닌,

순수 data로만 처리하도록 DB에게 전달하므로 사용자의 입력 내 SQL query문이 전달되는 경우를 차단할 수 있다.

 

 

 

 

반응형
저작자표시 (새창열림)

'취약점 진단' 카테고리의 다른 글

OWASP Juice Shop Mass Assignment  (0) 2025.12.11
OWASP Juice Shop [Redirect 취약점]  (0) 2025.12.11
OWASP Juice Shop [정보누출 취약점]  (0) 2025.12.11
Docker 사용법  (0) 2025.12.11
'취약점 진단' 카테고리의 다른 글
  • OWASP Juice Shop Mass Assignment
  • OWASP Juice Shop [Redirect 취약점]
  • OWASP Juice Shop [정보누출 취약점]
  • Docker 사용법
JNU
JNU
JNU의 보안공부
  • JNU
    JNU diary
    JNU
  • 전체
    오늘
    어제
  • 인기 글

    • 분류 전체보기 (105)
      • 네트워크 보안 (15)
      • 시스템 보안 (18)
      • 웹 보안 (16)
      • Frida (4)
      • Android (4)
      • 정보보안기사_산업기사 (1)
      • iOS (6)
      • Network (7)
      • 악성코드 분석 (10)
      • 침투테스트 (5)
      • Bandit 원정대 (4)
      • 대학원 (3)
      • AWS Cloud (3)
      • CVE (2)
      • Python (0)
      • Dreamhack (1)
      • 취약점 진단 (5)
      • 레드라쿤 CTI (1)
  • 06-09 04:58
  • hELLO· Designed By정상우.v4.10.5
JNU
OWASP Juice Shop [SQL Injection]
상단으로

티스토리툴바