Techniques around administrative/super user code being exposed - ruby-on-rails

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!

Related

How to securely show an auto-generated password in MVC 4?

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.

Single sign-on, multiple domains on same server, ruby on rails

If I have a single server with multiple domains, what is the preferred method for implementing a single-sign-on solution on the same domain. I am currently using devise, have a few million cookies in place on separate domains, and am stuck. On top of just implementing SSO, I also need to migrate the various cookies to a central domain. Regarding the various servers, they only have one single page that requires me to show different states depending on whether or not the user is logged in.
I have tried the following:
CORS: pick one domain as the central auth hub. From all other domains make cross domain checks to see if the user is logged in. For migrating cookies, detect if there's a "current_user" object, send it to the client, make a CORS request, sign the user in and kill the token. Works Great! BUT... After building it for 2-3 weeks, it TOTALLY FAILS in IE. Even IE11, I'm noticing the default setting is disabling this behavior.
tried tinkering with the session store at
Rails.application.config.session_store
with no luck.
I am currently experimenting with the following:
JSONP: I have someone right now trying to convert the above to JSONP instead while I try some other options:
Set up a custom OAUTH provider. Like before, it will be the "central domain" if the person is signed in, return to the requested domain with a token from which the users can make requests. https://github.com/songkick/oauth2-provider
Looking at this but it looks outdated? https://github.com/rubycas/rubycas-client. I also get the feeling this could have been a solution if I rolled this out from the get-go, but given how far we are into the project, it's unclear to me how I'd transfer the existing cookies. Also it's unclear if this requires two applications for me to get up and running ( one for client(s), one for auth server)
As I go through each of these possibilities, if anyone has had any experience doing what I'm doing, please do inform me and save me a whole lot of work :)
The best way unless this is a toy app is probably to set up an oauth provider.
We use Doorkeeper with Devise for this and it works great. It will be worth your time to set a little time aside to read through the documentation and watch a talk or two on youtube if you're not already familiar with the strategy but once you understand the core concepts its actually pretty simple to set up with the help of this gem.
There is a quick video run down on http://railscasts.com/episodes/353-oauth-with-doorkeeper

HTTP requests, session keys, and authorization as they relate to Rails

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.

Protect deeplink to unauthorized company

I have a multi-tenant application with Companies which have many Users and many Clients.
I have protected the views and controllers with before_filters, so that the current_user can only view clients belonging to the user's company. This works fine, an unauthorized user receives a "you do not have sufficient rights for this action" message. But when a user changes the URL from e.g. "/clients/1/edit" to "clients/2/edit", then he can edit a client from another company. What's the best way to protect this?
Expand your strategy to protect the clients controller as well - you need to be checking ownership of a client record on every action, since only some people should be able to access some clients.
You should be able to continue with whatever solution you've got. Another way to go about it is to use something like CanCan, which centralizes access, and can make it much easier and more straight forward to debug (and more importantly, confirm via your test suite) that users only have access to what they should have access to.
Here is a list of common/popular authorizations gems for Rails that address problems of user access to resources.
Whatever approach you ultimately choose, I can't stress enough how important it is to cover things like security access with test coverage. It's never perfect (because you might forget to test something), but it will mitigate the possibility that you break security access restrictions that are already in place, by keeping your security-related tests as up-to-date as humanly possible.

ASP.NET MVC Security checklist

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.

Resources