I have a toy web application that can be described roughly as a per-user key-value store. After logging in, the user can view and modify her set of key-value pairs. The keys and values are stored in a database on the server. The keys or values are not shared among users in any way.

I just discovered that JavaScript code included in the keys or values was not properly escaped. So if a user added a key foo with a value of bar <script>alert(1)</script>, the script would execute in the user's browser.

Of course, I fixed this as soon as I noticed it. But I was left wondering: Can this be exploited to do anything harmful? Remember that the key-value pairs are ONLY ever shown to the user who created them.

(The only scenario I could think of is rather far fetched: An attacker convinces the user to navigate to my web application and then to click on a rogue bookmarklet. The bookmarklet saves a key-value pair with a script that steals the user's key-value pairs. Because this is persisted to the database, the key-value pairs will be sent to the attacker every time the user loads the page. But with a rogue bookmarklet you can do almost anything anyway...)

Supposing the hacker could somehow inject the JS into someone else's profile (via hacking account, CSRF, etc.) then there is a definite risk. The JS could be used to create an entirely different page (most easily with an iframe). That new page would overwrite or overlap your existing page, and it would capture sensitive information entered by the user.
–
MosesNov 8 '12 at 19:11

Practise Defence in depth: Lock down all occurrences of common vulnerabilities, as when combined with another vulnerability on your site (which in itself might be harmless too) could open up a hole.
–
SilverlightFoxNov 9 '12 at 12:38

To clarify: As I said in the question, I fixed the vulnerability as soon as I spotted it. I was just wondering if this vulnerability could be exploited on its own. Apparently not, but I do agree with the argument that it can be combined with another (currently unknown) vulnerability, and then all hell will break loose.
–
cberzanNov 9 '12 at 16:29

4 Answers
4

There may be some potential for a CSRF attack, where an attacker maliciously saves a key value pair on behalf of your users. Then the executable JS in the key value pair might be able to be used for a run of the mill XSS attack to steal their cookies and potentially allow the attacker access to the application as the victim.

I agree with Jimmy's comment. If there's any possibility to properly scrub the user input, that would definitely be my first priority.

I had to look this up so I thought I'd note it here for any other people as less informed as me: A real world example of this problem can arise if a hacker sends a fake e-mail with a link to a page in the web application where javascript code has been added to the query string of the link in such a way that allows it to run on the page and potentially steal user input like usernames and passwords.
–
ioSamuraiFeb 22 '13 at 2:04

It's hard to say without looking at your app in detail, but yes, there is a potential for attacks here. If there is any way that a key-value pair might get stored into a user's profile, where the value is partially or completely controlled by someone else, then this could lead to an XSS attack.

Example: Suppose that there's a way to send a user an instant message, and the message automatically gets saved into the recipient's key-value store (or perhaps there is a button the user can press to save it). Then you've got problems.

If your app has a lot of functionality, there are many ways that untrusted data might end up getting stored into the key-value store. Therefore, I would suggest that you fix this vulnerability. A standard way to fix this is escape the value before inserting it into the HTML document.

I thought storing unescaped data was in itself a security risk (albeit a very small one), therefore you should be escaping data before it is stored in the database.
–
MosesNov 8 '12 at 19:15

2

@Moses, Well... no, I don't think that's quite right. The issue is more nuanced than that. If you want details, please post a separate question about "Should we always escape all data before it is stored in the database?". See also Filter user input before the database or upon display? The most important thing is to have a consistent policy: e.g., "everything in the database is 'trusted' (always escape before putting in the database)" or "everything in the database is untrusted (always escape anything you pull out of the database)".
–
D.W.Nov 8 '12 at 20:23

As D.W. says its hard to say without knowing the application. If you were 110% sure that the key value would never be shown to any other user than the user who put it there then no I dont see any danger but that dosent make up for the fact that its open for XSS. You should always fix these things - applications evolve and someday that key value suddenly have become open to other users and then you have problems :)