זיהוי דפדפנים Headless: Playwright, Puppeteer ומעבר להם
מנוע ה‑Bot Detection שלנו מזהה יותר מ‑15 מסגרות אוטומציה דרך אי‑עקביות באותות, ממשקי API חסרים ודפוסים התנהגותיים שבוטים אינם יכולים לזייף.
דפדפני headless הם כלי הנשק המועדף עבור web scraping מתוחכם, credential stuffing ופעולות הונאה. בשונה מלקוחות HTTP פשוטים, דפדפני headless מריצים JavaScript, מרנדרים דפים ותומכים בממשקי API מודרניים — מה שהופך אותם לקשים הרבה יותר לזיהוי. מנוע ה‑Bot Detection שלנו משתמש בכמה שיטות זיהוי עצמאיות כדי לזהות יותר מ‑15 מסגרות אוטומציה כמעט ללא התראות שווא.
ההתפתחות של אוטומציית דפדפנים
אוטומציית דפדפנים עברה כברת דרך ארוכה מסקריפטים פשוטים של curl. כלים מודרניים כמו Playwright, Puppeteer ו‑Selenium WebDriver שולטים במנועי דפדפן אמיתיים — Chromium, Firefox או WebKit — במצב headless. הם מריצים JavaScript, מעבדים CSS, מרנדרים אלמנטי canvas ומטפלים בשאילתות WebGL בדיוק כמו דפדפנים עם ממשק גרפי. הדבר הופך אותם לבלתי נראים לשיטות זיהוי שפשוט בודקות יכולת הרצת JavaScript.
הדור העדכני של הכלים הרחיק לכת עוד יותר. מצב ה‑stealth של Playwright מתקן רבים מהאותות שעליהם מסתמך זיהוי בוטים מסורתי. Puppeteer‑extra‑plugin‑stealth משנה מאפייני navigator, דורס מחרוזות vendor של WebGL ומזייף אירועי אינטראקציה של משתמש. אמצעי אנטי‑זיהוי אלו יצרו מרוץ חימוש בין מפעילי בוטים למערכות זיהוי.
שיטת זיהוי 1: ניתוח דגל WebDriver
המאפיין navigator.webdriver מקבל את הערך true כאשר דפדפן נשלט על ידי אוטומציה. בשלביו המוקדמים, הזיהוי היה פשוט כמו בדיקת מאפיין זה. אך כלי stealth מודרניים מוחקים או דורסים אותו. הזיהוי שלנו מעמיק — אנו בודקים לא רק את ערך המאפיין אלא גם את מתאר המאפיין (property descriptor) שלו, את נוכחותו בשרשרת הפרוטוטייפ, והאם נעשו ניסיונות להגדירו מחדש. אנו בודקים גם מאפיינים קשורים כמו חריגות באורך navigator.plugins שמלוות דריסות WebDriver.
שיטת זיהוי 2: ממצאי Chrome DevTools Protocol
Playwright ו‑Puppeteer שולטים בדפדפנים דרך ה‑Chrome DevTools Protocol (CDP). גם כאשר מצב stealth פעיל, CDP מותיר ממצאים בסביבת ההרצה: משתנים גלובליים ספציפיים, פונקציות getter ששונו ומתארי מאפיינים שהותאמו על אובייקטי ה‑Window וה‑Navigator. אנו מגששים אחר ממצאים אלו בטכניקות עמידות בפני דריסות פשוטות.
שיטת זיהוי 3: טביעת אצבע של דפדפן Headless
ל‑Chrome במצב headless יש מערך יכולות שונה מזה של Chrome עם ממשק גרפי. חסרים לו תוספי דפדפן מסוימים, יש לו מאפייני רינדור שונים עבור חלק ממאפייני CSS, והוא מדווח ערכים שונים עבור חלק מתוצאות MediaQuery. אנו מתחזקים מסד נתונים של מאפייני דפדפני headless ידועים ומשווים אליו טביעות אצבע נכנסות.
מדדי headless מרכזיים כוללים: היעדר chrome.runtime (קיים ב‑Chrome עם ממשק גרפי אך נעדר ב‑headless), מערך navigator.plugins באורך אפס, דפוסי user agent ספציפיים שקושרו למצב headless בגרסאות קודמות, והבדלים באופן שבו Chrome במצב headless מטפל בהקשרי אבטחה של iframe.
שיטת זיהוי 4: ניתוח אורך Eval
למנועי JavaScript שונים יש מימושים שונים של פונקציות מובנות, ולמימושים אלו יש ייצוגי מחרוזת שונים. על ידי בדיקת האורך של Function.prototype.toString.call(eval) והשוואתו לערכים ידועים עבור כל מנוע דפדפן, אנו יכולים לזהות זיוף סביבה — למשל, מופע Chrome במצב headless שמתחזה ל‑Firefox.
שיטת זיהוי 5: אימות‑צולב של TLS
כפי שנדון במאמר שלנו על טביעת אצבע של TLS, הודעת ה‑TLS Client Hello חושפת את הדפדפן או ספריית ה‑HTTP האמיתיים שמבצעים את החיבור. כאשר סקריפט Playwright שולט ב‑Chrome, טביעת האצבע של TLS תואמת ל‑Chrome — וזה צפוי. אך כאשר בוט מותאם אישית משתמש בספריית requests של Python או ב‑net/http של Go, טביעת האצבע של TLS חושפת את התרמית ללא קשר למחרוזת ה‑user agent שנשלחת.
שיטת זיהוי 6: ניתוח תזמון והתנהגות
משתמשים אמיתיים מציגים שונות טבעית בתזמון האינטראקציות שלהם. הם מזיזים את העכבר בעקומות, לא בקווים ישרים. הם עוצרים לפני לחיצה. הם גוללים במהירויות משתנות. כלים אוטומטיים, אפילו אלו שמדמים התנהגות אנושית, מייצרים דפוסים הניתנים להבחנה סטטיסטית — תזמון עקבי מדי, מסלולי עכבר לינאריים לחלוטין ומהירויות גלילה לא טבעיות.
אנו אוספים אותות התנהגותיים מינימליים במהלך תהליך טביעת האצבע עצמו — תזמון הקריאות ל‑API, סדר איסוף האותות ותגובתיות של ממשקי API מסוימים בדפדפן. אותות מיקרו‑התנהגותיים אלו קשים לזיוף עבור כלי אוטומציה משום שהם תלויים בסביבת ההרצה בפועל, ולא במאפיינים הניתנים לדריסה.
שיטת זיהוי 7: אי‑עקביות בהרשאות וב‑API
לדפדפנים אמיתיים יש מצבי הרשאה וזמינות API עקביים. דפדפן שטוען לתמוך בהתראות אך אין לו constructor של Notification, או שמדווח על רזולוציית מסך מסוימת אך מחזיר ערכים שונים מ‑window.screen ומשאילתות media של CSS, מציג אי‑עקביות שמעידה על שיבוש או אמולציה.
אנו בודקים עשרות נקודות אימות‑צולב כאלה, ומחפשים סתירות שצצות כאשר כלי אוטומציה דורסים באופן סלקטיבי חלק מהאותות מבלי לשמור על עקביות בין כל ממשקי ה‑API הקשורים.
שיטת זיהוי 8: זיהוי VM ואמולציה
פעולות בוט רבות רצות בתוך מכונות וירטואליות או מופעי ענן. אף שכשלעצמו הדבר אינו הוכחה לאוטומציה, זהו אות חזק כאשר הוא משולב עם מדדים אחרים. כדאי להבחין כאן בין שני דברים נפרדים, משום שנוטים לערבב ביניהם.
הראשון הוא רינדור תוכנה. מכונה ללא GPU אמיתי נסוגה לרסטרייזר תוכנה, ומחרוזת ה‑renderer של WebGL אומרת זאת במפורש — "llvmpipe", "SwiftShader" והווריאציות שלהן נוקבות בשם ישירות. זהו מדד headless: הוא מלמד על נתיב הרינדור, והוא מזין את הכרעת הבוט בכל תוכנית.
השני הוא זיהוי מכונות וירטואליות במובנו המדויק, שהוא יכולת של תוכנית Enterprise. הוא קורא את מחרוזות ה‑renderer וה‑vendor של WebGL בחיפוש אחר חתימות היפרוויזר — VMware, VirtualBox, Parallels, QEMU, Hyper-V — ומצליב אותן מול מאפייני חומרה שאינם עקביים עם מכשירי צריכה: רזולוציות מסך שהן ברירת מחדל של VM, ליבת CPU אחת או שתיים מאחורי User-Agent של מחשב שולחני, שני גיגה‑בייט זיכרון או פחות. אף סמן בודד אינו מכריע; המזהה מנקד את הצירוף ומדווח על ציון ביטחון יחד עם הסמנים שנדלקו. טווחי כתובות של מרכזי נתונים וספקי אחסון, הנפתרים ממודיעין IP, מאששים זאת מצד הרשת.
אף אחד משני האותות אינו הוכחה לאוטומציה בפני עצמו — בדיקות דפדפן המתארחות בענן ושולחנות עבודה וירטואליים ללא GPU הם לגיטימיים — ולכן שניהם מזינים את ההכרעה המשוקללת במקום להפעיל חסימה בכוחות עצמם.
היתרון הרב‑שיטתי
לכל שיטת זיהוי בפני עצמה יש מגבלות — מפעיל בוט מתוחכם עשוי לחמוק מכל שיטה בודדת. אך חמיקה מכל השיטות בו‑זמנית, תוך שמירה על עקביות באימות‑הצולב לרוחב כולן, יקרה באופן שאינו כדאי. עלות הפיתוח והתחזוקה של בוט שעובר את כל הבדיקות עולה על הערך הכלכלי של רוב פעולות הבוט.
התראות שווא כמעט אפסיות
הזיהוי שלנו פועל על מודל רשימת היתר עבור בוטים של מנועי חיפוש (Googlebot, Bingbot וכו') המאומתים דרך reverse DNS, ועל מודל רב‑אותי עבור שאר התעבורה. אנו דורשים כמה אותות מאשׁשׁים בטרם סיווג תעבורה כאוטומטית. זה בדיוק העיקרון של התכנון השמרני: סמן דו‑משמעי בודד לעולם אינו מספיק בפני עצמו, ולכן מבקר רגיל שבמקרה מפעיל בדיקה אחת אינו מסווג כבוט.