Is there a good way of securing an ASP.Net web service call made via Javascript on the click event handler of an HTML button? - asp.net

The purpose of using a Javascript proxy for the Web Service using a service reference with Script Manager is to avoid a page load. If the information being retrieved is potentially sensitive, is there a way to secure this web service call other than using SSL?

If your worried about other people access your web service directly, you could check the calling IP address and host header and make sure it matches expected IP's addresses.
If your worried about people stealing information during it's journey from the server to the client, SSL is the only way to go.

I would use ssl it would also depend I suppose on how sensitive your information is.

I would:
Use SSL for the connection
Put a time and session based token in the request
Validate the inputs against expected ranges on the server
SSL prevents man-in-the-middle
Tokenized requests verify that the request is coming from an active and authenticated session, within a reasonable amount of time from the last activity within the session. This prevents stale requests being re-submitted and verifies that it came from the source of the session (store the IP address, user-agent, etc on the server for session management).
Validating that the inputs are within expected ranges verifies that the request has not been doctored by the party that you are talking to.

Though SSL would be best, there are a number of client-side cryptography libraries that could alleviate some of the security concerns - see https://github.com/jbt/js-crypto for a nice collection

Related

Does Forms Authentication protect from session hijacking?

I have ASP.NET MVC app that uses Forms Authentication. After user is authenticated, in response he will receive forms cookie that contains auth information. Now regarding the forms cookie: It is encrypted by a machine key and it is protected from tampering by signature. I also use HTTPS... However, what if somehow I get the cookie and try to make request from another client (meaning that the request will be made from another IP address)?
It seems to me that this scenario will work. Are there any ways to defend from this kind of attack?
If you are using HTTPS everywhere on your site and set requireSSL="true" on your system.web/authentication/forms element in web.config, you are instructing the browser to only pass that cookie back over an HTTPS connection. This will protect against the vast majority of traffic sniffing-based session hijacking attacks and you should definitely use it if your site is HTTPS only.
Forms Authentication is inherently stateless. The server is encrypting the following information and storing it client-side: CookiePath, Expiration, Expired, IsPersistent, IssueDate, Name, UserData, Version. Assuming your machineKey hasn't been compromised, the client will just see this as a blob of encrypted data. When it presents that blob to the server again, the server decrypts it and converts it back into a FormsAuthenticationTicket, validates the fields in the ticket against config, verifies that the ticket isn't expired, etc. and decides whether to treat the request as authenticated. It doesn't 'remember' anything about which tickets are outstanding. Also note that it doesn't include the IP address anywhere.
The only real attack vector I can think of if you are HTTPS-only, take care to protect your machineKey, and set the forms auth cookie to requireSSL would be for an attacker to target the client's browser and/or computer. Theoretically they could steal the cookie from memory or disk out of the browser's space. It might be possible for a virus/trojan to do this or even a malicious browser extension. In short, if a user could get their hands on a valid, non-expired Forms Auth cookie, they could present it from any machine they wanted to until it expired. You can reduce the risk here by not allowing persistent auth cookies and keeping your timeouts to a minimum.
If they had the machineKey, they could create FormsAuth cookies from scratch whenever they wanted to.
Oh.. Can't forget Heartbleed. If you had a load balancer or reverse proxy that was using an insecure version of OpenSSL, it's possible an attacker could compromise your private key and intercept traffic over HTTPS connections. ASP.NET doesn't use OpenSSL, so you're safe from this in a pure-MS stack. If you ever hear anything about a vulnerability in MS' SSL implementation, you'd want to patch it ASAP and get your passwords changed and certificates re-issued.
If you are concerned about the browser/machine based hijacking, you might want to take a look at a project I started [and abandoned] called Sholo.Web.Security (https://github.com/scottt732/SholoWebSecurity). It's goal was to strengthen Forms Authentication by maintaining state on the server at the expense of some overhead on each request. You get the ability to do things like revoke tickets server-side (kick/logout a user) and prevent users from moving tickets between IP addresses. It can get annoying in the traveling mobile user scenario that Wiktor describes (it's optional). Feel free to fork it or submit pull requests.
The Anti-CSRF features that 0leg refers to apply to the UI/form mechanism that initiates the login process, but to my knowledge there is nothing in the Forms Authentication process itself that relates to CSRF. That is, once the cookie is issued to the client, the only thing protecting it from being bounced between servers is the fact that cookies are restricted to the domains/subdomain they were issued for. Your stackoverflow.com cookies won't be presented to serverfault.com. The browser takes care of that stuff for you.
Are there any ways to defend from that kind of attacks?
You shouldn't. Years ago we have had implemented such feature and abandoned it soon. It turned out that:
a single user making requests from the very same browser/machine but switching between http/https can sometimes be seen from different IP adresses
a single user traveling and using her mobile phone sometimes makes consecutive requests from different IP addresses when her phone switches between BTSes
Just to clarify the terminology, session hijacking is usually referred to the vulnerability where an unauthorized user accesses the session state on the server.
Authentication cookies are different from session cookies. ASP.NET puts a great deal more precautions in safeguarding authentication cookies. What you describe is better described by the term CSRF (Cross Site Request Forgery). As #Wiktor indicated in his response, restricting access by IP is not practical. Plus, if you read how CSRF works, the exploit can run in the user browser from the original IP address.
The good news is that ASP.NET MVC has built in support for CSRF prevention that is pretty easy to implement. Read here.

How are user logins from a desktop application usually handled?

What is the common(best practice) way of allowing a user to sign in from a Windows desktop application. Some examples of what I mean are Dropbox or Google Picasa. You sign in with your credentials and then the software is permanently signed in.
I assume the communication takes place over HTTPS. Does the client store the credentials to be sent with requests or is there some sort of token generated? Can anyone point me to some resources on how this should be handled?
Logging into a website normally creates a session at the server. The server then has to identify subsequent requests by the session. Typically, there is one of the following two solutions applied:
Session cookie, storing a session identifier
URL rewriting, where the session identifier is appended to every link in the html source
Which approach is taken is site dependent, so if you are writing a general 'for all sites' client, you might have to implement both.
In the former case, your application will have to handle the session cookies, in the second case, your application has either nothing to do - if it caches the html response - or will have to emulate the url rewriting itself.
In both cases be aware that the session will expire at server side after a certain period without any activity, so you might be required to generate such.

Does HTTPS protect against CSRF attacks?

I'm writing a mostly ajax-driven web application and I'm looking at how to protect the user from CSRF attacks. I'm planning to run the pages of the application where the user is logged in to do his work in HTTPS mode.
Does running the page on HTTPS work to protect against CSRF attacks?
No, running a page on HTTPS does not protect it from CSRF. The fact that the communications between the browser and server is encrypted has no bearing on CSRF.
I suggest reading the OWASP guidance on preventing CSRF.
A general, golden rule woule be:
Never trust that the incoming client request is a legitimate one. Be always suspicious and assume that the request could be maliciously forged.
Few specific rules beyond the mentioned OWASP article:
if your data needs authentication/authorization, avoid generic interfaces on the server, like the CRUD interface. easy to code, difficult to authorize specific requests coming from clients. instead, offer a SOA-style interface with explicit methods dedicated to specific use cases where you will have direct control over requests and their parameters.
http://msdn.microsoft.com/en-us/library/ms954638.aspx
even if the framework provides some control over the request validity (ASP.NET viewstate), check again if the user is authorized to pass the set of incoming parameters.
I'll try to explain:
• HTTPS prevents from someone on the same network to get your Session KEY/ID. Say they got your session identification key/id, then they can fake your IP if needed and send all POST requests they want back to server.
With HTTPS all HTTP body (the whole "HTML") is encrypted. Hence no session key is being guessed.
• What happens in CSRF is that the user is clicks a link, which also creates a request to another server and communicates with it, say using user's session but NOT ON THE SAME NETWORK. Means that it cannot listen to what the server replies back to user. If the attacker knows the replies and can communicate them, voila. No problem. No money's left on the user account. But if the server sends a random token to the IP associated with the session, then the attacker cannot guess it on a different network!
The best possible solution is to include secret tokens - to identify the user - in form submissions to the server. Refer to the following links for more information.
http://en.wikipedia.org/wiki/Cross-site_request_forgery
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
http://www.codinghorror.com/blog/2008/10/preventing-csrf-and-xsrf-attacks.html
http://seclab.stanford.edu/websec/csrf/
https doesn't safeguard your app from xss attacks. You need csrf token which should be (1) encrypted (2) expiring after some time (3) CSRF token based on page & time

Is a three-tiered architecture with REST-like Business Logic possible or viable for secure web applications?

So feel free to not only answer this question but to throw out suggestions or improvements. I've never put together a large scale web application before. Here's my thought process:
Persistence Layer: Standard Database (MySQL right now)
Business Logic Layer: REST-like structure (PHP, Java Servlets, etc...)
Presentation Layer: Web Browser, Android devices (application not browser), and others
The reason I selected this architecture is so that devices can devise their own custom UI's and tap into the REST-like functionality by using GET, POST, and what not to interact with the server.
Problem 1:
The problem is, how do you secure user's information? You can authenticate the user over an SSL connection and return a special HASH so that the user can manipulate their account but if someone is listening on the network, all they have to do is listen for a REST call and steal the HASH. One solution is that all REST-like calls have to be over SSL, but this causes another problem.
Problem 2:
If the REST procedures are in SSL, the browser has to use SSL for everything which from my understanding can be slow and cumbersome when unnecessary. Also, SOP makes it impossible to use SSL ajax calls to the REST procedures from an unsecure browser. HTTP and HTTPS are considered different origins even though its the same origin, different protocol.
Is this solution viable? How would I solve these two problems? Or possibly (probably) is there a better architecture I should look into for my web application. Thanks in advance for all suggestions.
If you want to secure the information you have to use SSL, since anybody can listen the network, and see the user information. If you want to secure the access, then use HTTP authentication RFC2617. Over SSL, Basic is secure enough, but if you don't want to use SSL for every request, Digest is the way to go:
your application can be stateless: i.e. more restful, easier load balancing, ...
the authentication token can hardly be reused if listen (no session hijacking)
almost every HTTP client (browser or lib) can use basic or digest HTTP authentication.
As it turns out, there is actually no great solution out there for this answer. You can either protect everything with SSL or devise your own home brew authentication system. A common method is to send the user a unique HASH, store the HASH in the database and in a cookie on the client's machine. Then only that user's IP, User-Agent, etc.. will be authenticated to that cookie.
So the answer is yes, the solution is viable. Extra security precautions will need to be maintained in order to disallow account hijacking. SSL for login will protected the password. A unique hash will allow the user to continue being authenticated without giving away their password to the account. Storing a large amount of information about the user such as IP, browser agent, etc... will disallow easy hijacking of an account.

Pass value from one ASP.NET app to another via HTTP Header

We are implementing a single sign on mechanism in an enterprise environment, where the token is shared between applications using HTTP header. Now, in order to do the integration test, I need to write an application to simulate this.
Is there any way in ASP.NET where I can redirect to another web-page and pass a custom HTTP header in the process?
Thanks
You need to create a page on Site B that Site A redirects the user too that sets a cookie with the desired value.
for instance.
http://siteb.com/authenticate.aspx?authtoken=15128901428901428904jasklads&returnUrl=http://siteb.com/index.aspx
authenticate.aspx would set a cookie and then every request would receive authtoken.
The server could send the HTTP header to the client on a redirect, but the client would not send it back to the other remote server.
The ideal solution in this case would be to use a Cookie, or a QueryString variable. Cookies may suffer from cross-domain issues and become complicated if host names are different enough.
In any of these approaches, one must be careful not to create a security hole by trusting this information as it is user input coming back from the client (or some black hat).

Resources