0

I am still very new to the concepts and design of ASP .NET's MVC and AJAX and I was wondering how secure the Controller is to unwanted user's when webdeployed.

I ask because for fun I made a little admin panel that requires a user name and password. Once input is entered the information is AJAX submitted to a ActionResult method in the Controller that just compares the strings to see if they match, then returns the response back to the AJAX.

My question is, how easy is it for someone to get into my Controller and see the hard-coded password?

No professional-type person will ever try to break into this, as it is a free site for a university club, but I want to make sure that the average Computer Science student couldn't just "break in" if they happen to "rage" or get mad about something (you never know! haha).

Question: Is having a password validation within the Controller "decently" secure on a ASP .NET MVC web-deployed application? Why or why not?

Here is the actual code in case the use of it matters for the answer (domain is omitted for privacy)

Note: I understand this use of Javascript might be bad, but I am looking for an answer relative to AJAX and Controller security of the password check.

View (Admin/)

//runs preloadFunc immediately
window.onpaint = preloadFunc();

function preloadFunc() {
    var prompting = prompt("Please enter the password", "****");
    if (prompting != null) {
        $.ajax({
            url: "/Admin/magicCheck",
            type: "POST",
            data: "magic=" + prompting,
            success: function (resp) {
                if (resp.Success) {
                  //continue loading page
                }
                else {
                    //wrong password, re-ask
                    preloadFunc();
                }
            },
            error: function () {
                  //re-ask
                  preloadFunc();
            }
        });
    }
    else {
       // Hitting cancel
        window.stop();
        window.location.replace("google.com");
    }
}

Controller (ActionResult Snippet)

[HttpPost]
public ActionResult magicCheck(string magic)
    {
        bool success = false;
        if (magic == "pass")
        {
            success = true;
        }
        else
        {
            success = false;
        }
        return Json(new { Success = success });
    }

Again I am new to MVC and AJAX, let alone anything dealing with security so I am just wondering how secure the Controller is, specifically on webdeploy for this simple password setup.

Ry-
  • 218,210
  • 55
  • 464
  • 476
Austin
  • 3,010
  • 23
  • 62
  • 97
  • rather than adding an answer as it has been answered really well by others here are a couple of great websites to look at when it comes to security and "best" practises. http://www.troyhunt.com/, http://brockallen.com/, http://leastprivilege.com/ also Brock's identity project on github https://github.com/brockallen/BrockAllen.MembershipReboot may be a great place to look at (I use this myself for my websites and it takes out all the hassle of having to handle the authentication and authorization sections of security. – David Shorthose Jul 15 '14 at 19:24

4 Answers4

2

During normal operation, there is no concern as your code is compiled, the DLL prevented from being served, and there is no way for the browser to request the controller to divulge its own code.

However, it is not impossible (but quite rare) that unforeseen bugs, vulnerabilities, or misconfigurations of the server could lead to the server divulging compiled code, web.config, etc., whereby someone could disassemble the code (IL is easily decompiled) and reveal your secret.

More worrisome would be someone having physical access to the server just grabbing the binaries directly and disassembling to find your secret.

Another thing to consider is who, during normal situations, might see that secret and whether or not they should know it. A developer, tester, or reviewer may be allowed to write or inspect code, but you may not want them to know the secret.

One way to handle this is not store secrets in plain text. Instead, create a hash of the valid value, then update your application to hash the user's input in the same manner, and compare the results. That way if the user ever gets your source code, they can't read the original plain text value or even copy/paste it into your UI. You can roll your own code to do the hashing, use the FormsAuthentication API, or something else.

Finally, do not rely on client-side enforcement of security. You can check security on the client side to have the UI react appropriately, but all server-side requests should be doing checks to make sure the user's security claims are valid.

The question really goes out of scope from here, regarding how to manage identities, passwords, and make security assertions. Spend a little time looking through the myriad articles on the subject. Also, the Visual Studio ASP.NET project templates include a lot of the security infrastructure already stubbed out for you to give you a head start.

Never leaving things to chance is an important policy. Learning about ASP.NET and MVC's various facilities for authentication and authorization is a worthwhile effort. Plus, there are numerous APIs you can plug in to do a lot of the heavy lifting for you.

Community
  • 1
  • 1
moribvndvs
  • 42,191
  • 11
  • 135
  • 149
  • So it sounds like for the most part it is okay unless there is a fluke in the system or if someone has access to the server? I currently host it with Winhost, so is the server problem an issue in this scenario? Thank you! – Austin Jul 15 '14 at 18:44
  • 1
    It depends on how much you care. If you judge that little damage or annoyance can be done and neither you nor anyone else cares if something happens to it, so be it. But I would encourage everyone that if they're going to do something, do it right. As I said in an edit, there are premade templates in Visual Studio (I suppose it depends on what version you have) that have the security stuff preconfigured for you. You can just edit the app to suit your purposes from there. – moribvndvs Jul 15 '14 at 19:11
2

As has already been pointed out if you can get a hold of the binaries for an app (or for that matter ANY .NET application not just MVC) then it's definately game over.

Just sat in front of me here and now I have 3 applications that make it child's play to see what's inside.

  • Telerick - Just Decompile
  • IL-Spy

Are both freely downloadable in seconds, and the former of the two will take an entire compiled assembly, and actually not just reverse engineer the code, but will create me a solution file and other project assets too, allowing me to load it immediately back into Visual Studio.

Visual Studio meanwhile, will allow me to reference the binaries in another project, then let me browse into them to find out their calling structure using nothing more than the simple object browser.

You can obfuscate your assemblies, and there are plenty of apps to do this, but they still stop short of stopping you from de-compiling the code, and instead just make the reverse engineered code hard to read.

on the flip side

Even if you don't employ anything mentioned above, you can still use command line tools such as "Strings" or editors such as "Ultra Edit 32" and "Notepad++" that can display hex bytes and readable ASCII, to visually pick out interesting text strings (This approach also works well on natively compiled code too)

If your just worried about casual drive by / accidental intrusions, then the first thing you'll want to do is to make sure you DON'T keep your source code in the server folder.

It's amazing just how many production MVC sites Iv'e come accross where the developer has the active project files and development configuration actually on the server that's serving live to the internet.

Thankfully, in most cases, IIS7 is set with sensible defaults, which means that things like '*.CS' files, or 'web.config' files are refused when an attempt is made to download them.

It's by no means however an exact science, just try the following link to see what I mean!!

filetype:config inurl:web.config inurl:ftp

(Don't worry it's safe, it's just a regular Google Search link)

So, to avoid this kind of scenario of leaking documents, a few rules to follow:

  • Use the web publishing wizard, that will ensure that ONLY the files needed to run end up on the server
  • Don't point your live web based FTP root at your project root, in fact if you can don't use FTP at all
  • DO double check everything, and if possible get a couple of trusted friends to try and download things they shouldn't, even with a head start they should struggle

Moving on from the server config, you have a huge mountain of choices for security.

One thing I definitely don't advocate doing though, is rolling your own.

For years now .NET has had a number of very good security based systems baked into it's core, with the mainstay being "ASP.NET Membership" and the current new comer being "ASP.NET simple membership"

Each product has it's own strengths and weaknesses, but every one of them has something that the method your using doesn't and that's global protection

As your existing code stands, it's a simple password on that controller only.

However, what if I don't give it a password.

What happens if I instead, decide to try a few random url's and happen to get lucky.

eg: http://example.com/admin/banned/

and, oh look I have the banned users page up.

This is EXACTLY the type of low hanging entry point that unskilled script kiddies and web-vandals look for. They wander around from site to site, trying random and pseudo random URL's like this, and often times they do get lucky, and find an unprotected page that allows them to get just far enough in, to run an automated script to do the rest.

The scary part is, small college club sites like yours are exactly the type of thing they look for too, a lot of them do this kind of thing for the bragging rights, which they then parade in front of friends with even less skill than themselves, who then look upon them as "Hacking Heroes" because they broke into a "College Site"

If however, you employ something like ASP.NET membership, then not only are you using security that's been tried and tested, but your also placing this protection on every page in your site without having to add boiler plate code to each and every controller you write.

Instead you use simple data annotations to say "This controller is Unprotected" and "This one lets in users without admin status" letting ASP.NET apply site wide security that says "NO" to everything you don't otherwise set rules for.

Finally, if you want the last word in ASP.NET security, MVC or otherwise, then go visit Troyhunt.com I guarantee, if you weren't scared before hand, you will be afterwards.

shawty
  • 5,729
  • 2
  • 37
  • 71
  • Hello! I appreciate all this feedback very much! From what I am getting, this is a terrible way to password protect web application pages and I understand that. You also mention that I need to worry about anything after the `Admin/` domain, which I fixed recently. I have a final question and more-so of a yes/no response. I modified my code to check password on all pages in `Admin/`, it correlates userID and password now, and then set's a cookie to remember that person for 10 minutes. In regards to "accidental break-in" is this secure or no? [PasteBin Code](http://pastebin.com/AwdvrFnJ) – Austin Jul 16 '14 at 13:39
  • 1
    Setting a cookie is the way most of the frameworks today work, yes, but make sure that it's a https (secure cookie) and that it lasts for the session life time only (That is, it dies when the browser closes the page - one thing MANY SITES don't do today is https all pages involved in a secure login, they believe that as long as the login form is https, the password and user name cannot be gotten, however many break ins actually occur because someone grabbed a session cookie off the wire from a non https page that was served over regular http after the login had been completed. – shawty Jul 16 '14 at 15:45
  • 1
    As for your comment on protecting all your pages, well that's good yes, but the issue you have now is one of maintenance. Lets suppose that in 1 years time, your college wants to add 100 extra pages to the site. That's 100 times you having to make sure that your adding the needed code to support your authentication system. Now if it's late, and you've already done 99 of them and are tired, page 100 might just be the one you miss, or make a programming mistake on. That chink in the Armour could very well make all the difference. – shawty Jul 16 '14 at 15:49
  • 1
    RE: your pastebin code. NO, NO and once more NO :-) the first thing that's a huge glaring slap in the face: "setting and resetting your cookie value in the JS", that means I can go along, press F12 in chrome, call your functions and alter the cookie as much as I like, then get your page to believe it's logged in. If your setting cookies like this for auth, they MUST BE SET SERVER SIDE, and what's more as your rolling your own auth, you need to be checking the cookie value you get back from the client on every request too, just to make sure it has not been tampered with. – shawty Jul 16 '14 at 16:03
  • I do call the `.js` on every page to make sure it is still okay. And how would I do this server-side? (in simple terms). I am brand new to all of this stuff and I am not sure how I would preform this server-side. The project right is put online in webdeploy, so isn't being on the server, server-side? Or does it need to be hidden more? – Austin Jul 18 '14 at 12:48
  • 1
    If you want to work with cookies server side see this : http://blogin.codeinside.eu/2010/10/19/howto-create-and-remove-cookies-with-asp-net-mvc/ and for a better understanding of how the newer auth services work : http://benfoster.io/blog/aspnet-identity-stripped-bare-mvc-part-1 Iv'e actually just used the information available in Ben's site to add authentication to an old MVC app that had none, as it's now been upgraded and now needs auth. – shawty Jul 18 '14 at 13:19
  • 1
    Ben's approach works well, and it leverages a LOT of whats already available in .NET preventing you from ever having to do any of the work yourself other than calling API's. – shawty Jul 18 '14 at 13:19
  • I appreciate all of this information, and all of your time. Thank you very much! – Austin Jul 18 '14 at 13:45
  • no probs, hth.. You can generally find me hanging around in 'Lidnug' (The .NET user group) on Linked-in if you ever want to discuss in more detail. – shawty Jul 18 '14 at 15:43
0

It looks like you are sending a password via AJAX POST. To your question, my answer would be that you should consider using SSL or encrypt the password prior to sending it via POST. See this answer for an example and explanation SSL Alternative - encrypt password with JavaScript submit to PHP to decrypt

As HackedByChinese said, the actual code being stored in your compiled files (DLL) wouldn't be too big of a deal. If you want to be extra paranoid, you can also store the password in your web.config and encrypt it there. Here's an example and explanation of that How to encrypt username and password in Web.config in C# 2.0

Community
  • 1
  • 1
user1477388
  • 20,790
  • 32
  • 144
  • 264
0

This code is not secure at all. Your JavaScript code can be replaced with EVERYTHING user wants. So someone can just get rid of your preloadFunc. Average computer sience student will execute this code directly from console:

if (resp.Success) {
    //continue loading page
    //this code can be executed by hand, from console
}

And that will be all when it comes to your security.

Authentication and authorization info should go to server with every request. As a simple solution, you could use FormsAuthentication, by calling

FormsAuthentication.SetAuthCookie("admin")

in /Admin/magicCheck, only if password is correct.

Then you should decorate data retrieval methods with [Authorize] attribute to check if cookie is present.

Using SSL to secure communication between browser and server would be wise too, otherwise password travels in clear text.

moribvndvs
  • 42,191
  • 11
  • 135
  • 149
LukLed
  • 31,452
  • 17
  • 82
  • 107
  • Just setting the cookie with forms authentication is not enough, you also need to configure the parameters for forms auth to work correctly in the applications web.config file. – shawty Jul 16 '14 at 15:52