מצב הסוואה (MASK)

איך להסתיר מהחוץ את הנתיבים שמסגירים שהאתר רץ על WizzoCMS - themes, system/js, minify, tag_manager.js ו-scss.css - בלי להזיז קבצים, איך מגדירים mask ו-mask_words, ומה לא מוסווה.

⏱ 5 דק' קריאה 971 מילים ערוך דף זה ב-GitHub

אתר WizzoCMS ניתן לזיהוי מבחוץ לפי צורת הנתיבים שהוא מגיש: themes/<name>/, system/js/, minify/3.js, הסיומת הכפולה .scss.css ו-tag_manager.js. מצב ההסוואה מחליף אותם בשמות ניטרליים, ב-HTML שיוצא וגם בבקשות שנכנסות, בלי להזיז אף קובץ בדיסק. הוא כבוי כברירת מחדל ומופעל על ידי הגדרה אחת באתר.

הערה

זה כיסוי שיווקי ולא אבטחה. אין כאן סוד שמוגן: ההסוואה רק מונעת מאתרים שאמורים להיראות ללא מותג להיראות כאותו מוצר. הקוד נמצא ב-collections/MASK.php.

הפעלה#

הגדרות ההסוואה הן שדות סטטיים במחלקת ההגדרות של האתר (CONFIG_USER, שממנה CONFIG יורשת). ראו גם את הטבלה ב-הגדרות.

// ערך true: מפה ברירת מחדל, כולל ה-theme הפעיל של הפלטפורמה
public static $mask = true;

// או מפה מפורשת (מומלץ, קל לבדוק בביקורת קוד): אמיתי => מוסווה
public static $mask = [
    'themes/shop/'   => 'lib/ui/',
    'system/js/'     => 'lib/js/',
    'minify/'        => 'lib/b/',
    'tag_manager.js' => 'lib/tm.js',
];

כש-$mask === true המפה היא:

אמיתימוסווה
minify/lib/b/
system/js/lib/js/
tag_manager.jslib/tm.js
themes/<deftheme>/lib/ui/ (רק אם לפלטפורמה מוגדר deftheme)

בנוסף, בכל מצב פעיל הסיומת .scss.css מוחלפת ב-.css.

מפה ריקה, חסרה או שאינה true ואינה מערך לא ריקה משאירה את ההסוואה כבויה. אתר שלא הגדיר דבר משלם בדיקת property_exists אחת לבקשה.

טיפ

קידומת לא חייבת להיות תיקייה. אפשר להסוות גם נקודת קצה של בקר שהדפדפן קורא לה, למשל 'system/analytics' => 'lib/a'. אותו כלל חל על כל קידומת במפה: היא מוחלפת ב-HTML היוצא ומוחזרת לערך האמיתי בבקשה הנכנסת.

איך זה עובד#

כיוון יציאה (אמיתי למוסווה)#

MASK::out($html) מריץ החלפה אחת (strtr) על טקסט שהדפדפן מקבל. המפתחות הארוכים קודמים, וטקסט שכבר הוחלף לא נסרק שוב, כך שהקריאה אידמפוטנטית. היא רצה ב:

  • core.php, על כל העמוד, לפני שמירת מטמון העמודים. המטמון מכיל בייטים מוסווים, וכל דרך הגשה (טרי, gz ישיר, מפוענח) מוציאה HTML מוסווה.
  • PAGE::parse_page, אחרי parse_page_func ולכן גם בפגיעת מטמון (ראו PAGE API).
  • הכותרת scripts ש-PAGE::JsIncludeJsCss שולח בתשובות pmode=empg, כי היא נושאת את רשימת הנכסים.
  • כל קובץ טקסט שמוגש מנתיב מוסווה ופלט של בקר שמאחורי קידומת מוסווה (CSS מקומפל, תגובת tag_manager).

בפאנל הניהול (system_type == "admin") ההסוואה לא פועלת, והנתיבים נשארים אמיתיים.

הערכים ב-JSON עוברים טיפול מיוחד: כל קידומת שכוללת / מוחלפת גם בצורה עם \\/ (כפי ש-json_encode כותב), כך שגם הקריאה applyTags([...]) של ה-tag manager מוסווית.

כיוון כניסה (מוסווה לאמיתי)#

בראש ROUTER::parse_friendly_url נקראת MASK::in($url), כך ששאר הנתב רואה רק נתיבים אמיתיים. כשהבקשה נושאת קידומת מוסווה:

  1. הקידומת מוחזרת לאמיתית (הקידומת המוסווית הארוכה ביותר קובעת).
  2. בקשה ל-x.css שהמקור שלה x.scss (ושאין לה .css פיזי) מוחזרת ל-x.scss.css. נתיבים תחת minify/ לא עוברים את ההמרה הזו.
  3. אם הנתיב האמיתי הוא קובץ סטטי שקיים בדיסק (תמונה, גופן, .css, .js, .json ועוד), MASK מגיש אותו בעצמו, כפי ששרת האינטרנט היה עושה, ומסיים.
  4. אחרת (קבוצת minify, SCSS, tag_manager, נקודת קצה) REQUEST_URI מכוון לנתיב האמיתי, ופלט הבקר עובר מסנן שמסווה אותו שוב. הנתב ממשיך כרגיל.

הגשת קובץ סטטי: Cache-Control: public, max-age=604800 (שבוע), Last-Modified ו-Expires, ותשובת 304 לפי If-Modified-Since. לגופנים נוספות הכותרות Access-Control-Allow-Origin: * ו-Cross-Origin-Resource-Policy: cross-origin. קבצי טקסט (css, js, mjs, json, map, txt, xml) עוברים הסוואה לפני ההגשה, ושאר הקבצים מוגשים כמות שהם.

הגנות בהגשה#

  • נתיב עם .. או תו NUL נדחה, והנתיב הממשי (realpath) חייב להישאר בתוך base_path, אחרת 404.
  • הקובץ נשלף רק מנתיב שעבר החלפה של קידומת מוסווית. בקשה רגילה לא עוברת דרך ההגשה הזו.
  • ההגשה עצמה מותרת רק לסיומות ברשימה קבועה (תמונות, גופנים, מדיה, css, js, json, txt, xml, pdf, wasm, zip ועוד).

mask_words: זיהוי מזהים ב-JS#

מזהים שהליבה שולחת לדפדפן (למשל wz_jquery, wz_cookies) מסגירים את המערכת כמו נתיב. $mask_words מוסיפה החלפות בכיוון יציאה בלבד:

public static $mask_words = [
    'wz_jquery'  => 'onReady',
    'wz_cookies' => 'cookieJar',
];

ההחלפה חלה על כל טקסט שהדפדפן מקבל דרך PHP, ולכן שם משתנה מוחלף בהגדרה ובכל שימוש בו בבת אחת. התנאי: הקבצים שמגדירים אותם חייבים לעבור דרך PHP, כלומר שרת האינטרנט לא אמור להגיש .js ו-.css מתחת לקידומת מוסווית בעצמו.

mask_words פועל רק כשיש מפה פעילה (בלי mask הוא מתעלם). מילה יכולה להופיע גם בשם קובץ (למשל _tumb_ בכל תמונה ממוזערת). אז בקשה לשם הניטרלי מוחזרת לקובץ האמיתי, אבל רק לקבצים בינאריים (תמונות, גופנים, מדיה, PDF). קובץ טקסט אף פעם לא נשלף בדרך הזו.

שימו לב

בחרו מילים ארוכות וייחודיות. ההחלפה היא החלפת מחרוזת פשוטה בכל הפלט, כך שמילה קצרה (wz) תשבור קוד, כתובות ותוכן שבמקרה מכילים אותה. בדקו את הדף בדפדפן אחרי כל שינוי במפה.

מה לא מוסווה#

הקוד קובע במפורש שלושה דברים שנשארים גלויים:

  • קידומת הקוקיז CRM_ (אימות, סיכון גבוה ובלי תועלת למבקר אנונימי).
  • ספריות הליבה תחת /assets/ (רובן קוד צד שלישי גנרי, והמזהים שבהן כבר משתמשים בשמות ניטרליים בנתב).
  • ה-meta של copyright (מבוטל ב-CONFIG::$show_wizzo_credits = false, לא על ידי ההסוואה).
שימו לב

גם עם הסוואה, נתיבים של בקרי ליבה (system/Tools/...) וקוד הצד של הלקוח שמפנה אליהם (למשל MISC.js) לא מוסווים אלא אם הוספתם אותם למפה. אם הסוואה חשובה, עברו על ה-HTML והסקריפטים שהדפדפן מקבל וחפשו system/ ו-wz_.

פתרון תקלות#

סימפטוםסיבה סבירה
תמונה או גופן מנתיב מוסווה מחזירים 404הקובץ לא קיים בדיסק באותו נתיב אמיתי, או שהנתיב יוצא מ-base_path
ה-CSS נטען אבל נראה ישןהבקשה קיבלה 304 או מטמון חזק: הנתיב נושא ?ver=, ראו צינור הנכסים ונקו מטמון
עמוד מהמטמון מכיל נתיבים אמיתייםהעמוד נשמר לפני שהפעלתם הסוואה. ההסוואה נשמרת בתוך המטמון, ולכן צריך לנקות מטמון עמודים אחרי הפעלה או שינוי מפה
סקריפט נשבר אחרי mask_wordsהמילה מופיעה גם בטקסט אחר. הגדילו אותה או הסירו אותה

ראו גם#

מצאתם טעות או חוסר? תקנו את הדף או פתחו Issue בריפו. התיעוד נכתב מתוך הקוד של ליבה 5.0.115.