จัดการกับการละเมิดโค้ดที่โฮสต์จากระยะไกล

โค้ดที่โฮสต์จากระยะไกลหรือ RHC คือสิ่งที่ Chrome เว็บสโตร์เรียกว่าสิ่งใดก็ตามที่ เบราว์เซอร์ดำเนินการซึ่งโหลดจากที่อื่นที่ไม่ใช่ ไฟล์ของส่วนขยายเอง เช่น JavaScript และ WASM แต่ไม่รวมถึงข้อมูลหรือสิ่งต่างๆ เช่น JSON หรือ CSS

เหตุใดจึงไม่อนุญาตให้ใช้ RHC อีกต่อไป

ตอนนี้ส่วนขยาย Manifest V3 ต้องรวมโค้ดทั้งหมดที่ใช้ไว้ภายใน ส่วนขยายเอง ในอดีต คุณสามารถแทรกแท็กสคริปต์แบบไดนามิกจาก URL ใดก็ได้บนเว็บ

ฉันได้รับแจ้งว่าส่วนขยายของฉันมี RHC เกิดอะไรขึ้น

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

วิธีสังเกต RHC

การสังเกต RHC ไม่ใช่เรื่องยากนักเมื่อคุณรู้ว่าต้องมองหาอะไร ก่อนอื่น ให้ ตรวจสอบสตริง "http://" หรือ "https://" ในโปรเจ็กต์ หากมีการละเมิด RHC คุณน่าจะค้นหาการละเมิดดังกล่าวได้ หากคุณมีระบบบิลด์แบบเต็ม หรือใช้การขึ้นต่อกันจาก npm หรือแหล่งที่มาอื่นๆ ของบุคคลที่สาม โปรดตรวจสอบว่าคุณกำลังค้นหาโค้ดเวอร์ชันที่คอมไพล์แล้ว เนื่องจากเป็นเวอร์ชันที่ร้านค้าจะประเมิน หากยังคงไม่พบปัญหา ขั้นตอนถัดไปคือการติดต่อทีมสนับสนุนแบบครบวงจร โดยทีมสนับสนุนจะสามารถระบุการละเมิดที่เฉพาะเจาะจง และสิ่งที่จำเป็นต่อการเผยแพร่ส่วนขยายโดยเร็วที่สุด

สิ่งที่ต้องทำหากห้องสมุดขอรหัส

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

จะเกิดอะไรขึ้นหากคุณรอการอัปเดตคลังไม่ได้

ไลบรารีบางรายการจะจัดส่งการอัปเดตทันทีหลังจากได้รับการแจ้งเตือน แต่ไลบรารีอื่นๆ อาจถูกละทิ้งหรือใช้เวลาในการแก้ไขปัญหา คุณอาจไม่ต้องรอให้สิ่งที่เกิดขึ้นในการละเมิดที่เฉพาะเจาะจงย้ายไปอยู่ในสถานะที่เลิกบล็อกแล้วและทำการตรวจสอบให้เสร็จสมบูรณ์ คุณมีตัวเลือกมากมายที่จะช่วยให้กลับมาใช้งานได้อีกครั้งอย่างรวดเร็ว

ตรวจสอบโค้ด

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

หรือมีไลบรารีอื่นที่ให้บริการฟีเจอร์เดียวกันไหม ลองดูตัวเลือกอื่นๆ ที่ตอบโจทย์กรณีการใช้งานเดียวกันได้ที่ npmjs.com, GitHub หรือเว็บไซต์อื่นๆ

เขย่าต้นไม้

หากไม่ได้ใช้โค้ดที่ทำให้เกิดการละเมิด RHC จริงๆ เครื่องมืออาจลบโค้ดนั้นโดยอัตโนมัติได้ เครื่องมือบิลด์ที่ทันสมัย เช่น webpack, Rollup และ Vite (ยกตัวอย่างมาเพียงไม่กี่รายการ) มีฟีเจอร์ที่เรียกว่า tree-shaking เมื่อเปิดใช้ในระบบบิลด์แล้ว Tree Shaking จะนำเส้นทางโค้ดที่ไม่ได้ใช้ออก ซึ่งหมายความว่าคุณไม่เพียงแต่มีโค้ดเวอร์ชันที่ เป็นไปตามข้อกำหนดมากขึ้น แต่ยังมีโค้ดที่กระชับและรวดเร็วขึ้นด้วย โปรดทราบว่าไลบรารีบางรายการไม่สามารถทำการ Tree Shaking ได้ แต่หลายรายการทำได้ เครื่องมือบางอย่าง เช่น Rollup และ Vite จะเปิดใช้ Tree Shaking โดยค่าเริ่มต้น ส่วน webpack ต้องได้รับการกำหนดค่าจึงจะเปิดใช้ได้ หากคุณไม่ได้ใช้ระบบบิลด์เป็นส่วนหนึ่งของส่วนขยาย แต่ใช้ไลบรารีโค้ด เราขอแนะนำให้คุณลองเพิ่มเครื่องมือบิลด์ลงในเวิร์กโฟลว์ เครื่องมือบิลด์ ช่วยให้คุณเขียนโปรเจ็กต์ที่ปลอดภัย น่าเชื่อถือ และบำรุงรักษาได้มากขึ้น

รายละเอียดวิธีใช้ Tree Shaking ขึ้นอยู่กับโปรเจ็กต์ของคุณ แต่หากจะยกตัวอย่างง่ายๆ ด้วย Rollup คุณสามารถเพิ่มการกำจัดโค้ดที่ไม่จำเป็นได้เพียงแค่ คอมไพล์โค้ดโปรเจ็กต์ เช่น หากคุณมีไฟล์ที่บันทึกเฉพาะการเข้าสู่ระบบ Firebase Auth ชื่อ main.js

import { GoogleAuthProvider, initializeAuth } from "firebase/auth";

chrome.identity.getAuthToken({ 'interactive': true }, async (token) => {
  const credential = GoogleAuthProvider.credential(null, token);
  try {
    const app = initializeApp({ ... });
    const auth = initializeAuth(app, { popupRedirectResolver: undefined, persistence: indexDBLocalPersistence });
    const { user } = await auth.signInWithCredential(credential)
    console.log(user)
  } catch (e) {
    console.error(error);
  }
});

จากนั้นคุณเพียงแค่ต้องบอก Rollup ถึงไฟล์อินพุต ปลั๊กอินที่จำเป็นในการ โหลดไฟล์โหนด @rollup/plugin-node-resolve และชื่อของไฟล์เอาต์พุต ที่สร้างขึ้น

npx rollup --input main.js --plugin '@rollup/plugin-node-resolve' --file compiled.js

เมื่อเรียกใช้คำสั่งนั้นในหน้าต่างเทอร์มินัล คุณจะได้รับเวอร์ชันที่สร้างขึ้น ของไฟล์ main.js ซึ่งคอมไพล์ทั้งหมดลงในไฟล์เดียวชื่อ compiled.js

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

การแก้ไขไฟล์โดยอัตโนมัติ

วิธีที่โค้ดที่โฮสต์จากระยะไกลสามารถเข้าสู่ฐานของโค้ดของคุณได้ซึ่งพบเห็นได้มากขึ้นเรื่อยๆ คือ เป็นทรัพยากรย่อยของไลบรารีที่คุณรวมไว้ หากไลบรารี X ต้องการimportไลบรารี Y จาก CDN คุณจะต้องอัปเดตไลบรารีเพื่อให้โหลดจากแหล่งที่มาในเครื่อง ระบบบิลด์ที่ทันสมัยช่วยให้คุณสร้างปลั๊กอินเพื่อดึงข้อมูลอ้างอิงระยะไกลและแทรกลงในโค้ดได้โดยตรง

ซึ่งหมายความว่าหากมีโค้ดที่มีลักษณะดังนี้

import moment from "https://unpkg.com/moment@2.29.4/moment.js"
console.log(moment())

คุณสามารถสร้างปลั๊กอิน Rollup ขนาดเล็กได้

import { existsSync } from 'fs';
import fetch from 'node-fetch';

export default {
  plugins: [{
    load: async function transform(id, options, outputOptions) {
      // this code runs over all of out javascript, so we check every import
      // to see if it resolves as a local file, if that fails, we grab it from
      // the network using fetch, and return the contents of that file directly inline
      if (!existsSync(id)) {
        const response = await fetch(id);
        const code = await response.text();

        return code
      }
      return null
    }
  }]
};

เมื่อเรียกใช้บิลด์ด้วยปลั๊กอินใหม่แล้ว ระบบจะค้นพบ import URL ระยะไกลทั้งหมด ไม่ว่าจะเป็นโค้ดของเรา การขึ้นต่อกันย่อย การขึ้นต่อกันย่อยย่อย หรือที่อื่นๆ

npx rollup --input main.js --config ./rollup.config.mjs --file compiled.js

การแก้ไขไฟล์ด้วยตนเอง

ตัวเลือกที่ง่ายที่สุดคือการลบรหัสที่ทำให้เกิด RHC เปิดในโปรแกรมแก้ไขข้อความที่คุณเลือก แล้วลบบรรทัดที่ละเมิด โดยทั่วไปแล้วเราไม่แนะนำให้ทำเช่นนี้ เนื่องจากอาจทำให้เกิดข้อผิดพลาดและอาจลืมได้ ซึ่งจะทำให้การดูแลโปรเจ็กต์ยากขึ้นเมื่อไฟล์ที่ชื่อ "library.min.js" ไม่ใช่ library.min.js จริงๆ แทนที่จะแก้ไขไฟล์ดิบ ตัวเลือกที่ดูแลได้ง่ายกว่าเล็กน้อยคือการใช้เครื่องมืออย่าง patch-package ตัวเลือกนี้มีประสิทธิภาพสูงมาก ซึ่งช่วยให้คุณบันทึกการแก้ไขลงในไฟล์ได้แทนที่จะบันทึกลงใน ไฟล์นั้นๆ โดยสร้างขึ้นจากไฟล์แพตช์ ซึ่งเป็นสิ่งเดียวกันกับที่ ขับเคลื่อนระบบควบคุมเวอร์ชัน เช่น Git หรือ Subversion คุณเพียงแค่ต้อง แก้ไขโค้ดที่ละเมิดด้วยตนเอง บันทึกไฟล์ Diff และกำหนดค่า patch-package ด้วยการเปลี่ยนแปลงที่ต้องการใช้ คุณสามารถอ่านบทแนะนำฉบับเต็มได้ ในไฟล์ README ของโปรเจ็กต์ หากคุณกำลังแพตช์โปรเจ็กต์ เราขอแนะนำ ให้ติดต่อโปรเจ็กต์เพื่อขอให้ทำการเปลี่ยนแปลง ในต้นทาง แม้ว่า patch-package จะช่วยให้การจัดการแพตช์ง่ายขึ้นมาก แต่การไม่มีอะไรให้แพตช์ก็ดียิ่งกว่า

สิ่งที่ต้องทำหากไม่ได้ใช้รหัส

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

มีวิธีแก้ปัญหาใดๆ ไหม

โดยทั่วไปแล้วไม่อนุญาตให้ใช้ RHC อย่างไรก็ตาม มีบางกรณีที่อนุญาตให้ใช้ ซึ่งแทบทุกกรณีจะเป็นกรณีที่ตัวเลือกอื่น เป็นไปไม่ได้

User Scripts API

สคริปต์ของผู้ใช้คือข้อมูลโค้ดขนาดเล็กที่มักจะมาจากผู้ใช้ ซึ่งมีไว้สำหรับเครื่องมือจัดการสคริปต์ของผู้ใช้ เช่น TamperMonkey และ Violentmonkey เครื่องมือจัดการเหล่านี้ไม่สามารถรวมโค้ดที่ผู้ใช้เขียนได้ ดังนั้น User Script API จึงแสดงวิธีเรียกใช้โค้ดที่ผู้ใช้ระบุ ไม่ใช่ตัวแทนของ chrome.scripting.executeScript หรือสภาพแวดล้อมการเรียกใช้โค้ดอื่นๆ ผู้ใช้ต้องเปิดใช้โหมดนักพัฒนาแอปเพื่อดำเนินการใดๆ หากทีมตรวจสอบของ Chrome เว็บสโตร์คิดว่ามีการใช้ฟีเจอร์นี้ในลักษณะอื่นนอกเหนือจากที่ตั้งใจไว้ (เช่น โค้ดที่ผู้ใช้ระบุ) ระบบอาจปฏิเสธหรือนำข้อมูลแอปออกจากร้านค้า

chrome.debugger

chrome.debugger API ช่วยให้ส่วนขยายโต้ตอบกับโปรโตคอลเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome ได้ นี่คือโปรโตคอลเดียวกันกับที่ใช้สำหรับ เครื่องมือสำหรับนักพัฒนาเว็บของ Chrome และเครื่องมืออื่นๆ อีกมากมาย ซึ่งช่วยให้ส่วนขยายสามารถขอและเรียกใช้โค้ดจากระยะไกลได้ เช่นเดียวกับสคริปต์ของผู้ใช้ สคริปต์เนื้อหาไม่ใช่ สิ่งที่จะมาแทนที่ chrome.scripting และมีประสบการณ์ของผู้ใช้ที่โดดเด่นกว่ามาก ขณะใช้งาน ผู้ใช้จะเห็นแถบคำเตือนที่ด้านบนของหน้าต่าง หากปิดหรือปิดแบนเนอร์ เซสชันการแก้ไขข้อบกพร่องจะสิ้นสุดลง

ภาพหน้าจอของแถบที่อยู่ใน Chrome ที่มีข้อความ "ส่วนขยายดีบักเกอร์เริ่มดีบักเบราว์เซอร์นี้แล้ว"
ภาพหน้าจอของแถบที่อยู่ใน Chrome ที่มีข้อความ "ส่วนขยายดีบักเกอร์เริ่มดีบักเบราว์เซอร์นี้แล้ว"

iframe ที่ทำแซนด์บ็อกซ์

หากคุณต้องการประเมินสตริงเป็นโค้ดและอยู่ในสภาพแวดล้อม DOM (เช่น สคริปต์เนื้อหา ซึ่งต่างจาก Service Worker ของส่วนขยาย) อีกทางเลือกหนึ่งคือการใช้ iframe แบบแซนด์บ็อกซ์ ส่วนขยายไม่รองรับสิ่งต่างๆ เช่น eval() โดยค่าเริ่มต้นเพื่อเป็นการป้องกันด้านความปลอดภัย โค้ดที่เป็นอันตรายอาจทำให้ความปลอดภัย ของผู้ใช้มีความเสี่ยง แต่เมื่อมีการเรียกใช้โค้ดในสภาพแวดล้อมที่ปลอดภัยที่ทราบเท่านั้น เช่น iframe ที่ได้รับการแซนด์บ็อกซ์จากส่วนอื่นๆ ของเว็บ ความเสี่ยงเหล่านั้นก็จะลดลงอย่างมาก ในบริบทนี้ คุณสามารถยกเลิกนโยบายรักษาความปลอดภัยเนื้อหาที่บล็อกการใช้ eval เพื่อให้คุณเรียกใช้โค้ด JavaScript ที่ถูกต้องได้

หากมีกรณีการใช้งานที่ไม่ได้ครอบคลุม โปรดติดต่อทีม โดยใช้รายชื่ออีเมล chromium-extensions เพื่อรับความคิดเห็น หรือเปิด คำขอใหม่เพื่อขอคำแนะนำจาก One Stop Support

สิ่งที่ควรทำหากไม่เห็นด้วยกับคำตัดสิน

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