בהתחשב בכמות המידע האישי שזורם ברשת האינטרנט, הצפנה היא לא משהו שאנחנו יכולים או צריכים להתעלם ממנו. דפדפנים מודרניים מציעים כמה מנגנונים שבהם אתם יכולים להשתמש כדי לוודא שנתוני המשתמשים מאובטחים בזמן ההעברה: קובצי Cookie מאובטחים ו-Strict Transport Security הם שניים מהחשובים ביותר. הם מאפשרים לכם להגן על המשתמשים שלכם בצורה חלקה, לשדרג את החיבורים שלהם ל-HTTPS ולהבטיח שנתוני המשתמשים אף פעם לא נשלחים בצורה גלויה.
למה זה חשוב? כדאי לחשוב על זה:
הצגת דף אינטרנט דרך חיבור HTTP לא מוצפן דומה פחות או יותר למסירת מעטפה לא חתומה לאדם הראשון שרואים ברחוב, שנראה כאילו הוא הולך לכיוון הדואר. אם יתמזל מזלכם, היא תעביר את החבילה בעצמה עד ליעד, או שהיא תעביר אותה לאדם הבא שהיא תראה שהולך בכיוון הנכון. האדם הזה יכול לעשות את אותו הדבר, וכן הלאה.
רוב האנשים הזרים בשרשרת המאולתרת הזו הם אמינים, והם לא יציצו במכתב הפתוח שלכם או ישנו אותו. אבל ככל שהמכתב עובר יותר ידיים, כך גדל מספר האנשים שיש להם גישה מלאה למכתב שאתם שולחים. בסופו של דבר, סביר מאוד להניח שהנמען של המכתב יקבל משהו בדואר, אבל לא בטוח שהמשהו הזה יהיה אותו משהו ששלחתם מלכתחילה. אולי היית צריך לסגור את המעטפה הזו…
מתווכים
לטוב ולרע, חלקים נרחבים מהאינטרנט מסתמכים על האמינות של זרים. השרתים לא מחוברים ישירות זה לזה, אלא מעבירים בקשות ותגובות מנתב לנתב, כמו במשחק טלפון שבור ענק.
אפשר לראות את הדילוגים האלה בפעולה באמצעות traceroute. המסלול מהמחשב שלי אל HTML5Rocks נראה בערך כך:
$ traceroute html5rocks.com
traceroute to html5rocks.com (173.194.71.102), 30 hops max, 60 byte packets
1 router1-lon.linode.com (212.111.33.229) 0.453 ms
2 212.111.33.233 (212.111.33.233) 1.067 ms
3 217.20.44.194 (217.20.44.194) 0.704 ms
4 google1.lonap.net (193.203.5.136) 0.804 ms
5 209.85.255.76 (209.85.255.76) 0.925 ms
6 209.85.253.94 (209.85.253.94) 1.226 ms
7 209.85.240.28 (209.85.240.28) 48.714 ms
8 216.239.47.12 (216.239.47.12) 22.575 ms
9 209.85.241.193 (209.85.241.193) 36.033 ms
10 72.14.233.180 (72.14.233.180) 43.222 ms
11 72.14.233.170 (72.14.233.170) 43.242 ms
12 *
13 lb-in-f102.1e100.net (173.194.71.102) 44.523 ms
13 דילוגים זה לא רע, באמת. אבל אם שולחים בקשות דרך HTTP, לכל אחד מהנתבים האלה יש גישה מלאה לבקשות ולתשובות של השרתים. כל הנתונים מועברים כטקסט פשוט לא מוצפן, וכל אחד מהגורמים המתווכים האלה יכול לפעול כאדם באמצע, לקרוא את הנתונים שלי או אפילו לשנות אותם בזמן ההעברה.
גרוע מכך, כמעט בלתי אפשרי לזהות יירוט כזה. תגובת HTTP ששונתה באופן זדוני נראית בדיוק כמו תגובה תקינה, כי אין מנגנון שמאפשר לוודא שהנתונים שהתקבלו הם _בדיוק_ הנתונים שנשלחו. אם מישהו מחליט להפוך את האינטרנט שלי בשביל הצחוקים, אז פחות או יותר אין לי מזל.
האם זה קו מאובטח?
המעבר מ-HTTP בטקסט פשוט לחיבור HTTPS מאובטח הוא ההגנה הטובה ביותר מפני גורמים מתווכים. חיבורי HTTPS מצפינים את כל הערוץ מקצה לקצה לפני שליחת הנתונים, כך שמכונות שנמצאות בין המקור ליעד לא יכולות לקרוא או לשנות את הנתונים במעבר.
האבטחה שפרוטוקול HTTPS מספק מבוססת על הרעיון של מפתחות קריפטוגרפיים ציבוריים ופרטיים. דיון מעמיק בפרטים חורג (לשמחתנו) מהיקף המאמר הזה, אבל הנחת היסוד די פשוטה: נתונים שמוצפנים באמצעות מפתח ציבורי נתון ניתנים לפענוח רק באמצעות המפתח הפרטי התואם. כשהדפדפן מתחיל לחיצת יד של HTTPS כדי ליצור ערוץ מאובטח, השרת מספק אישור שנותן לדפדפן את כל המידע שנדרש כדי לאמת את הזהות שלו, על ידי בדיקה שהשרת מחזיק במפתח הפרטי המתאים. כל התקשורת מאותו רגע ואילך מוצפנת באופן שמוכיח שהבקשות נשלחות לשרת המאומת והתשובות מתקבלות ממנו.
לכן, פרוטוקול HTTPS מבטיח במידה מסוימת שאתם מתקשרים עם השרת שאתם חושבים שאתם מתקשרים איתו, ושאף אחד אחר לא מאזין או מתעסק עם הנתונים. הצפנה כזו היא תנאי הכרחי לאבטחה באינטרנט. אם האפליקציה לא מועברת כרגע באמצעות HTTPS, היא חשופה להתקפות. לפתרון הבעיה. ב-Ars Technica יש מדריך מצוין לקבלת אישור ולהתקנה שלו (בחינם). מומלץ לעיין בו כדי לקבל פרטים טכניים. ההגדרה תהיה שונה בין ספקים ובין שרתים, אבל תהליך הבקשה לאישור זהה בכל מקום.
אבטחה כברירת מחדל
אחרי שמבקשים ומתקינים אישור, חשוב לוודא שהמשתמשים נהנים מהעבודה הקשה שלכם: מעבירים את המשתמשים הקיימים לחיבורי HTTPS באופן שקוף באמצעות הפניה אוטומטית של HTTP, ומוודאים שקובצי ה-cookie מועברים רק דרך חיבורים מאובטחים.
בואו נתחיל
כשמשתמש נכנס לכתובת http://example.com/, מפנים אותו לכתובת https://example.com/ על ידי שליחת תגובה מסוג 301 Moved
Permanently עם כותרת Location מתאימה:
$ curl -I http://mkw.st/
HTTP/1.1 301 Moved Permanently
Server: nginx/1.3.7
...
Keep-Alive: timeout=20
Location: https://mkw.st/
אפשר להגדיר הפניה אוטומטית כזו בקלות בשרתים כמו Apache או Nginx.
לדוגמה, הגדרת Nginx שמפנה מ-http://example.com/ אל https://example.com/ נראית כך:
server {
listen [YOUR IP ADDRESS HERE]:80;
server_name example.com www.example.com;
location "/" {
rewrite ^(.*) https://www.example.com$1 permanent;
}
}
נעילת צנצנת העוגיות
קובצי Cookie מאפשרים לנו לספק למשתמשים חוויות חלקות של התחברות באמצעות פרוטוקול HTTP ללא שמירת מצב. נתונים שמאוחסנים בקובצי Cookie, כולל מידע רגיש כמו מזהי סשנים, נשלחים עם כל בקשה, וכך השרת יכול להבין לאיזה משתמש הוא מגיב באותו רגע. אחרי שמוודאים שהמשתמשים נכנסים לאתר באמצעות HTTPS, צריך גם לוודא שהמידע הרגיש שמאוחסן בקובצי Cookie מועבר רק בחיבור מאובטח, ולא נשלח אף פעם בטקסט מפורש.
הגדרה של קובץ Cookie כוללת בדרך כלל כותרת HTTP שנראית בערך כך:
set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT
אפשר להורות לדפדפן להגביל את השימוש בקובץ ה-Cookie לסשנים מאובטחים על ידי הוספת מילת מפתח אחת:
Set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT; secure
קובצי Cookie שמוגדרים עם מילת המפתח secure לא יישלחו אף פעם דרך HTTP.
סגירת החלון הפתוח
הפניה אוטומטית שקופה ל-HTTPS פירושה שברוב המקרים שבהם המשתמשים נמצאים באתר, הם ישתמשו בחיבור מאובטח. עם זאת, היא משאירה חלון הזדמנויות קטן למתקפה: חיבור ה-HTTP הראשוני פתוח לרווחה וחשוף להסרת SSL ולמתקפות קשורות. מכיוון שלגורם המתווך יש גישה מלאה לבקשת ה-HTTP הראשונית, הוא יכול לפעול כשרת proxy ביניכם לבין השרת, ולהשאיר אתכם בחיבור HTTP לא מאובטח, בלי קשר לכוונות של השרת.
כדי לצמצם את הסיכון למתקפה מהסוג הזה, אתם יכולים לבקש מהדפדפן לאכוף את HTTP Strict Transport Security (HSTS). שליחת הכותרת Strict-Transport-Security HTTP מורה לדפדפן לבצע את ההפניה האוטומטית מ-HTTP ל-HTTPS בצד הלקוח, בלי לגעת ברשת (זה גם מעולה לביצועים; הבקשה הכי טובה היא זו שלא צריך לשלוח):
$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000
דפדפנים שתומכים בכותרת הזו (כרגע Firefox, Chrome ו-Opera: פרטים נוספים זמינים ב-caniuse) יציינו שהאתר הספציפי הזה ביקש גישה רק באמצעות HTTPS, כלומר לא משנה איך המשתמשת מגיעה לאתר, היא תבקר בו באמצעות HTTPS. גם אם היא תקליד http://example.com/ בדפדפן, היא תגיע ל-HTTPS בלי ליצור חיבור HTTP. יתרה מכך, אם הדפדפן מזהה אישור לא חוקי (שעלול לנסות לזייף את זהות השרת), המשתמשים לא יוכלו להמשיך דרך HTTP. זה הכל או כלום, וזה מצוין.
הדפדפן יבטל את תוקף סטטוס ה-HSTS של השרת אחרי max-age שניות (בערך חודש בדוגמה הזו). צריך להגדיר ערך גבוה מספיק.
כדי לוודא שכל תת-הדומיינים של המקור מוגנים, אפשר להוסיף את ההוראה includeSubDomains לכותרת:
$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000
התקדמות בטוחה
פרוטוקול HTTPS הוא הדרך היחידה לוודא שהנתונים שאתם שולחים מגיעים לנמען המיועד ללא שינוי. כדאי להגדיר חיבורים מאובטחים לאתרים ולאפליקציות שלכם כבר היום. זה תהליך די פשוט, והוא יעזור לשמור על בטיחות הנתונים של הלקוחות. אחרי שמגדירים ערוץ מוצפן, צריך להפנות את המשתמשים באופן שקוף לחיבור המאובטח הזה, בלי קשר לאופן שבו הם מגיעים לאתר, על ידי שליחת תגובת HTTP 301. לאחר מכן, ודאו שכל פרטי הסשן הרגישים של המשתמשים שלכם משתמשים רק בחיבור המאובטח הזה, על ידי הוספת מילת המפתח secure כשאתם מגדירים קובצי Cookie.
אחרי שביצעתם את כל הפעולות האלה, ודאו שהמשתמשים שלכם לא יפספסו את ההזדמנות: הגנו עליהם על ידי כך שתוודאו שהדפדפן שלהם מבצע את הפעולה הנכונה ושולח כותרת Strict-Transport-Security.
הגדרת HTTPS לא דורשת הרבה עבודה, ויש לה יתרונות עצומים לאתר ולמשתמשים שלו. זה שווה את המאמץ.
משאבים
- ב-StartSSL אפשר לקבל אישורים בחינם לדומיינים מאומתים. אין כמו בחינם. כמובן שאפשר לשדרג לרמות אימות גבוהות יותר, והמחיר סביר.
- בדיקת שרת SSL: אחרי שמגדירים HTTPS לשרתים, צריך לוודא שההגדרה בוצעה בצורה נכונה על ידי הפעלת בדיקת השרת של SSL Labs. תקבלו דוח מפורט שיאפשר לכם לראות אם הכל פועל כמו שצריך.
- כדאי לקרוא את המאמר של Ars Technica, "Securing your Web Server with SSL/TLS", כדי לקבל קצת יותר רקע על הפרטים הקטנים של הגדרת שרת.
- כדאי לעיין במפרט של HTTP Strict Transport Security (RFC6797) כדי לקבל את כל המידע הטכני על הכותרת
Strict-Transport-Security. - אחרי שתבינו היטב מה אתם עושים, תוכלו לפרסם שהאתר שלכם צריך להיות נגיש רק באמצעות קבוצה ספציפית של אישורים. ב-IETF עובדים על פיתוח שיאפשר לכם לעשות בדיוק את זה באמצעות הכותרת
Public-Key-Pins. זה עדיין בשלבים מוקדמים, אבל זה מעניין וכדאי לעקוב אחרי זה.