ป้องกัน WordPress REST API จากการถูกโจมตี

REST API ของ WordPress เปิดให้เข้าถึงข้อมูลบางอย่างโดยไม่ต้องล็อกอิน รู้ทันและป้องกันได้

ป้องกัน WordPress REST API จากการถูกโจมตี WordPress

WordPress REST API คืออะไร?

REST API (Representational State Transfer Application Programming Interface) ของ WordPress คือ Interface ที่ให้โปรแกรมหรือแอปพลิเคชันอื่น ๆ สามารถเข้าถึงข้อมูลของเว็บไซต์ WordPress ได้ผ่าน HTTP Requests โดยไม่ต้องเข้าไปยัง WordPress Admin Dashboard ตัวอย่าง เช่น:

REST API มี URL Endpoint ที่อยู่ในรูป https://yoursite.com/wp-json/wp/v2/ นี่คือ Entry Point หลักของ REST API ที่ให้เข้าถึงข้อมูล WordPress ต่าง ๆ

ช่องโหว่ของ REST API

REST API จะ Expose (เปิดเผย) ข้อมูลบางอย่างของเว็บไซต์ตามค่า Default ของ WordPress ซึ่งอาจเป็นปัญหาความปลอดภัย:

1. การเปิดเผยชื่อ Users

Endpoint /wp-json/wp/v2/users จะให้เข้าถึงรายชื่อผู้ใช้ที่มีสิทธิ์เป็น Author หรือสูงกว่า ผู้โจมตีอาจใช้ชื่อผู้ใช้นี้ไปพยายาม Brute Force Password

2. การเปิดเผยรายชื่อโพสต์

Endpoint /wp-json/wp/v2/posts จะให้เข้าถึงรายชื่อโพสต์ทั้งหมด รวมถึง Draft หรือ Scheduled Posts ซึ่งอาจเป็นข้อมูลที่ไม่อยากให้คนอื่นรู้

3. Plugin Endpoints ที่ไม่ปลอดภัย

Plugin บางตัวอาจสร้าง Custom REST Endpoints ที่ไม่มีการตรวจสอบสิทธิ์ (Authentication) อย่างถูกต้อง ทำให้ผู้โจมตีสามารถเข้าถึง หรือแก้ไขข้อมูลได้

4. Publicly Accessible Meta Data

Custom Meta Data (Custom Fields) ที่ถูก Mark เป็น "publicly accessible" จะแสดงผ่าน REST API ถ้า Custom Field มีข้อมูลที่ไม่อยากให้คนอื่นรู้ อาจจะเป็นปัญหา

วิธีปกป้อง REST API

วิธีที่ 1: ปิด REST API ทั้งหมด (สำหรับเว็บไซต์ที่ไม่ใช้)

หากเว็บไซต์ของคุณไม่ต้องใช้ REST API ตัวเลือกที่ง่ายที่สุดคือปิดมันทั้งหมด เพิ่มบรรทัดต่อไปนี้ลงใน functions.php ของธีม:

<?php
// ปิด REST API สำหรับผู้ใช้ที่ไม่ได้ Login
add_filter( 'rest_authentication_errors', function( $result ) {
    if ( ! empty( $result ) ) {
        return $result;
    }
    if ( ! is_user_logged_in() ) {
        return new WP_Error( 'rest_not_logged_in', 'You are not currently logged in.', array( 'status' => 401 ) );
    }
    return $result;
});
?>

บรรทัดนี้จะบอก WordPress ให้ปิด REST API สำหรับผู้ใช้ที่ไม่ได้ Login เฉพาะผู้ใช้ที่ Login เข้า WordPress Admin ทำการเข้าถึง REST API ได้

วิธีที่ 2: ปิด User Endpoint เพื่อป้องกันการเปิดเผยชื่อผู้ใช้

ถ้าต้องการให้ REST API ทำงาน แต่ปิด User Endpoint เพิ่มบรรทัดนี้ลงใน functions.php:

<?php
// ปิด User REST Endpoint
add_action( 'rest_api_init', function () {
    remove_post_type_support( 'users', 'rest-api' );
});
?>

วิธีที่ 3: ปิด Posts Endpoint เพื่อไม่ให้เปิดเผยรายชื่อโพสต์

หากต้องการปิด POST Endpoint แต่ยังให้ Plugin/App อื่นใช้ REST API:

<?php
// ปิด Posts REST Endpoint
add_action( 'rest_api_init', function () {
    remove_post_type_support( 'post', 'rest-api' );
});
?>

วิธีที่ 4: ใช้ .htaccess เพื่อบล็อก REST API

อีกวิธีหนึ่งคือใช้ .htaccess เพื่อบล็อก /wp-json/ URL จากผู้ที่ไม่ได้ Login เพิ่มบรรทัดต่อไปนี้ลงใน .htaccess ที่ root ของเว็บไซต์:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_URI} ^/wp-json/
    RewriteCond %{HTTP_AUTHORIZATION} ^$
    RewriteRule . - [F,L]
</IfModule>

บรรทัดนี้จะบล็อก /wp-json/ URL จากผู้ที่ไม่มี Authorization Header (ไม่ได้ส่ง Authentication Token)

วิธีที่ 5: ใช้ Plugin REST API Security Plugin

มีหลาย Plugin ที่ช่วยในการปกป้อง REST API เช่น:

Application Passwords สำหรับ REST API

ถ้าคุณต้องการให้แอปพลิเคชันภายนอกเข้าถึง REST API โดยปลอดภัย WordPress มีฟีเจอร์ "Application Passwords":

วิธีนี้ดีกว่าการใช้รหัสผ่าน WordPress จริงในแอปพลิเคชัน เพราะเมื่อต้องการยกเลิก Access ก็สามารถลบ Application Password นั้นได้โดยไม่ต้องเปลี่ยนรหัสผ่าน WordPress

ตรวจสอบข้อมูลที่เปิดเผยผ่าน REST API

วิธีตรวจสอบว่า REST API เปิดเผยข้อมูลใด:

  1. เปิด Browser และไปที่ https://yoursite.com/wp-json/wp/v2/users
  2. หากเห็นรายชื่อผู้ใช้ แสดงว่า User Endpoint ยังเปิดอยู่
  3. ลองไปที่ https://yoursite.com/wp-json/wp/v2/posts เพื่อเช็คว่า Posts Endpoint ยังเปิด
  4. ดูว่า Draft หรือ Scheduled Posts ขึ้นมาหรือไม่
Tip: หากเห็นข้อมูลที่ไม่อยากให้เปิดเผย ให้ปลั๊กอิน REST API Security Plugin หรือแก้ไข functions.php ตามวิธีที่ 1-4 ข้างบน

ตรวจสอบว่า REST API ทำงานถูกต้อง

หลังการปกป้อง REST API ให้ตรวจสอบว่ายังทำงานได้ถูกต้อง:

# 1. ตรวจสอบ REST API Endpoint (ผู้ใช้ที่ไม่ Login):
curl -s https://yoursite.com/wp-json/wp/v2/users | head -50
# ควรเห็น Error หรือข้อมูลเดือก ไม่ใช่รายชื่อผู้ใช้

# 2. ตรวจสอบ REST API เมื่อ Login:
# ลองเข้า WordPress Admin และเปลี่ยน "Application Password"
# แล้วลองเชื่อมต่อกับแอปพลิเคชัน

# 3. ทดสอบว่า Block Editor (Gutenberg) ยังทำงานได้หรือไม่
# เพราะ Block Editor ใช้ REST API โดยอัตโนมัติ
# ลองไปแก้ไขโพสต์แล้วดูว่ามี Error หรือไม่

# 4. ตรวจสอบ Logs ของ Hosting
# บาง Hosting Provider บันทึก REST API Requests
# ดูว่ามี 403 Forbidden Errors หรือไม่
Tip: Block Editor จำเป็นต้องใช้ REST API ในการทำงาน หากปิด REST API ทั้งหมด Block Editor อาจไม่ทำงาน แนะนำให้ใช้วิธีที่ 1 (ปิดเฉพาะผู้ที่ไม่ Login) แทน

แก้ปัญหาที่พบบ่อย

Error: "Block Editor ไม่โหลดหลังปิด REST API"

เพิ่มบรรทัด Code เพื่อปิด REST API แต่ตอนนี้ Block Editor ไม่ทำงาน

วิธีแก้: Block Editor ต้องใช้ REST API ในการทำงาน ถ้าปิด REST API ทั้งหมด Block Editor จะชำรุด แนะนำให้ใช้วิธีที่ 1 "ปิดเฉพาะผู้ที่ไม่ Login" แทน วิธีนี้ยังให้ Block Editor ทำงานได้ แต่ผู้ที่ไม่ได้ Login ไม่สามารถเข้าถึง REST API

Error: "แอปพลิเคชันที่ใช้ REST API หยุดทำงาน"

มี Mobile App หรือ Integration Tool ใช้ REST API ของเว็บไซต์ หลังปิด REST API มันหยุดทำงาน

วิธีแก้: ใช้ Application Passwords ให้แอปพลิเคชันเข้าถึง REST API ได้ ขั้นตอน: ไปที่ WordPress Admin > Users > Your Profile > Application Passwords > สร้าง Password ใหม่ แล้วให้แอปพลิเคชันใช้ Password นี้ในการ Authenticate

Error: "REST API ยังเปิดเผย User Names แม้ปิดไปแล้ว"

ปิด User Endpoint แล้ว แต่ยังสามารถเห็นชื่อผู้ใช้ได้ผ่านทาง Author Archives หรือ Author Pages

วิธีแก้: นี่เป็นปัญหาแยกต่างหาก REST API ไม่ใช่ช่องโหว่ตรงนี้ ชื่อผู้ใช้ถูกแสดงบนหน้าเว็บไซต์แบบปกติ ถ้าต้องการซ่อนชื่อผู้ใช้ให้พิจารณาใช้ Plugin "Hide My WP" หรือปิด Author Archives

Error: "ได้รับ 401 Unauthorized เมื่อใช้ REST API Application Password"

ลองเข้าถึง REST API โดยใช้ Application Password แต่ได้ 401 Error

วิธีแก้: ตรวจสอบว่า:

Error: "REST API Endpoint ที่สร้างจาก Plugin ไม่ปลอดภัย"

Plugin สร้าง Custom REST Endpoint โดยไม่มีการตรวจสอบสิทธิ์

วิธีแก้: ติดต่อผู้พัฒนา Plugin แล้วรายงาน Security Issue ให้เขาแก้ไข หรือใช้ .htaccess เพื่อปิด Endpoint นั้นจากผู้ที่ไม่ได้ Login


คำถามที่พบบ่อย

Q: ต้องปิด REST API หรือไม่?

A: ขึ้นอยู่กับเว็บไซต์ของคุณ หากใช้ Block Editor, WooCommerce App, หรือมี Integration Tool ต่างๆ ที่ใช้ REST API ให้ปล่อยไว้ แต่แนะนำให้ใช้วิธีที่ 1 "ปิดเฉพาะผู้ที่ไม่ Login" แทนการปิดทั้งหมด หากไม่ใช้ REST API เลย ปิดไว้ก็ได้เพื่อความปลอดภัยเพิ่มเติม

Q: Application Passwords นั้นปลอดภัยหรือไม่?

A: ได้ Application Passwords มีระบบ Hash อย่างดี และสามารถยกเลิกการใช้งานได้โดยไม่ต้องเปลี่ยนรหัสผ่าน WordPress หากแอปพลิเคชัน Compromised คุณเพียงแค่ลบ Application Password นั้นได้

Q: การปิด REST API จะทำให้ SEO ของเว็บไซต์ได้รับผลกระทบหรือไม่?

A: ไม่ การปิด REST API ไม่มีผลต่อ SEO เพราะ Search Engine Crawlers ไม่ใช้ REST API ในการ Index เนื้อหา พวกเขา Crawl HTML Pages แบบปกติ