1. Ghost CMS (Content Management System)
- 오픈소스 콘텐츠 관리 시스템 [1]
2. 취약점

- Content API에서 사용자 입력을 SQL 구문에 직접 삽입하여, 인증되지 않은 공격자가 데이터베이스에서 임의의 데이터를 읽을 수 있는 SQL Injection 취약점 (CVSS: 9.4)
> 해당 취약점과 Click-Fix 공격을 결합하여 웹 사이트의 관리자 API 키를 탈취한 뒤 웹 사이트에 악성 코드를 삽입 [3]
영향받는 버전
- Ghost 3.24.0 ~ 6.19.0 버전
- Ghost는 읽기 전용 공개 Content API인 /ghost/api/content/posts/를 제공하며, CONTENT_API_KEY를 사용해 요청을 인증
> CONTENT_API_KEY 값은 테마 HTML에 포함되어 있으므로, 사실상 공개되어 있는 상태
- slug-filter-order.js는 slug:[...] 형식의 사용자 입력을 정규표현식으로 추출한 후 쉼표(,)를 기준으로 분할하여 SQL ORDER BY절 내부의 CASE WHEN 구문 생성 [4]
> slug 값에 대한 적절한 검증 또는 매개변수 바인딩 없이 SQL 구문에 직접 포함하여 취약점이 발생
const slugFilterOrder = (table, filter) => {
let orderMatch = filter.match(/slug:\s?\[(.*)\]/);
if (orderMatch) {
let orderSlugs = orderMatch[1].split(',');
let order = 'CASE ';
orderSlugs.forEach((slug, index) => {
order += `WHEN \`${table}\`.\`slug\` = '${slug}' THEN ${index} `;
});
order += 'END ASC';
return order;
}
};
module.exports = slugFilterOrder;
- 만약 요청에 filter=slug:[post-1,post-2,'THEN 0 END ||,|| <INJECTION>||,||CASE WHEN'] 포함되어 있을 경우 CASE WHEN 구문은 다음과 같이 생성됨
CASE
WHEN `posts`.`slug` = 'post-1' THEN 0
WHEN `posts`.`slug` = 'post-2' THEN 1
WHEN `posts`.`slug` = '''THEN 0 END ||' THEN 2 -- 외부 CASE문을 닫고, 문자열 연결(concat)을 시작함
WHEN `posts`.`slug` = ' || <INJECTION> ||' THEN 3 -- <INJECTION> 구문이 스칼라 표현식으로 실행됨
WHEN `posts`.`slug` = ' || CASE WHEN'' THEN 4 -- 뒤에 올 END ASC를 흡수하기 위해 새로운 CASE문을 시작함
END ASC
- 따라서 공격자가 /ghost/api/content/posts/ 엔드포인트에 Content API Key와 조작된 slug 매개변수를 포함한 요청을 전송해 SQL Injection이 가능
> 이를 통해 데이터베이스 내 관리자 계정 정보, API Key, Session Secret 등의 민감 정보를 추출할 수 있음
[조작된 요청 예시]
GET /ghost/api/content/posts/?key=<CONTENT_API_KEY>&filter=slug:[post-1,post-2,'THEN 0 END ||,|| <INJECTION>||,||CASE WHEN']
3. 대응방안
- 벤더사 제공 업데이트 적용 [5][6][7]
> 매개변수 바인딩을 사용해 사용자 입력이 SQL 구문에 삽입되지 않도록 수정
| 취약점 | 제품명 | 영향받는 버전 | 해결 버전 |
| CVE-2026-26980 | Ghost | 3.24.0 ~ 6.19.0 버전 | 6.19.1 |
- 관리자 비밀번호 및 API 키, 세션 비밀 키 등 모든 비밀 키 변경
- CONTENT_API_KEY 값의 외부 노출 제한
- 탐지 정책 적용 및 모니터링
> slug:[ 또는 slug%3A%5B (URL 인코딩 형식) 뒤에 SQL 키워드(CASE, WHEN, THEN, END, ||, char( , SELECT, randomblob )가 포함된 모든 콘텐츠 API 요청을 차단 또는 경고
4. 참고
[1] https://ghost.org/
[2] https://nvd.nist.gov/vuln/detail/CVE-2026-26980
[3] https://blog.xlab.qianxin.com/ghost-cms-mass-compromised-via-cve-2026-26980-now-fueling-clickfix-attacks/
[4] https://github.com/TryGhost/Ghost/blob/v6.19.0/ghost/core/core/server/api/endpoints/utils/serializers/input/utils/slug-filter-order.js
[5] https://github.com/advisories/GHSA-w52v-v783-gw97
[6] https://github.com/TryGhost/Ghost/commit/30868d632b2252b638bc8a4c8ebf73964592ed91
[7] https://github.com/TryGhost/Ghost/releases/tag/v6.19.1
'취약점 > Injection' 카테고리의 다른 글
| LiteLLM SQL 인젝션 취약점 (CVE-2026-42208) (0) | 2026.05.12 |
|---|---|
| LMDeploy Vision-Language Module의 SSRF 취약점 (CVE-2026-33626) (0) | 2026.04.29 |
| sequelize SQL Injection 취약점 (CVE-2026-30951) (0) | 2026.03.18 |
| Apache Tika XML 외부 엔티티 인젝션 취약점 (CVE-2025-66516) (3) | 2025.12.28 |
| Fortinet FortiSIEM Command Injection 취약점 (CVE-2025-25256) (2) | 2025.08.19 |