לא מזמן כתבתי על דו"ח ממצאי בדיקות אבטחה שקיבלנו (ויש שיאמרו "חטפנו") והצעתי לכל בודק לחשוב קצת ולראות מה הוא יכול לעשות. דבר אחד שלא עשיתי מספיק, בעיקר כי לא רציתי לכתוב מגילה באורך הגלות, הוא להדגיש נקודה פשוטה:
כשרוב האנשים שומעים את המונח "בדיקות אבטחה", הם מייד חושבים על האקר גאון שמפעיל כלים סופר מתוחכמים. נניח, כמו שעושה הבחור הזה. ואיך בשם שמיים אפשר להתגונן מדברים כאלה בלי להיות מומחה אבטחה חכם לא פחות?
המציאות, כמובן, שונה. כן, ישנן מדי פעם מתקפות מהסוג הזה (מי אמר Stuxnet?) , אבל כמעט תמיד יש פרצות אבטחה הרבה יותר קלות לניצול ומתקפות פשוטות יותר – האם עובד בחברה יכול לגשת למידע סודי בלי שאף אחד אחר ידע מזה? האם משתמש יכול לנצל את תקופת הניסיון של התוכנה שלכם ולשחק עם השעון על המחשב שלו כדי להשתמש בה בחינם לנצח? האם משתמש עם הרשאות ניהול יכול לראות מידע פרטי של משתמשים תחתיו ? האם זה מידע שהוא אולי לא צריך ולא אמור לראות?
בקיצור, יש המון בעיות אבטחה שקל למצוא, וצריכים רק לחפש.
אבל, לפני שניגשים לבדוק את תכונות האבטחה של מוצר, כדאי לדעת מה אנחנו רוצים להבטיח.
בדרך כלל, מקובל לייחס לתוכנה שש תכונות אבטחה עיקריות (יש עוד כמה חלוקות, מפורטות יותר או פחות, אבל זו חביבה עלי).
בדרך כלל, כל התקפה שניתקל בה תפגע באחת, או יותר, מהתכונות האבטחה האלה.
בדרך כלל, כל התקפה שניתקל בה תפגע באחת, או יותר, מהתכונות האבטחה האלה.
· זיהוי - התוכנה מסוגלת לוודא שמישהו (אדם או תוכנה אחרת) הוא באמת מי שהוא טוען שהוא.
· שלמות - המערכת יכולה להבטיח שמידע לא השתנה באופן לא חוקי ולא הושחת בשום אופן, לא בזמן העברת המידע ולא בזמן שהמידע היה מאוחסן.
· אי יכולת הכחשה - אף אחד לא יכול לבצע פעולה ולומר "אני לא עשיתי את זה" כי המערכת מסוגלת לספק עדות מהימנה לביצוע הפעולה על ידי הגורם הרלוונטי.
· סודיות - מידע מגיע רק למי שמורשה לגשת אליו.
· זמינות - המערכת זמינה למשתמשים הלגיטימיים שלה בכל זמן בו היא אמורה להיות זמינה.
· הרשאה - המערכת מוודאת שפעולות נגישות רק למי שמורשה לבצע אותן.
במייקרוסופט הגו סדרה של דפוסי איום שמקבילים לתכונות האלה, כדי לעזור לנו לחפש חולשות, הם אפילו המציאו ראשי תיבות כך שיהיה קל לזכור:
STRIDE:
Spoofing - התחזות
Tampering - זיוף.
Repudiation - הכחשה.
Information disclosure - הדלפת מידע.
Denial of Service - שלילת שירות.
Elevation of privilege - העלאת הרשאות (אם למישהו יש רעיון לתרגום טוב יותר, אשמח לשמוע עליו)/
STRIDE:
Spoofing - התחזות
Tampering - זיוף.
Repudiation - הכחשה.
Information disclosure - הדלפת מידע.
Denial of Service - שלילת שירות.
Elevation of privilege - העלאת הרשאות (אם למישהו יש רעיון לתרגום טוב יותר, אשמח לשמוע עליו)/
עוד תכונה אליה לא אתייחס היא "בטיחות" – התכונה שגורמת לנו להאמין שהמוצר לא יתפוצץ למישהו בפרצוף. לא שזה לא חשוב, אבל זה רלוונטי רק למוצרים מסויימים, ואני לא מבין בזה כלום.
בכל מקרה, אחרי כשכולנו מבינים טיפה יותר טוב מה הן תכונות האבטחה שאנחנו רוצים שיהיו למוצר שלנו, אני רוצה לסיים עם שלוש דוגמאות מתוך הדו"ח שקיבלנו. המטרה שלי היא בעיקר להדגים כמה פשוטות יכולות להיות הבעיות וכמה פשוט למצוא אותן.
חשוב לציין – גם אם נראה שחלק מהממצאים האלה זניחים או אפילו מטופשים, יש לכל ממצא כזה עלות גבוהה יחסית למוצר שלנו - גם מבחינת מאמץ שאנחנו צריכים להשקיע כדי לתקן את הממצאים בלו"ז שנראה ללקוח הגיוני (הוא הרי סימן את הממצאים כ"עדיפות גבוהה") וגם מבחינת המוניטין שלנו. כשאני נתקל בחולשות כאלה ההנחה הראשונה שלי היא שמי שכתב את התוכנה לא חשב על אבטחת מידע, זה לא משהו שאנחנו רוצים שהלקוחות שלנו יחשבו.
ועכשיו, לדוגמאות:
1. משתמש יכול לבצע פעולה שלא הגיוני שתהיה מותרת לו: במקרה שלנו, ישנו "מנהל קבוצה", הוא רשאי ליצור משתמשים חדשים בתוך הקבוצה שלו. בנוסף, הוא יכול לשנות כמה פרטים שלהם.
הממצא היה פשוט - למרות שמנהל קבוצה לא יכול ליצור משתמש בקבוצה שאינה שלו, בממשק העריכה מנהל הקבוצה יכול להזיז את המשתמש לקבוצה אחרת.
הממצא היה פשוט - למרות שמנהל קבוצה לא יכול ליצור משתמש בקבוצה שאינה שלו, בממשק העריכה מנהל הקבוצה יכול להזיז את המשתמש לקבוצה אחרת.
2. שיקוף קלט בחזרה למשתמש: כשמשתמש מנסה להיכנס ומכניס סיסמה לא נכונה (או טועה בשם המשתמש) מוצגת ההודעה "ניסיון הכניסה כשל עבור שם המשתמש X." ההתקפה פשוטה - שב בין המשתמש לאתר שלנו (מה שקל מאוד לעשות בעזרת ההתקפה המוכרת כ"איש בדפדפן") וברגע בו הוא מנסה להיכנס, שנה את שם המשתמש שנשלח אלינו ל"X. אנא התקשר למספר: 1-800-1234567".
התוצאה? המשתמש רואה הודעת שגיאה שנראית לגיטימית ומפנה אותו להתקשר לתמיכה הטכנית במספר של המתקיף, שיכול עכשיו לנסות ולחלץ ממנו את הסיסמה.
התוצאה? המשתמש רואה הודעת שגיאה שנראית לגיטימית ומפנה אותו להתקשר לתמיכה הטכנית במספר של המתקיף, שיכול עכשיו לנסות ולחלץ ממנו את הסיסמה.
3. אי וידוא קלט בצד השרת:
הממצא הזה הוא כנראה המביך ביותר מבחינתי, ההנחיה לבדוק קלט בצד השרת נמצאת בעמוד הראשון של כל מדריך לכתיבת תוכנה בטוחה. ואנחנו בודקים דברים כאלה עם כל פיתוח חדש שאנחנו עושים, אז פספסנו את זה בחלק ישן יותר של המוצר? נו באמת.
הממצא היה כזה: למשתמש מסוים יש גישה לדף, אבל לא את היכולת לערוך אותו. הוא לא רואה את הכפתורים שמוביל לעריכה (והם גם לא חבויים בדף). אבל, כשהוא מנסה לבצע פעולה הוא עוצר את הבקשה בצד שלו (למשל, בעזרת כלי כמו fiddler) ומשנה את שם הפעולה מ"צפה" ל"ערוך" - ומקבל גישה לממשק העריכה.
הממצא הזה הוא כנראה המביך ביותר מבחינתי, ההנחיה לבדוק קלט בצד השרת נמצאת בעמוד הראשון של כל מדריך לכתיבת תוכנה בטוחה. ואנחנו בודקים דברים כאלה עם כל פיתוח חדש שאנחנו עושים, אז פספסנו את זה בחלק ישן יותר של המוצר? נו באמת.
הממצא היה כזה: למשתמש מסוים יש גישה לדף, אבל לא את היכולת לערוך אותו. הוא לא רואה את הכפתורים שמוביל לעריכה (והם גם לא חבויים בדף). אבל, כשהוא מנסה לבצע פעולה הוא עוצר את הבקשה בצד שלו (למשל, בעזרת כלי כמו fiddler) ומשנה את שם הפעולה מ"צפה" ל"ערוך" - ומקבל גישה לממשק העריכה.
-------------------------------------------------------
Not long ago I wrote a post about a security report we got (or got smacked with, as some would claim) and I suggested that every tester should think a bit about the security when testing an application. One thing I didn't do enough, mainly since I didn't want the other post to be too long, is to emphasize one simple point:
When most people think about "security tests" they immediately start imagining the complex stuff implied in today's movies. You know, the scene where that super sophisticated hacker is using cool tools, hackers like this guy. And how could you defend against such smart people without being an equally smart security expert?
The reality, of course, is very different. Yes, from time to time you hear about such attacks (did anyone say Stuxnet?), but more often than not there are security vulnerabilities that are far easier to exploit, and simpler attacks. Can an employee in the company access confidential data without anyone knowing about it? Can a user change the clock settings on his PC in order to gain unlimited trial time for your software? Can an admin user see personal data about the users managed by him? Maybe this data isn't required in order to do his work?
So, to cut things short, there are many easy-to-find security problems, and you have only to look. But, before starting to wander around in that dark forest, perhaps it is best to describe the security properties that we want to ensure in the program. Usually, when measuring software security, we speak about six properties (there are some other lists, but I like that one), and sost security related attacks will hinder one (or more) of these properties.
· Authentication – the ability to identify someone (or some process) is who he claims to be.
· Integrity – The system's ability to ensure that data, either in transit or in storage, was not changed by an unauthorized entity or was corrupted.
· Non-Repudiation - No one can perform an action and then claim "I didn't do it", since the system is able to provide credible evidence both action and actor (what was done, who did it)
· Confidentiality – Information is available only to those allowed to see it.
· Availability – the system can be used by its legitimate users any time where it is expected to work.
· Authorization – The system will allow a user to perform only actions that are permitted to that user.
The nice fellows in Microsoft came up with a series of threat patterns that targets each item in the above list, and even gave us a cool acronym to remember it (this, by the way, is the reason the list above is ordered in such a way): STRIDE.
Spoofing
Tampering
Repudiation
Information Disclosure
Denial of service
Elevation of privilege
One thing I will not deal with here is the property called "safety" – the property that gives us confidence that the product won't blow up in someone's face. It's not that it is not important, it's just that it is relevant only to certain types of products, and I don’t understand much in this issue.
Anyway, after we are all a bit more comfortable around software security properties, I want to wrap things up by presenting three cases out of the report we got. My intent in quoting them is to show how simple they are and how easily they can be found.
I want also to note that while some of these may look negligible, or even silly, they all have a significant cost to our product – both in terms of effort we had to invest to fix these things in a schedule that meets our client's expectations, and in terms of reputation of our product: when I see such vulnerabilities I assume that those who wrote the software didn't care much about information security, and that's not something we want our customers to think.
So, that in mind – to the list:
1. A user can perform an action that shouldn't be available to him:
In our system we have a group admin user that can create other users. All users created are in the same group as that group admin. However, when the group admin edits the user's properties, he can change its group to a different one.
The nice thing about this vulnerability? It does not require "hacking" of any sort, just legitimate user actions.
In our system we have a group admin user that can create other users. All users created are in the same group as that group admin. However, when the group admin edits the user's properties, he can change its group to a different one.
The nice thing about this vulnerability? It does not require "hacking" of any sort, just legitimate user actions.
2. Reflecting input back to the user:
we had a nice error message when a user could not login – it was something in the line of "Login attempt failed for user X"
Now, imagine a scenario where we get the username "X, please call 1-800-1234567".The user will see that in his error message and will call the attacker, that will now try to extract the password from the user. Changing the username from X to "X, call me" is fairly simple to achieve by injecting a simple JavaScript to the user (thus achieving a "man in the browser" attack) or routing the browser traffic via a proxy.
we had a nice error message when a user could not login – it was something in the line of "Login attempt failed for user X"
Now, imagine a scenario where we get the username "X, please call 1-800-1234567".The user will see that in his error message and will call the attacker, that will now try to extract the password from the user. Changing the username from X to "X, call me" is fairly simple to achieve by injecting a simple JavaScript to the user (thus achieving a "man in the browser" attack) or routing the browser traffic via a proxy.
3. Not checking for permissions on server side:
Really, this was what embarrassed me most. It's in the first page of just about any guide you'll find on dealing with implementing secure software.
What we had was a simple scenario – in a certain user in our application had the permissions to view a page, but not to edit it. The edit button was properly removed, but if someone would click "view" and then stop before sending the request (using a tool such as fiddler) and change "view" into "edit", we would grant access to the edit page.
Really, this was what embarrassed me most. It's in the first page of just about any guide you'll find on dealing with implementing secure software.
What we had was a simple scenario – in a certain user in our application had the permissions to view a page, but not to edit it. The edit button was properly removed, but if someone would click "view" and then stop before sending the request (using a tool such as fiddler) and change "view" into "edit", we would grant access to the edit page.