Tomer Cohen

<a href="http://tomercohen.com">Blog lives here</a>

פתרון פשוט למניעת ספאם באתרים

with 5 comments

הבטחתי ללא מעט אנשים לספר על הפתרון שלי לבעיות ספאם באתרים שאני מנהל, וכיצד באמצעות קוד פשוט אפשר לעצור לחלוטין כל תוכנה אוטומטית שמטרתה לזבל את האתר ולגרום למנהליו להשקיע את זמנם במחיקת הודעות ותגובות ולא בהשקעה בדברים קצת יותר חשובים.

מה זה? איך אפשר לקרוא את זה? מתברר שלבוטים קל יותר.נתחיל מההתחלה. במשך תקופה ארוכה שיחקתי במשחק חתול ועכבר מול מפיצי הספאם – הם שולחים ספאם, אנחנו מוסיפים שכבת הגנה לאתר. בשלב כלשהו הם מוצאים דרך לשלוח ספאם שיודע להתגבר על ההגנה שלנו, ואנחנו מוסיפים שכבה נוספת של הגנה. ניסינו הכל, החל מחיוב בהרשמה שרק גרם לספאמרים להירשם לאתר, כל מיני קאפאצ'ות שהתבררו כקלות לפיענוח לתוכנות, אימות בדוא"ל שהתברר כלא יעיל ועוד.

החלטתי לנסות את מזלי ולכתוב משהו משלי. רציתי משהו פשוט וקל, שלא ידרוש שינויים רבים בקוד התוכנה, ויהיה כמה שיותר אוניברסלי. משהו שידרוש מינימום התערבות מצד המשתמש אבל יהיה מודולרי כדי שאוכל לשנות ולשפר אותו בקלות בהתאם לבוטים שיצליחו לעקוף אותו בעתיד.במקום להוסיף את הקוד כתוסף למערכות קיימות במקרה הטוב או במקרה הפחות טוב לשנות את קוד המקור של המערכת, החלטתי שהתוכנה שלי צריכה להיות כמה שיותר מינימליסטית ולא לדרוש התקנה מסובכת.

איך זה עובד:

  1. המשתמש גולש בצורה רגילה באתר.
  2. ברגע שהוא מנסה לעשות פעולה מיוחדת כגון פרסום תגובה באתר, מופעל קוד אימות.
  3. אם המשתמש מורשה לגישה לדף הוא מועבר כלאחר כבוד לדף המתאים.
  4. אם המשתמש לא מצליח לעבור את האימות כנראה והוא רובוט והוא איננו מורשה לעבור לדף המבוקש.

מאחר ומנגנון האימות לא נחוץ במידה והמשתמש כבר אומת בעבר, אין צורך להציק לו שוב, ולכן מנגנון האימות משתיל לו עוגיית אימות במחשב ("אסימון"). קוד העוגיה אמור להיות שונה מאתר לאתר, אחרת הספאמרים ידעו תמיד להסתובב עם העוגייה המתאימה.

עוגיות ניתן להשתיל באמצעות תסריטים בצד השרת ובצד הלקוח. כאשר טוענים אותן בצד השרת הלקוח מקבל אותן בתור קוד HTTP/1.1 רגיל, ולכן מרבית הבוטים יודעים למשוך אותן כמו שצריך. כאשר מדובר בקוד בצד לקוח בשפת JavaScript, לבוט המחמד שלנו הרבה יותר קשה להבין מה הוא אמור לעשות, ולכן הוא לא מצליח לאכול את העוגייה. אם נדרשת פעולה מצד המשתמש המצב אפילו גרוע יותר, והבוט לא יוכל לעולם לבצע את הפעולה בצורה אוטומטית.

חסרונות השיטה

  • חסימת דפים מסויימים תמנע יכולת קריאה שלהם על־ידי בוטים. גם הזחלנים של גוגל הם בוטים ולכן גם הם יתקעו בהגנה. לא כדאי להוסיף קוד שיאפשר להם להיכנס כדי לא להשאיר פתח לזבלנים להתחזות לבוטים ידידותיים ולחדור אלינו לאתר. כאשר מדובר רק בעמודי הרישום ופרסום התגובות באתר אין בכך נזק משמעותי שכן אין בעמודים אלו תוכן משמעותי.
  • מאחר והפתרון מתבסס על Cookies, הדפדפנים של כלל המשתמשים חייבים לא לחסום את טעינת העוגיות מהאתר. אם המשתמש חוסם את העוגיות הוא יתקע יחד עם הבוטים בהסגר, ולא יצליח לעשות פעולות מסויימות באתר. אם עמוד ההסגר יסביר למשתמש שהוא אמור לא למנוע את טעינת העוגיות כולם יהיו מרוצים. לא שמעתי על הרבה אנשים שחוסמים עוגיות בימנו.
  • המשתמש חייב להיות מצוייד בדפדפן שכולל תמיכה ב־JavaScript. משתמשי lynx יאלצו להישאר בחוץ.

הטמעה באתר

כאמור, רציתי להתבסס כמה שפחות על קוד בצד השרת, ועם שינויים מינימליים בתוכנות שרצות על השרת. החלטתי להשתמש ב־mod_rewrite של שרת Apache, כדי שלא אצטרך לגעת בשום רכיב באתר.

קובץ ה־.htaccess בתיקייה בה נמצאים הקבצים הבעיתיים יראה כך:
RewriteEngine on
RewriteCond %{HTTP_COOKIE} !nospam_token=welcome
RewriteRule posting.php|login.php|profile.php /spam_jail/index.html

הוראות אלו יגרמו לכל מי שמנסה לגשת לדפים posting.php, login.php או profile.php (שלושת הקבצים הבעיתיים ביותר במערכות פורומים מסוג phpbb) לקבל דף HTML מיוחד במקום הדף שהם ביקשו, כאשר אין להם עוגייה nospam_token עם הערך "welcome". תרגישו חופשיים לשנות את שם העוגיה (האסימון) ואת הערך (הסיסמה) שלה.

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

דף ההסגר (שימו לב – אין שום תסריט בצד השרת) יכיל מינימום קוד כדי שהוא יעלה מהר, אבל גם הנחיות למשתמשים שנתקעים בו. כדאי להפנות אותם למקום בו יוכלו לקבל תמיכה נוספת כדי לא לאבד אותם בעקבות הגנה מסיבית או לא ידידותית.

אני משמיט את הקוד הלא רלוונטי לנושא, ומשאיר רק את החלקים החשובים.

טעינת העוגייה. הקוד יעלה את העמוד מחדש כאשר העוגייה קיימת בדפדפן, וינסה להטעין אותה שוב אם לא הצליח בפעם הראשונה. במידה והמשתמש מתבקש לאשר את טעינת העוגייה והוא עונה בסירוב, הוא יתבקש להטעין את העוגיה שוב.
<script language="JavaScript">
function main()
{
createCookie ("nospam_token", "welcome", 30);
if (readCookie("nospam_token")=="welcome")
window.setTimeout ("refresh (true);", 100);
else
window.setTimeout ("main();", 250);
}
</script>

טיפול בעוגיות –
<script language="JavaScript">
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.l
ength);
}
return null;
}

טעינת העמוד מחדש. מתברר שזה דבר מסובך, ויש צורך בשלוש פונקציות שונות כדי לתמוך בכל הגירסאות והדפדפנים.
<script language="JavaScript">
function refresh()
{
var sURL = unescape(window.location.pathname);
window.location.href = sURL;
}
</script>
<script language="JavaScript1.1">
function refresh()
{
var sURL = unescape(window.location.pathname);
window.location.replace( sURL );
}
</script>
<script language="JavaScript1.2">
function refresh()
{
window.location.reload( false );
}
</script>

קריאה לקוד מדף ה־HTML –
<body onload="main()">

הקוד הנ"ל יגרום לטעינת עוגיית המפתח עם תאריך תפוגה של שלושים יום לעתיד. החלפת פרטי העוגייה לא תגרום לנעילת משתמשים מחוץ למערכת, אלא לטעינה חוזרת שלה לדפדפן.

מאחר ו־mod_rewrite לא מאפשר העברת טפסים עם נתוני POST, לא ניתן יהיה להכניס את הקוד על מערכת ששולחת תגובות ישירות מדף ההודעה (פה למשל). הפתרון שמצאתי היה לשתול את קוד טעינת העוגיה בעמוד אחר שהמשתמש חייב לעבור בדרכו לעמוד החסום, ובכך לגרום למשתמש שלא יגיע לעולם לדף ההסגר.

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

עוד באותו נושא

מודעות פרסומת

Written by Tomer Cohen

אפריל 11, 2007 בשעה 18:30

פורסם בSpam

5 תגובות

Subscribe to comments with RSS.

  1. זה אמור לעבוד בבלוגלי, כלומר בבלוג שלך?

    הומר

    אפריל 12, 2007 at 0:13

  2. הקוד לא דורש שינויים מיוחדים כדי לעבוד גם במערכות מבוססות WordPress, אלא שבשרתי איחסון ציבוריים דוגמת בלוגלי המשתמש איננו מסוגל לגעת בקונפיגורצית השרת.

    אלעד/תום/חנית – רוצים לעשות ניסוי קטן? 😉

    תומר

    אפריל 12, 2007 at 1:07

  3. תומר – אנחנו עושים ניסיון עם משהו דומה. כמה תגובות ספאם אתה מקבל בבלוג שלך כאן?

    אלעד

    אפריל 12, 2007 at 10:47

  4. אלעד – לא מעט, אני משער שבסביבות ה־20 ביום, לפחות.

    תומר

    אפריל 12, 2007 at 11:13

  5. תגיד לי בבקשה במשך היום האם יש שינוי?

    אלעד

    אפריל 12, 2007 at 11:20


להשאיר תגובה

הזינו את פרטיכם בטופס, או לחצו על אחד מהאייקונים כדי להשתמש בחשבון קיים:

הלוגו של WordPress.com

אתה מגיב באמצעות חשבון WordPress.com שלך. לצאת מהמערכת / לשנות )

תמונת Twitter

אתה מגיב באמצעות חשבון Twitter שלך. לצאת מהמערכת / לשנות )

תמונת Facebook

אתה מגיב באמצעות חשבון Facebook שלך. לצאת מהמערכת / לשנות )

תמונת גוגל פלוס

אתה מגיב באמצעות חשבון Google+ שלך. לצאת מהמערכת / לשנות )

מתחבר ל-%s

%d בלוגרים אהבו את זה: