첫 CVE 발급받기까지의 과정
방학 프로젝트로 CVE를 얻기 위해 patchstack에서 WordPress 플러그인에서 취약점을 찾기로 했다.
처음에는 감을 아예 못잡아서 여러 플러그인들의 코드를 계속 읽고 Docker로 WordPress를 빌드해서 테스트 해보고 블로그들을 읽으며 다른 사람들은 어떻게 취약점을 찾았는지 봤다.
몇주간 계속 그렇게 하다가 일정을 관리하는 event post라는 플러그인을 발견하고 여러 기능들이 있길래 분석해보기로 했다.
코드를 계속 읽어보니 POST로 사용자 입력을 받는데 필터링이나 escape를 거치지 않고 address 태그의 속성에 그대로 넣는 변수가 보였다.
public function print_location($post=null, $context='') {
$location = '';
if ($post == null)
$post = get_post();
elseif (is_numeric($post)) {
$post = get_post($post);
}
if (!isset($post->start)) {
$post = $this->retreive($post);
}
if ($post != false){
$address = $post->address;
$lat = $post->lat;
$long = $post->long;
$color = $this->get_post_color($post->ID, $this->settings['default_color'], true);
$icon = $this->DashIcons->icons[$this->get_post_icon($post->ID, $this->settings['default_icon'], true)];
$virtual_location = $post->virtual_location;
$attendance_mode = $post->attendance_mode;
if ($this->is_online($post) && $virtual_location) {
$location.="\t\t\t\t".'<div><a href="'.esc_url($virtual_location).'" class="eventpost-virtual-location-link" target="_blank" rel="noopener">'
.__('Join link', 'event-post')
.'</a></div>'
."\n";
}
if ($this->is_offline($post) && ($address != '' || ($lat != '' && $long != ''))) {
$location.="\t\t\t\t".'<address';
if ($lat != '' && $long != '') {
$location.=' data-id="' . $post->ID . '"
data-latitude="' . $lat . '"
data-longitude="' . $long . '"
data-marker="' . $this->get_marker($color) . '"
data-iconcode="' .$icon. '"
data-icon="' . mb_convert_encoding('&#x'.$icon.';', 'UTF-8', 'HTML-ENTITIES'). '"
data-color="#' . $color. '"';
}
$location.=' itemprop="adr" class="eventpost-address">'
. "\n\t\t\t\t\t\t\t".'<span>'
. "\n".$address
. "\n\t\t\t\t\t\t\t". '</span>';
if ($context=='single' && $lat != '' && $long != '') {
$location.="\n\t\t\t\t\t\t\t".'<a class="event_link gps dashicons-before dashicons-location-alt" href="https://www.openstreetmap.org/?lat=' . $lat .'&lon=' . $long . '&zoom=13" target="_blank" itemprop="geo">' . __('Map', 'event-post') . '</a>';
}
$location.="\n\t\t\t\t\t\t".'</address>';
if (wp_is_mobile() && $lat != '' && $long != '') {
$location.="\n\t\t\t\t\t\t".'<a class="event_link gps-geo-link" href="geo:' . $lat . ',' . $long . '" target="_blank" itemprop="geo"><i class="dashicons-before dashicons-location"></i> ' . __('Open in app', 'event-post') . '</a>';
}
}
}
return apply_filters('eventpost_printlocation', $location);
}
이 함수에서 $lat와 $long이 일정 장소를 위도와 경도로 받아서 지도로 나타내기 위한 변수들인데 POST로 받고 address 태그에 escape 없이 속성값으로 삽입된다.

이렇게 Location을 지정할 때 Latitude에 악성 스크립트를 삽입할 수 있다.
이때 address 태그에 onmouseover 속성이 있길래 Latitude에
" onmouseover="alert(1)"을 넣고
address 태그가 웹페이지 상에 있어야 되므로

Event List 위젯을 추가하고

Event date를 설정해 줬다.
그 후 글을 저장하고

빨간 동그라미 위에 마우스를 가져다 대면 XSS가 발생한다.
이때 Latitude에
" onmouseover="alert(1)">
이렇게 써서 태그 꺽쇠를 닫아주고 위젯에서

Events Timeline을 추가하면

이렇게 원래 있던 html 코드가 보이고 저기 위에 마우스를 가져다대면 XSS가 발생한다.
제보할 땐 이 방식으로 제보했다.
취약점이 1410줄에서 나왔다.
그 후 코드가 패치된 후 코드를 다시 보니
public function print_location($post=null, $context='') {
$location = '';
if ($post == null)
$post = get_post();
elseif (is_numeric($post)) {
$post = get_post($post);
}
if (!isset($post->start)) {
$post = $this->retreive($post);
}
if ($post != false){
$this->map_id++;
$address = $post->address;
$lat = $post->lat;
$long = $post->long;
$color = $this->get_post_color($post->ID, $this->settings['default_color'], true);
$icon = $this->DashIcons->icons[$this->get_post_icon($post->ID, $this->settings['default_icon'], true)];
$virtual_location = $post->virtual_location;
$attendance_mode = $post->attendance_mode;
if ($this->is_online($post) && $virtual_location) {
$location.="\t\t\t\t".'<div><a href="'.esc_url($virtual_location).'" class="eventpost-virtual-location-link" target="_blank" rel="noopener">'
.__('Join link', 'event-post')
.'</a></div>'
."\n";
}
if ($this->is_offline($post) && ($address != '' || ($lat != '' && $long != ''))) {
$location.="\t\t\t\t".'<address';
if ($lat != '' && $long != '') {
$geo_attributes = ' data-latitude="' . esc_attr($lat) . '"
data-longitude="' . esc_attr($long) . '"
data-marker="' . esc_attr($this->get_marker($color)) . '"
data-iconcode="' .esc_attr($icon). '"
data-icon="' . esc_attr(mb_convert_encoding('&#x'.$icon.';', 'UTF-8', 'HTML-ENTITIES')). '"
data-color="#' . esc_attr($color). '"
data-id="' . $post->ID . '-'.$this->map_id.'"';
$location.=' '.$geo_attributes;
}
$location.=' itemprop="adr" class="eventpost-address">'
. "\n\t\t\t\t\t\t\t".'<span>'
. "\n".$address
. "\n\t\t\t\t\t\t\t". '</span>';
if ($context=='single' && $lat != '' && $long != '') {
$location.="\n\t\t\t\t\t\t\t".'<a class="event_link gps dashicons-before dashicons-location-alt" href="https://www.openstreetmap.org/?lat=' . esc_attr($lat) .'&lon=' . esc_attr($long) . '&zoom=13" target="_blank" itemprop="geo" ' . $geo_attributes . '>' . __('Map', 'event-post') . '</a>';
}
$location.="\n\t\t\t\t\t\t".'</address>';
if (wp_is_mobile() && $lat != '' && $long != '') {
$location.="\n\t\t\t\t\t\t".'<a class="event_link gps-geo-link" href="geo:' . esc_attr($lat) . ',' . esc_attr($long) . '" target="_blank" itemprop="geo" ' . $geo_attributes . '><i class="dashicons-before dashicons-location"></i> ' . __('Open in app', 'event-post') . '</a>';
}
}
}
return apply_filters('eventpost_printlocation', $location);
}
esc_attr을 이용해 escape하는 코드가 추가됐다.
이 플러그인 말고 다른 플러그인에서 취약점 제보를 3개 정도 더 했는데 아쉽게도 다른 사람이 먼저 제보를 해버렸다.
취약점 등록 확정 이메일

CVE 발급 이메일

CVE details

https://nvd.nist.gov/vuln/detail/CVE-2025-26923
NVD - CVE-2025-26923
References to Advisories, Solutions, and Tools By selecting these links, you will be leaving NIST webspace. We have provided these links to other web sites because they may have information that would be of interest to you. No inferences should be drawn on
nvd.nist.gov
'project' 카테고리의 다른 글
| axios Prototype Pollution 1 day 취약점 분석 (0) | 2025.07.23 |
|---|---|
| CVE-2025-27415 1 day 취약점 분석 (0) | 2025.07.08 |
| CVE-2024-34343 1 day 취약점 분석 (0) | 2025.07.02 |
| Nodejs로 게시판을 만들면서 찾아봤던 것들[1] (0) | 2024.11.05 |