
SureForms <= 2.2.0 - 인증되지 않은 저장형 크로스 사이트 스크립팅
SureForms 플러그인에 심각한 저장형 XSS 취약점이 존재합니다. 이 취약점은 entries.js에서 사용자 입력을 프로그래밍 방식으로 디코딩(서버 측 살균을 역전)한 후 적절한 클라이언트 측 살균 없이 dangerouslySetInnerHTML을 사용하여 렌더링하는 안전하지 않은 클라이언트 측 구현에서 비롯됩니다. 이를 통해 인증되지 않은 공격자는 표준 양식 필드를 통해 악성 JavaScript 페이로드를 주입하여 WordPress 기본 wp_kses 필터를 우회할 수 있습니다.
대상 사이트가 SureForms를 실행 중인지 확인하려면 일반적으로 버전 번호가 포함된 번역 파일 헤더를 검사하십시오.
대상 URL:
http://target-site.com/wp-content/plugins/sureforms/languages/sureforms.pot
확인 명령어:
curl -s "http://target-site.com/wp-content/plugins/sureforms/languages/sureforms.pot" | grep "Project-Id-Version"
취약점은 양식 항목을 보기 위한 React 기반 관리자 인터페이스(entries.js)에 있습니다.
축소된 entries.js 파일에는 HTML 엔티티를 처리하도록 설계된 헬퍼 함수(분석된 빌드에서 Xv로 식별됨)가 있습니다.
코드 로직 (재구성):
// 함수 Xv: 필드 값 전처리
var Xv = function(input) {
var value = input.value;
// 취약점 근본 원인:
// 문자열에 HTML 엔티티(예: <)가 포함된 경우 textarea를 생성하고,
// 내용을 삽입한 다음 값을 추출합니다.
// 이렇게 하면 HTML 엔티티가 효과적으로 원시 HTML 태그로 디코딩됩니다.
// 예: "<img ...>"가 ""가 됩니다.
if (typeof value === "string" && value.match(/&[a-zA-Z0-9#]+;/)) {
var textarea = document.createElement("textarea");
textarea.innerHTML = value;
// 살균을 되돌리는 로직
if (textarea.value.includes("<") || textarea.value.includes(">")) {
value = textarea.value; // 이제 'value'에는 원시 HTML이 포함됨
}
}
return { ...input, value: value };
}
분석: 이 함수는 백엔드 보안을 무력화합니다. WordPress가 데이터베이스에 <script>를 <script>로 올바르게 저장하더라도, 이 함수는 API에서 가져온 직후 다시 <script>로 변환합니다.
디코딩 후 데이터는 렌더링 구성 요소( Jv로 식별됨)로 전달됩니다.
코드 로직 (재구성):
// 함수 Jv: 필드 렌더링
var Jv = function(props) {
var field = props.field;
var val = field.value; // 이 값은 이제 원시 HTML입니다 (디코딩 후)
// 트리거: 문자열이 HTML처럼 보이는지 확인
if (typeof val === "string" && val.match(/<[^>]+>/g)) {
// 싱크: 클라이언트 측 살균(예: DOMPurify) 없이 dangerouslySetInnerHTML을 사용하여 렌더링
return React.createElement("span", {
dangerouslySetInnerHTML: { __html: val }
});
}
// HTML이 아닌 텍스트의 경우 안전하게 렌더링
return React.createElement("span", null, val);
}
주입: 인증되지 않은 공격자가 프런트엔드에서 양식을 제출합니다. 원시 HTML 태그(WordPress 백엔드에서 제거/살균됨)를 사용하는 대신 공격자는 HTML 엔티티를 보냅니다.
저장: WordPress는 입력(예: <img...)을 안전한 텍스트로 간주하여 데이터베이스에 저장합니다.
실행 (덫):
Xv 함수가 엔티티를 감지하고 <img...를 ` 항목으로 이동합니다.1단계에서 제출한 항목을 클릭하여 세부 정보를 확인합니다.
결과: 브라우저가 JavaScript 페이로드(alert('XSS_SUREFORMS'))를 실행합니다.