Preventing Cross-Site Request Forgery Attacks With a Windows Client Application - c#

I develop an web application by web api2.
My client application is a windows application that developed by C# , .net 4.0.
The client application sends some Json data to the web api application and the application stores data in database.
Now the issue is sending the request with another method except my application and sending dump data to the server.I have authentication on the server but it isn't enough,I need some tokens for handling this issue.
After some searches i find this article and read it, but the client is a web application.
Could i use this method in my windows client app?how?

Bottom line: You shouldn't need to.
By definition, CSRF attacks can only affect client applications that share cookies across domains. e.g. if you visit www.bank.com with your browser and then open another tab to www.evil.com, if www.bank.com does not protect against CSRF then www.evil.com may be able to POST a form submission to www.bank.com while you are logged in and then transfer money by forging the request to the form's action URL on the transfer money page.
If your client is a Windows application, the HTTP client should not have cookies stored for any other service other than your web API.
Note that the above only applies to when cookies are used as the session management mechanism (i.e. not Kerberos, NTLM, Basic Auth, etc).
.I have authentication on the server but it isn't enough
This should be enough as an attacker cannot forge a HTTP request to your API that will be sent along with the victim's cookies as the cookies are separated due to there being different instances of web clients. Much like being logged into Google on Chrome, but then accessing Google on Firefox - you will not share the same logged in session.
Of course, protect your API with HTTPS so the information is encrypted whilst in transit. Note that this does not protect against decompilation of your source code, which is something that is not easy to prevent. At the end of the day you cannot trust clients that are not under your control. You can make it difficult, but not impossible to prevent someone working out or changing what is being sent to your API.

Cross site anti-forgery tokens are a form of authentication. It authenticates the client who's sending the request: the client has to visit a certain page to get the token from the server, so it cannot be any client who has not visited that page and some how just send random data to that server.
The purpose of authentication is for the server to authenticate the client (other way around is also possible, but let's forget that for the moment). You setup the system such that it is very difficult for others to pretend to be your Windows Form app. Note it can be very difficult, but theoretically it's always possible to fake. So the aim is to setup an auth such that an attacker considers it impractical to launch an attack.
This auth should not be mixed up with the authentication to verify the human user. They are different. An app can provide a UI for human users to login, but the app is not written by you. So you need to authenticate 2 things:
the request actually comes from your app, if that succeeds, then
the human user is who he claims he is, otherwise
reject the request

Related

should sign in occur in the front-end or the back-end of an asp.net project

I am trying to build a web project that will include user sign in. It will have an asp.net front-end, and an asp.net back-end. I am trying to figure out how this should work with user context and where user sign-in should happen. I believe controlling user sign in is a back-end responsibility, but it seems that many 3rd party validation methods would prefer it to be front-end. As I understand it seems that if I was using something like google or Microsoft validation. It would try to bring up a window, but that window wouldn't be seen by my user, because it was coming from the back-end that is not serving them, and is instead serving the front-end server.
Based on your comments I'll try to summarize a bit here. Do note, that this is not a coding question and should really have been asked on https://security.stackexchange.com/, but I'll give it a go.
A few keywords you should read up on:
Authentication: This is the process of verifying the identity of an entity (a person, device etc.)
Authorization: This is the process of granting access to a given resource based on some parameters - usually based on a verified identity
Identity provider: A system that manages and can verify the identity of an entity (in your example that would be Google or Microsoft)
Service provider: A system providing a service to authenticated entities (in this case your server application)
OAuth, which you use as an example, is not an authentication protocol but an authorization protocol, which makes it important for you to understand the difference. However, OpenID Connect is a protocol/layer built on top of OAuth 2.0 and...
It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server [read: "Identity provider" under the hood]. [source]
Copied from Wikipedia (point 8 removed to avoid confusion):
The communication flow in both processes is similar:
(Not pictured) The user requests a resource or site login from the application.
The site sees that the user is not authenticated. It formulates a request for the identity provider, encodes it, and sends it to the user as part of a redirect URL.
The user's browser requests the redirect URL for the identity provider, including the application's request
If necessary, the identity provider authenticates the user (perhaps by asking them for their username and password)
Once the identity provider is satisfied that the user is sufficiently authenticated, it processes the application's request, formulates a response, and sends that back to the user along with a redirect URL back to the application.
The user's browser requests the redirect URL that goes back to the application, including the identity provider's response
The application decodes the identity provider's response, and carries on accordingly.
This is the flow you're asking about. The only thing the client (front end) does is follow the URLs it's provided from your application in order to visit an authentication server. This server then provides the proven identity that your client then passes on to your server again.
So bottom line is, the client/front end does not perform the authentication, that's handled by the identity provider (a 3rd party backend).

How to obtain credentials for Http Basic Authentiction

I'm writing a C# application and need to scrape some information from an rss page that only offers Http Basic Authentication.
This seems to leave me with two choices
Ask the user to input their credentials into my app (which has trust issues as the app is then a potential middleman attacker?)
Get windows to insert the credentials on behalf of my app somehow (does this facility exist?)
All the examples I've seen on SO have the username/password hardcoded in the app or passed in as parameters from somewhere unspecified. My use-case is I'd like to give this app to people who may not want to trust it with their password.
How is this usually handled? Thanks
Short answer: It is not possible with basic auth. It is generally not possible with the OS a the trusted instance.
Long answer:
The proper way to solve this would involve a procedure where your application hands control to the OS (Windows), which then asks the user "Do you trust application XY to use your identity?". After user acceptance, your application would receive a security token which you could use afterwards to make your HTTP request to get the RSS feed. The problem is, that the site in question does only accept basic auth. This means, that the "security token" is the base64-encoded username and password. So the username and password would be exposed to your application anyway.
The second problem is that the OS and the RSS site have to share a secret (i.e. an encryption key not available to you or anyone else not allowed to log in site users), to enable the OS to issue a secure token that is trusted by the RSS site.
How the problem can actually be solved
The default, real-world example for the access of web resources with third-party software on behalf of the user without knowing his password is OAuth, see for example the Facebook login flow. (However, this requires the website/resource in question to provide third-party access. As your question indicates, this does not apply for your use case.)
The pattern employed is the following:
Prerequisite: You need to register your application with the RSS service provider to obtain an application ID and an application secret.
Your application redirects the user to the login endpoint of the identity provider.
The user accepts (or declines) the access of your application to his identity and data (e.g. the RSS stream).
The identity provider redirects to your app
Your application receives a token which can be used to make authenticated requests on behalf of the user. This may involve additional steps like exchanging the token for another.
Alternative Solution (does not answer your question):
Sometimes (protected) RSS feeds can be accessed via secret user-specific URLs. Of course, the user would have to provide your application with that url.

How to handle persistent login from in MVVM application?

I'm writing an application which displays a login form before it loads, and it sends a POST request to a web application which I previously developed.
I can send login details off and get returned a 200 message and can recieve data within that request. However I now wish to store this login after the application has closed, to allow the user to not have to login every time they open the application, or in this case when the computer is restarted. (It will run at boot however needs to maintain an application and not a WCF service)
I'm using HTTPWebRequest in C# to handle POST requests to the server, and I can make cookies on the server side. How do I let my application know about these cookies and store them in a secure way to allow persistent login for my entire application? I've looked at a number of ways to store cookies in C# such as these two links:
http://www.c-sharpcorner.com/uploadfile/mahesh/managing-cookies-in-a-wpf-application/
http://msdn.microsoft.com/en-us/library/dd920298(v=vs.95).aspx
However the code in the first link gave me an odd cookie:
"CSCUser2=test-username; android_developer_C:_width=243px; __utma=1.1718972007.1316996246.1316996246.1316996246.1; __utmz=1.1316996246.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); android_developer_reference_lastpage=/C:/AndroidSDK/android-sdk-windows/docs/reference/android/speech/RecognizerIntent.html"
So I'm not sure if that approach is best? Any pointers would be appreciated.
I think the CookieContainer (i.e. the MSDN link) is the correct way to set and get cookies (By the way: note that your question has nothing to do with wpf or mvvm patter. It is a general c# /.net/httpwebreuqest topic).
As for caching credentials on the user machine which can be used in subsequent sessions - there are several ways to do this. You can either store the user password in a secure location, or you can store a session key sent to you from the server. The advantage of the second method is that the session key is limited in time (e.g. one week), and after that they user will have to perform a new login. The session key can be delivered to you from the server out of band as a cookie, or with a specific API. Web applications are using cookies because they have no access to any persistent store, but your wpf application can store the password or the session key anywhere it wants.
I recommend you use the DPAPI to persist secrets on the user computer. Google for c# and DPAPI to see how to do it in .net.

Automatic AND Secure Web Login from Client Application

We have a client application running on each users computer that has a link to the associated web application.
A recent requirement is that if the user is logged in on the client application that they should be able to click the link and be automatically logged in on the web application.
Our web application is encrypted using SSL. Our client application is in Silverlight.
Is there a way to achieve this securely?
Our first naive thought was simply to embed the username and password in the url for the site, but obviously this is not secure because it is visible in the history and via the back button.
Attempt two involved simply converting the password segment into Base64 as to obscure it from view and trust in the SSL to encrypt it.
I'm still not happy. Ideally we would want to use some sort of time based token that expires within minutes of being used.
Where do we start?
If this becomes overly complicated (special hardware) or requires the user to do anything other than click the link-button then the feature will be dropped.
Perhaps you could make an authenticated web service call from the client application to the web application to obtain a token when the user clicks on the link, and then append the token to the querystring? Then the user is logged into the web application using the token, which is then immediately invalidated (valid for one-time use only).

Synchronizing sessions over domains

how can I synchronize sessionID over multiple second-domain servers? For example, I've got servers(you can log-in into server swarm at any of these), www.service1.com, www.service2.com, www.service3.com, and if you log in at one of them, the login information (+anything else) should persist along them. How can I provide SessionID to other domains? (session itself is stored on sql server shared across the services).
Cross domain logins are possible, but very tricky, and prone to issues.
Generally a scheme to do this will involve a third server that acts a centralized auth server. Login requests on individual sites will route through the auth server and the auth server will pass back a secure token to use as a session id.
I've seen this session id passed back to the server via url redirects, and also through back end server communication.
My personal advice would be to use the auth server as a webservice of some sort, and maintain individual sites logins separately. The workflow would be roughly:
Sign in on a given site
The site would send a behind the scenes request to the auth server asking for authentication and information
The auth server would respond appropriately
The site would login on success, and show error message on failure.
It is possible to use some fancy redirects and some forms of trust to implement a auto login system, but honestly such things are rarely if ever worth it. The above suggestion would end up with them having to login on each individual site, but they'd share the same credentials and profile on every site.
Don't you mean across domains?
This is not possible due to security features in browsers. Browsers do not allow cookies to be accessed across domains.

Categories