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

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

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

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

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

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

วิธีค้นหา RHC

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

สิ่งที่ต้องทำหากไลบรารีขอรหัส

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

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

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

ตรวจสอบโค้ด

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

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

ต้นไม้สั่นสะเทือน

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

รายละเอียดวิธีใช้การปลูกต้นไม้จะขึ้นอยู่กับโปรเจ็กต์ของคุณ แต่สำหรับตัวอย่างง่ายๆ ด้วย 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

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

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

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

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

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

คุณสามารถสร้างปลั๊กอินรวมช่องสั้นๆ ได้

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
    }
  }]
};

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

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

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

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

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

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

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

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

API สคริปต์ของผู้ใช้

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

chrome.debugger

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

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

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

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

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

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

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