วิธีป้องกัน GitHub Actions จากภัยเงียบ Poisoned Dependencies

9 นาที 14 views บันทึกเป็น PDF

รู้หรือไม่ว่าการใช้ GitHub Actions อาจมีภัยแฝง! มาเรียนรู้วิธีป้องกันโค้ดของคุณจากการถูกแอบแก้ไขด้วยการล็อกเลขรหัส Commit SHA ให้ปลอดภัยและมืออาชีพยิ่งขึ้น

ทำความรู้จักกับ GitHub Actions และภัยเงียบจากโค้ดภายนอก

เวลาที่เราเขียนโปรแกรมและเอาโค้ดไปเก็บไว้บน GitHub (เว็บไซต์สำหรับเก็บและจัดการซอร์สโค้ด) เรามักจะใช้ฟีเจอร์ที่เรียกว่า GitHub Actions (ระบบช่วยรันคำสั่งอัตโนมัติ เช่น การทดสอบโค้ดหรือการนำโค้ดขึ้นเซิร์ฟเวอร์) เพื่อทุ่นแรงให้เราไม่ต้องมานั่งทำทุกอย่างด้วยตัวเองซ้ำๆ ทุกครั้งที่อัปเดตโค้ดใหม่

ลองจินตนาการว่า GitHub Actions เหมือนกับลูกมือที่เราจ้างมาช่วยงานในโรงงาน ซึ่งลูกมือเหล่านี้มักจะเป็นโค้ดที่คนอื่นเขียนไว้ให้เราหยิบมาใช้ได้ฟรีๆ แต่นี่แหละคือจุดเสี่ยง เพราะถ้าวันหนึ่งลูกมือคนนี้ถูกเปลี่ยนตัวหรือถูกผู้ไม่หวังดีแอบเข้ามาแก้โค้ด งานที่เราไว้ใจให้เขารันก็อาจจะมีคำสั่งอันตรายแฝงมาด้วยโดยที่เราไม่รู้ตัว

ภัยนี้เราเรียกว่าการทำ Poisoned Dependencies (การใส่โค้ดอันตรายเข้าไปในส่วนประกอบที่เรานำมาใช้งาน) ซึ่งเปรียบเหมือนการที่เราไปซื้ออะไหล่รถยนต์จากร้านที่ดูน่าเชื่อถือ แต่ดันมีคนแอบเอาอะไหล่ปลอมที่พังง่ายไปวางปนไว้ ทำให้รถเราขับไปแล้วเกิดอุบัติเหตุกลางทางนั่นเอง

หากเราเป็นโปรแกรมเมอร์มือใหม่ การเข้าใจเรื่องนี้จะช่วยให้เราสร้างระบบที่ปลอดภัยตั้งแต่ต้น ไม่ใช่แค่เขียนโค้ดให้รันได้ แต่ต้องเขียนให้รันได้อย่างปลอดภัยด้วย เรามาดูกันว่าเราจะป้องกันปัญหานี้ได้อย่างไรบ้าง

ทำไมการใช้เลขเวอร์ชันแบบลอยตัวถึงอันตราย

ในการใช้งาน GitHub Actions หลายคนมักจะเขียนอ้างอิงถึงโค้ดคนอื่นด้วยเลขเวอร์ชัน เช่น @v4 ซึ่งเปรียบเหมือนการบอกลูกมือว่า "ไปหยิบอุปกรณ์รุ่น 4 มาให้หน่อย" โดยที่ระบบจะไปดึงโค้ดเวอร์ชันล่าสุดที่ถูกแปะป้ายชื่อว่า v4 มาใช้งานให้เราโดยอัตโนมัติ

ปัญหาคือป้ายชื่อเหล่านี้มัน เคลื่อนที่ได้ (Floating Tags) เพราะเจ้าของโค้ดสามารถสั่งเปลี่ยนได้ตลอดเวลาว่า v4 จะให้ชี้ไปที่โค้ดตัวไหน หากวันหนึ่งบัญชีของผู้พัฒนาคนนั้นถูกแฮ็กหรือถูกเปลี่ยนตัว คนร้ายก็สามารถแก้ไขโค้ดที่อยู่หลังป้าย v4 ให้กลายเป็นโค้ดขโมยข้อมูลได้ทันทีโดยที่เราไม่ต้องทำอะไรเลย

เรามาดูตัวอย่างการเขียนแบบที่เสี่ยงอันตรายกันครับ:

# ตัวอย่างการเขียนแบบเสี่ยงอันตราย
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4 # อันตราย เพราะ v4 เปลี่ยนโค้ดข้างในได้ตลอด
      - uses: actions/setup-node@v4 # อันตราย เพราะ v4 อาจถูกแอบแก้ได้ในอนาคต

คำอธิบายโค้ด:

  • uses คือคำสั่งบอกให้ไปดึงโค้ดคนอื่นมาใช้งาน
  • actions/checkout@v4 คือการบอกให้ใช้โค้ดชุดสำหรับดึงไฟล์จาก Repository (ที่เก็บโค้ดของโปรเจกต์) โดยใช้เวอร์ชัน 4
  • หากมีการอัปเดตเวอร์ชัน 4 ให้เป็นโค้ดใหม่ ระบบของเราจะรันโค้ดใหม่นั้นทันทีโดยไม่ได้ตรวจสอบก่อน

ผลลัพธ์ที่เกิดขึ้น: ทุกครั้งที่คุณสั่งรัน Workflow (ขั้นตอนการทำงานอัตโนมัติ) ระบบจะไปดึงเวอร์ชันล่าสุดของ v4 มาใช้เสมอ ซึ่งถ้าเจ้าของโปรเจกต์แอบใส่โค้ดขโมยรหัสผ่านเข้าไป คุณก็จะโดนขโมยไปโดยไม่รู้ตัว

วิธีป้องกันด้วยการล็อกเลขรหัส Commit SHA

วิธีแก้ปัญหาที่ง่ายและได้ผลดีที่สุด คือการใช้ Commit SHA (รหัสตัวเลขและตัวอักษร 40 หลักที่ระบุเวอร์ชันของโค้ดแบบถาวร) แทนที่จะใช้เลขเวอร์ชันแบบลอยตัว การใช้รหัสนี้เปรียบเหมือนการระบุเลขบัตรประชาชนของโค้ดตัวนั้นๆ ลงไปเลย ไม่ว่าใครจะพยายามเปลี่ยนป้ายชื่อเวอร์ชันยังไง โค้ดของเราก็จะหยิบเฉพาะตัวเดิมที่เราเคยตรวจสอบแล้วมาใช้งานเสมอ

การทำแบบนี้จะทำให้ Workflow ของเรามีความคงที่ (Immutable) คือไม่มีวันเปลี่ยนเองจนกว่าเราจะเป็นคนเปลี่ยนมันด้วยตัวเอง นี่คือมาตรฐานความปลอดภัยที่มืออาชีพทุกคนต้องทำในการเขียน CI (ขั้นตอนการตรวจสอบโค้ดอัตโนมัติ)

เรามาดูตัวอย่างการเขียนแบบที่ปลอดภัยกันครับ:

# ตัวอย่างการเขียนแบบปลอดภัย
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # ล็อกด้วยรหัส SHA 40 หลัก เพื่อความปลอดภัยสูงสุด
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
      - uses: actions/setup-node@4992456781334f2795ae9dd169f5041797d85689 # v4.4.0

คำอธิบายโค้ด:

  • รหัสยาวๆ เช่น 11bd7190... คือ Commit SHA ที่ระบุตัวตนของโค้ดเวอร์ชันนั้นๆ อย่างชัดเจน
  • เรายังใส่คอมเมนต์ # v4.2.2 ไว้ข้างหลังเพื่อให้มนุษย์อ่านเข้าใจง่าย แต่ตัวระบบจะรันตามรหัส SHA เท่านั้น
  • หากมีการแอบแก้โค้ดใน v4.2.2 รหัส SHA นี้จะไม่ตรงกับของใหม่ และระบบจะไม่รันโค้ดที่ผิดปกติให้เรา

ผลลัพธ์ที่เกิดขึ้น: ระบบจะดึงโค้ดเวอร์ชันที่ระบุไว้เป๊ะๆ มาใช้งาน หากโค้ดต้นทางถูกแก้ไขจนรหัสไม่ตรงกัน GitHub จะหยุดทำงานหรือแจ้งเตือนทันที ช่วยป้องกันการถูกแอบเปลี่ยนโค้ดได้ 100%

ใช้งาน Dependabot เพื่ออัปเดตอย่างมั่นใจ

เมื่อเราล็อกโค้ดด้วยรหัส SHA แล้ว เราก็ต้องคอยอัปเดตเป็นระยะเพื่อให้ได้ฟีเจอร์ใหม่หรือแก้ไขบั๊ก แต่การนั่งไล่เปลี่ยนรหัสเองทุกครั้งก็เป็นเรื่องที่น่าปวดหัวและเสี่ยงต่อการลืม นี่คือหน้าที่ของ Dependabot (บอทของ GitHub ที่คอยตรวจสอบและอัปเดตโปรแกรมให้เรา)

เราสามารถตั้งค่าให้ Dependabot คอยตรวจดูว่ามีเวอร์ชันใหม่ของ Actions ออกมาหรือยัง ถ้ามี บอทจะสร้างการแจ้งเตือนแบบ Pull Request (การขอรวมโค้ดใหม่เข้าโปรเจกต์) ให้เราเข้าไปรีวิวโค้ดก่อนกดตกลงอัปเดต วิธีนี้ทำให้เรามั่นใจว่าทุกการเปลี่ยนแปลงผ่านสายตาเราก่อนเสมอ

วิธีตั้งค่าให้สร้างไฟล์ .github/dependabot.yml ไว้ในโปรเจกต์ของคุณ:

version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly" # ให้บอทตรวจทุกสัปดาห์

คำอธิบายโค้ด:

  • package-ecosystem: "github-actions" บอกให้บอทโฟกัสแค่เรื่อง Actions เท่านั้น
  • interval: "weekly" คือการตั้งให้บอททำงานทุกสัปดาห์ เพื่อไม่ให้เราโดนแจ้งเตือนถี่เกินไปจนรำคาญ
  • เมื่อบอทพบเวอร์ชันใหม่ มันจะสร้าง Pull Request ให้เราเข้าไปตรวจสอบรหัส SHA ใหม่ก่อนกด Merge (รวมโค้ด)

ผลลัพธ์ที่เกิดขึ้น: คุณจะได้รับการแจ้งเตือนอัตโนมัติเมื่อมีเวอร์ชันใหม่ ทำให้การอัปเดตโค้ดเป็นเรื่องปลอดภัยและเป็นระเบียบ ไม่ต้องกังวลว่าจะพลาดโค้ดอันตรายที่แอบแฝงมา

จำกัดขอบเขตการใช้งานด้วย Allowlist

นอกจากการล็อกรหัสแล้ว เรายังสามารถจำกัดได้ว่า Workflow ของเราอนุญาตให้ดึงโค้ดมาจากใครได้บ้าง ซึ่งเรียกว่าการทำ Allowlist (รายการที่อนุญาตให้ผ่านได้) เพื่อไม่ให้ใครก็ตามในทีมเผลอไปดึงโค้ดจากแหล่งที่ไม่น่าเชื่อถือมาใช้งานในระบบของเรา

การทำแบบนี้เปรียบเหมือนการตั้งระบบรักษาความปลอดภัยที่หน้าประตูโรงงาน ที่จะให้เฉพาะพนักงานที่ลงทะเบียนไว้เท่านั้นที่เดินเข้ามาได้ การทำเช่นนี้จะช่วยลดความเสี่ยงจากการที่คนในทีมอาจจะเผลอไปใช้ Action ที่มีชื่อคล้ายกับของจริงแต่เป็นของปลอม (Typosquatting)

คุณสามารถตั้งค่าได้ที่เมนู Settings ของโปรเจกต์หรือระดับองค์กร:

  • ไปที่ Settings > Actions > General
  • เลือก Allow specified actions
  • ระบุชื่อผู้สร้างที่เชื่อถือได้ เช่น actions/* หรือ my-org/*

ข้อควรระวัง: การทำ Allowlist ไม่ได้แปลว่าคุณไม่ต้องล็อกเลข SHA นะครับ มันเป็นเพียงด่านแรกที่ช่วยกรองของปลอมออกไป แต่ในด่านที่สอง คุณก็ยังต้องใช้รหัส SHA ล็อกโค้ดตัวที่อนุญาตแล้วอยู่ดี เพื่อความปลอดภัยสองชั้น

สรุป: สร้างระบบที่ปลอดภัยเริ่มจากจุดเล็กๆ

การป้องกัน Poisoned Dependencies ไม่ใช่เรื่องไกลตัวหรือเรื่องของคนเก่งเท่านั้น แต่มันคือ พื้นฐานความรับผิดชอบ ของโปรแกรมเมอร์ทุกคนที่ต้องใส่ใจตั้งแต่เริ่มเขียนโค้ด การใช้เลขเวอร์ชันแบบลอยตัวอาจจะดูสะดวก แต่ความเสี่ยงที่ตามมานั้นไม่คุ้มค่าเลยกับการที่โค้ดหรือข้อมูลของลูกค้าต้องหลุดออกไป

สรุปขั้นตอนง่ายๆ ที่คุณนำไปใช้ได้วันนี้เลย:

  1. เปลี่ยนจากการใช้ @v4 มาเป็นการใช้รหัส Commit SHA 40 หลักแทน
  2. ใส่คอมเมนต์ระบุเวอร์ชันที่แท้จริงไว้ท้ายบรรทัดเพื่อให้อ่านง่าย
  3. เปิดใช้งาน Dependabot เพื่อให้มันช่วยแจ้งเตือนตอนมีอัปเดต
  4. คอยตรวจสอบ Pull Request ทุกครั้งก่อนกด Merge เข้าสู่โปรเจกต์

ตัวอย่างการนำไปใช้จริง: สมมติว่าคุณกำลังทำโปรเจกต์เว็บแอปพลิเคชันแรกในชีวิต แทนที่จะเขียน uses: actions/checkout@v4 ให้คุณไปดูที่หน้าเว็บของ actions/checkout ใน GitHub แล้วก๊อปปี้รหัส SHA ของเวอร์ชันล่าสุดมาแปะแทน เท่านี้คุณก็เป็นโปรแกรมเมอร์ที่ใส่ใจเรื่องความปลอดภัยมากกว่าคนทั่วไปแล้วครับ เริ่มต้นจากจุดเล็กๆ แบบนี้จะทำให้คุณเป็นโปรแกรมเมอร์ที่เก่งและน่าเชื่อถือในสายตาของเพื่อนร่วมทีมแน่นอน


ที่มา: How to Prevent Poisoned GitHub Actions Dependencies — freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

แชร์บทความ

Facebook X LINE

บทความที่เกี่ยวข้อง

จัดการเซิร์ฟเวอร์ผ่าน VS Code ให้ง่ายขึ้นด้วย Easy SSH พร้อมฟีเจอร์โหลดไฟล์ผ่านคลิกเดียว

จัดการเซิร์ฟเวอร์ผ่าน VS Code ให้ง่ายขึ้นด้วย Easy SSH พร้อมฟีเจอร์โหลดไฟล์ผ่านคลิกเดียว

เบื่อไหมที่ต้องสลับหน้าจอไปมาเพื่อจัดการเซิร์ฟเวอร์? มาลองใช้ Easy SSH ปลั๊กอิน VS Code ที่ช่วยให้คุณรีโมทผ่าน Terminal ได้สะดวก แถมโหลดไฟล์ได้ง่ายแค่กด Ctrl+click

ที่มา: DEV Community

4 hours ago 11 นาที
3 views
วิธีดึงข้อมูลราคาจาก Google Hotels ด้วย API สำหรับนักพัฒนา

วิธีดึงข้อมูลราคาจาก Google Hotels ด้วย API สำหรับนักพัฒนา

อยากทำแอปท่องเที่ยวแต่ดึงข้อมูลราคาจาก Google Hotels ไม่ได้? มาดูวิธีใช้ Apify Actor ช่วยดึงข้อมูลแบบอัตโนมัติด้วย Python ง่ายๆ ไม่ต้องกลัวเว็บพัง

ที่มา: DEV Community

7 hours ago 8 นาที
5 views
วิธีเช็กความพร้อมโปรเจกต์ก่อนปล่อยงานจริงด้วย ReleaseReady

วิธีเช็กความพร้อมโปรเจกต์ก่อนปล่อยงานจริงด้วย ReleaseReady

เคยไหม? โค้ดรันได้ในเครื่องแต่พอปล่อยจริงกลับพัง! มาดูวิธีตรวจสอบความพร้อมของโปรเจกต์ก่อนอัปขึ้น GitHub ด้วยเครื่องมือ ReleaseReady กัน

ที่มา: DEV Community

11 hours ago 9 นาที
5 views