Assume I want visitors of my site to be able to fill in a long form. That's not necessary for them to fill it in to use the site, but if they want to send a story to me, they need to fill it in. So, some of them will wish to do it, some won't. The form is quite large so visitor may want to leave it semi-filled to come back later and finish it. To make the process as easy as possible for the visitor, I want him just to click a link "Create a story" that will redirect the visitor to an automatically generated url, like www.mysurveys.com/7Bs3h4vSWEe. Here the visitor works with his form and clicks 'Save' when he wants to save it so that to return back later to finish it. The form data is kept in the database with its generated ID. When the visitor thinks the form is filled properly and is done, he clicks 'Send for review' and then the form goes to me.
The question is: how secure is to use this automatically generated URL as the only credential for the user? I suppose any sniffer could easily get the url visitor uses to fill in the form. How to make a process like this as simple as possible? What are ways to make it a little more safe? I know I can do it using standard user registration pattern but I want to make it simpler.
This ID is a lot like having a session id for the user and in that sense its not a compromise. One difference is that session id's should always expire. If security is a concern then HTTPS should be used to prevent eavesdropping.
This url value should be a Cryptographic Nonce. You should also take brute force into consideration. If someone is guessing a lot of keys that don't exist, prompt them with a captcha.
It's not that secure, BUT sniffing is basically the only attack, AND unless the attacker doesn't care whose URL they get, they would have to target their victim quite specifically.
I wouldn't use this for, for example, financial information, or third-party-confidential information, but for low-risk information it might well be fine.
edit: I've ignored brute force, but much the same applies, and as other answers suggest, there are protections against that, like captcha.
Related
I want to password protect a web page. I'm wondering if anyone would critique my approach.
An anonymous user would go to the page and a modal would open up asking the user to enter a password. I would of course not display any content at the back in case anyone decides to be clever and display:none; the modal.
Once the user enters the password, I would redirect and save a randomly generated token as a cookie and check for that so that user wouldn't have to keep entering the password.
Just wondering if there are any security issues here aside from a personal physically accessing the computer and also if there would be any improvements that could be made.
I know I'm still being a little vague on some details, so let me know if there's anything important that I left out in regards to exact implementation.
Even though what you describe might work, in general it's a bad idea to implement your own security. Even if you use https to prevent sniffing of the token, someone might find that your random numbers are not really random and be able to guess the next number.
You will be better off using one of the security feature that comes with the framework in which you are building your application. Most frameworks support something like forms-based authentication. It might even support claims-based authN with security tokens.
As you're not mentioning what framework you're using, I can't recommend anything.
It's a horrible idea. The password as a cookie would be transmitted in the clear in every HTTP request. There are plenty of examples of how to do this correctly. I am not going to elaborate because this question is very likely going to be flagged. NEVER save a password anywhere. The first thing to do with a submitted password is compute a hash value. The hash becomes the password.
So I just read this article by Jeff Atwood and I wanted to make sure I understand it correctly as to how it applies to my use case. I am trying to validate a session for silent login. For security purposes this should be done with a POST right? Does it matter? I am just passing the sessionID and username from the cookie.
When it comes to CSRF (Cross-site request forgery), you can cause a user to take any action on any site which they are logged in to provided that the action requires only a GET. Forcing this to be done over a POST request defeats the approach of embedding an image, script tag, whatever in another page.
Even POST isn't completely secure in this scenario. There are other ways to mount a CSRF attack on a site using POST. Clickjacking/UI-Redressing enables another site to trick a user into submitting a form to a different website.
Basically the best way to validate is to add an automatically generated, hidden form element. You can store this inside your session data (Example: $_SESSION for PHP) so that you only need to generate a token at the start of a session. Of course, an attack could try do something like clickjacking (mentioned above) in combination with a iframe pointing directly to your site and possibly some JS to hide things a little.
For anything important you should re-prompt the user for their password, thereby greatly diminishing the value of any successful CSRF attacks.
My web application displays some sensitive information to a logged in user. The user visits another site without explicitly logging out of my site first. How do I ensure that the other site can not access the sensitive information without accept from me or the user?
If for example my sensitive data is in JavaScript format, the other site can include it in a script tag and read the side effects. I could continue on building a blacklist, but I do not want to enumerate what is unsafe. I want to know what is safe, but I can not find any documentation of this.
UPDATE: In my example JavaScript from the victim site was executed on the attacker's site, not the other way around, which would have been Cross Site Scripting.
Another example is images, where any other site can read the width and height, but I don't think they can read the content, but they can display it.
A third example is that everything without an X-Frame-Options header can be loaded into an iframe, and from there it is possible to steal the data by tricking the user into doing drag-and-drop or copy-and-paste.
The key point of Cross Site Attack is to ensure that your input from user which is going to be displayed, is legal, not containing some scripts. You may stop it at the beginning.
If for example my sensitive data is in JavaScript format, the other site can include it in a script tag
Yep! So don't put it in JavaScript/JSONP format.
The usual fix for passing back JSON or JS code is to put something unexecutable at the front to cause a syntax error or a hang (for(;;); is popular). So including the resource as a <script> doesn't get the attacker anywhere. When you access it from your own site you can fetch it with an XMLHttpRequest and chop off the prefix before evaluating it.
(A workaround that doesn't work is checking window.location in the returned script: when you're being included in an attacker's page they have control of the JavaScript environment and could sabotage the built-in objects to do unexpected things.)
Since I did not get the answer I was looking for here, I asked in another forum an got the answer. It is here:
https://groups.google.com/forum/?fromgroups=#!topic/mozilla.dev.security/9U6HTOh-p4g
I also found this page which answers my question:
http://code.google.com/p/browsersec/wiki/Part2#Life_outside_same-origin_rules
First of all like superpdm states, design your app from the ground up to ensure that either the sensitive information is not stored on the client side in the first place or that it is unintelligible to a malicious users.
Additionally, for items of data you don't have much control over, you can take advantage of inbuilt HTTP controls like HttpOnly that tries to ensure that client-side scripts will not have access to cookies like your session token and so forth. Setting httpOnly on your cookies will go a long way to ensure malicious vbscripts, javascripts etc will not read or modify your client-side tokens.
I think some confusion is still in our web-security knowledge world. You are afraid of Cross Site Request Forgery, and yet describing and looking for solution to Cross Site Scripting.
Cross Site Scripting is a vulnerability that allows malicious person to inject some unwanted content into your site. It may be some text, but it also may be some JS code or VB or Java Applet (I mentioned applets because they can be used to circumvent protection provided by the httpOnly flag). And thus if your aware user clicks on the malicious link he may get his data stolen. It depends on amount of sensitive data presented to the user. Clicking on a link is not only attack vector for XSS attack, If you present to users unfiltered contents provided by other users, someone may also inject some evil code and do some damage. He does not need to steal someone's cookie to get what he wants. And it has notnig to do with visiting other site while still being logged to your app. I recommend:XSS
Cross Site Request Forgery is a vulnerability that allows someone to construct specially crafted form and present it to Logged in user, user after submitting this form may execute operation in your app that he didin't intended. Operation may be transfer, password change, or user add. And this is the threat you are worried about, if user holds session with your app and visits site with such form which gets auto-submited with JS such request gets authenticated, and operation executed. And httpOnly will not protect from it because attacker does not need to access sessionId stored in cookies. I recommend: CSRF
I inherited some code that was recently attacked by repeated remote form submissions.
Initially I implemented some protection by setting a unique session auth token (not the session id). While I realize this specific attack is not CSRF, I adapted my solution from these posts (albeit dated).
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29
http://tyleregeto.com/a-guide-to-nonce
http://shiflett.org/articles/cross-site-request-forgeries
I've also read existing posts on SO, such as Practical non-image based CAPTCHA approaches?
However, the attacker now requests the form page first, starting a valid session, and then passes the session cookie in the following POST request. Therefore having a valid session token. So fail on my part.
I need to put some additional preventative measures in place. I'd like to avoid CAPTCHA (do to poor user experience) and JavaScript solutions if possible. I've also considered referrer checks (can be faked), honeypots (hidden fields), as well as rate limiting (which can be overcome by throttling). This attacker is persistent.
With that said, what would be a more robust solution.
If you are having a human that attacks specifically your page, then you need to find what makes this attacker different from the regular user.
If he spams you with certain URLs or text or alike - block them after they are submitted.
You can also quarantine submissions - don't let them go for say 5 minutes. Within those 5 minutes if you receive another submission to the same form from the same IP - discard both posts and block the IP.
CAPTCHA is good if you use good CAPTCHA, cause many custom home-made captchas are now recognized automatically by specially crafted software.
To summarize - your problem needs not just technical, but more social solutions, aiming at neutralizing the botmaster rather than preventing the bot from posting.
CAPTCHAs were invented for this exact reason. Because there is NO WAY to differentiate 100% between human and bot.
You can throttle your users by increasing a server-side counter, and when it reaches X times, then you can consider it as a bot attack, and lock the site out. Then, when some time elapse (save the time of the attack as well), allow entry.
i've thought a little about this myself.
i had an idea to extend the session auth token to also store a set of randomized form variable names. so instead of
<input name="title" ... >
you'd get
<input name="aZ5KlMsle2" ... >
and then additionally add a bunch of traps fields, which are hidden via css.
if any of the traps are filled out, then it was not a normal user, but a bot examining your html source...
How about a hidden form field? If it gets filled automatically by the bot, you accept the request, but dismiss it.
I have a site which will show sensitive information. I am using Anti Forgery Tokens etc to protect against XSRF in POSTS. However I am worried about someone being able to view sensitive info from a GET. What is the recommended practice for protecting read only data sent via a GET in .Net MVC 2?
If you are sure that GET requests are read-only, then you have nothing to worry from XSRF. Its not possible to steal information from another website using just XSRF, and so you don't need to protect urls via a token. In fact, using tokens in the URL is going to make it impossible to use bookmarks.
Having said that, you should be 100% sure there are no XSS vulnerabilities in your app. If there are, an attacker doesn't need to bother with XSRF and unpredictable tokens.
The XSRF protection on POST data (using tokens like you said) should work on GET data as well. From a hacker's point of view a GET forgery is much easier than POST forgery (at the first you only post a link, at the second you need to point to a malware website with hidden iframe and autosubmit forms), but both of them fail if tokens are checked.
Example:
posting a link like this:
www.domain.tld/page.aspx?get=data&token=token_given_to_hacker
shouldn't return anything, or just an error for those who got other tokens. This way no sensitive action is made for the wrong people.
This is xsrf, with this you can't steal information, but make others submit forms and take action which result only the hackers know. For example:
Changing email, on an email form, to the email of the hacker. Let's assume you have a GET form, with 1 field: the new email (for the sake of simplicity). When submitted the URL looks like this:
www.domain.tld/page.aspx?email=myemail#otherdomain.tld
Now, if a hacker posts a link on your forum with the URL:
www.domain.tld/page.aspx?email=hackers_email#yetotherdomain.tld
Everyone who clicks on it, will get a new email, of the hackers. But if you put a token there, and you'll check it every time, the action will be taken only for those who's the same token was given on page request, in this case the link will work only for the user who posted it, and no one else.
You could also protect sensitive forms, like changing email, password and so on with a password field. Note, that captcha is not much of a help here.