🇰🇷 한글 설명
Five Star Restaurant Reservations 플러그인 2.7.16 이하 버전에서 PHP 느슨한 비교(==)를 이용한 결제 우회 취약점입니다. 인증되지 않은 공격자가 빈 payment_id를 전송하여 실제 결제 없이 예약을 '결제됨' 상태로 표시할 수 있습니다.
💡 쉬운 설명
WordPress 식당 예약 플러그인이 결제 확인을 제대로 하지 않아서, 결제하지 않고도 예약을 완료한 것처럼 만들 수 있는 버그입니다. 누구나 이 버그를 이용해 무료로 예약을 할 수 있습니다.
🇺🇸 원문 (English)
The Five Star Restaurant Reservations plugin for WordPress is vulnerable to a payment bypass via PHP type juggling in versions up to, and including, 2.7.16 This is due to the valid_payment() function using a PHP loose comparison (==) between the attacker-controlled payment_id POST parameter and the booking's stripe_payment_intent_id property. When an unauthenticated attacker submits a request to the nopriv AJAX handler rtb_stripe_pmt_succeed before the Stripe payment intent has been created for a booking (i.e., before the JavaScript-triggered create_stripe_pmtIntnt() call has stored an intent ID in post meta), the stripe_payment_intent_id property on the booking object remains null. The comparison sanitize_text_field('') == null evaluates to TRUE in PHP loose comparison, causing the payment verification check to pass with zero actual payment. This makes it possible for unauthenticated attackers to mark any existing payment_pending booking as paid without completing a Stripe payment by submitting an empty payment_id parameter.
📍 영향받는 시스템
Five Star Restaurant Reservations plugin version ≤ 2.7.16
⚔️ 공격 벡터
공격자가 rtb_stripe_pmt_succeed AJAX 핸들러에 빈 payment_id 파라미터를 POST로 전송하면 결제 검증을 우회할 수 있습니다.
🛡️ 대응 방법
플러그인을 2.7.17 이상으로 업그레이드하거나, valid_payment() 함수에서 strict comparison(===)을 사용하도록 수정하세요.
🔧 검증 코드
위 명령어로 플러그인의 결제 검증 함수를 찾을 수 있습니다. 느슨한 비교(==)가 있으면 취약하고, strict comparison(===)이면 안전합니다.
grep -r 'valid_payment\|stripe_payment_intent_id' /var/www/html/wp-content/plugins/five-star-restaurant-reservations/ 2>/dev/null | head -5