Writing secure web applications - Part III - XSS and Least-Privileged Access
Tags : Microsoft Excel, Tips, Tricks, Software, Visual Basic, Calender, Workbook
If you remember; I said completely securing a web application will certainly render it unusable. But we are doing a darn good job of securing To-Do Master and it still is pretty usable. Of course, that must mean it is not completely secure. So here we are, with the third installment of “writing secure web applications”.
Part 1 and 2 are available here and here respectively. If you are joining us only for this part and do not wish to go through the introductory rants, a summary of To-Do Master is right here.
The To-Do Master feature set:1. It’s a system that lets you maintain a To-Do list. So users can add/edit/delete To-Do items (belonging to the user, we wouldn’t want Mary to edit Lucy’s To-Do list). 2. If a user has administrator access then he/she can add/edit/delete users. 3. The users need to login to access the system. 4. The users can update their passwords. |
We will use a database with two tables:
|
This time we will deal with Cross Site Scripting (CSS or XSS, we will stick to XSS because CSS leads to some confusion with Cascading Style Sheets) and touch upon the importance of using “only what you need” access, usually referred to as “Least-Privileged Access”.
Cross Site Scripting
SQL Injection is usually aimed at causing harm to the web application server. XSS, on the other hand, targets clients of a vulnerable web application. The major use of XSS is embedding a client-side scripting snippet into the page and using it to gather information about the client.
For example: Let us say the login page of the To-Do Master displays an error message if the login was invalid. It uses a GET parameter to specify what kind of an error occurred. So, if Joe tries to login using a wrong password, we re-direct him to:
http://todomaster.com/login?error=Invalid%20password
The login page simply displays the error message as-is and shows the login form. Now, Sam (yes, we changed the villain of our story) desperately wants to know if Joe is planning to ask Lucy out. What better way to do this than check out Joe’s to-do list. Sam composes an email and spoofs the “from” email-address to admin@todomaster.com
Dear Joe,
Due to the overwhelming success of To-Do Master, our servers are under heavy load. We wish to identify our currently active users and inactivate other accounts. Please login by clicking here if you wish to retain your account, otherwise it will be inactivated in two days’ time.
Regards,
Administrator
To-Do Master
The link, of course, points to:
http://todomaster.com/login?error=
If Sam thinks the JavaScript in the URL is too obvious and will make Joe suspicious, he will simply convert it to HEX. After all, sites like Hotmail and Yahoo trail their URLs will all sorts of funny looking characters.
When Joe clicks on the link in the email, he goes to the login page and does not see anything abnormal. But unknown to him, the form submits all the data to Sam’s site. Sam logs the password, and redirects Joe back to the login page:
http://todomaster.com/login?error=Invalid%20password
Poor Joe thinks he must’ve typed the wrong password, re-types it, and logs in, content that his account will remain active in spite of the To-Do Master’s server problems. Now Sam has Joe’s password and the rest will soon be history.
Why was this possible? Simply because the error message was displayed as-is. It ignores the fact that certain characters are special. How to prevent it? By simply encoding everything that can come from user input before you display it on the web-page.
The above example is a simple one to illustrate how attacker’s can exploit the fact that you don’t encode output to your page. If the user’s browser has some vulnerability then the embedded malicious JavaScript could take advantage of that and attack the client’s system. You might not be passing error messages using GET (how foolish is that, you are thinking), but it is a good practice to encode all data displayed on a web-page that might have come from client input. Microsoft and JAVA technologies come with a host of functions to do that. For PHP, you can use htmlspecialchars or htmlentities.
So the golden rule: encode all data displayed on a web-page that might have come from client input.
Least-Privileged Access
Well, we have tried our best to make the attacker’s life difficult. What we can further do is to mitigate the extent of damage that the attacker can cause in case one of the vulnerabilities above escapes our notice. The best way to do this is to use “Least-Privileged Access”. The principle is pretty simple: Give an account /user only as much access as is absolutely critical for its functioning.
For example: To-Do Master does not need to create/drop tables. Thus, the account the web application uses to connect to the database should only have select/update/insert/delete privileges. If you went berserk and embraced this principal in its totality, you would use different accounts to connect to the database on different pages. So the admin account pages will have access to only the user table while the to-do item pages will access only the todo_item table. Maybe the “edititem” page should not access the database with an account having “delete” privileges. But let us maintain some semblance of sanity here; we need to balance maintainability and security.
Let us also extend the principle to the DBMS itself. Run the DBMS using a least-privileged account. If you are using SQL Server disable stored procedures like xp_cmdshell (lets you execute DOS commands). Activate only what you need and sleep easy.
I think it’s time to end this series and I hope all of us will be writing less vulnerable web-apps after these two months. The work of securing an application is never done; if you can use it, it isn’t secure. What we can do (I know, I know, I am repeating myself) is make the attacker’s task more difficult and hence reduce the number of attackers who can take advantage of vulnerabilities.
Happy securing!
Further Reading (if you haven’t had enough):
http://www.cgisecurity.com/articles/xss-faq.shtml
http://www.cert.org/tech_tips/malicious_code_mitigation.html
http://sourceforge.net/project/showfiles.php?group_id=64424
http://www.securereality.com.au/studyinscarlet.txt
http://ist-socrates.berkeley.edu:7309/web_sec/index.html
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/CL_SecDBSe.asp
http://www.sitepoint.com/article/php-security-blunders
Well, if you think the writer of this article deserves a compliment or two (or if you think he should be abused, vilified and never allowed to write a single line of code again) then don’t just sit there. Voice your opinion. Direct your comments, suggestions, corrections (especially), anecdotes, taunts, abuses, compliments and remarks to Tarun.



