How to protect calls to web services from being visible - wcf

im using silverlight 5 and WCF .. and the site is secured with HTTPS . however if i use fiddler , i can see this in the headers:
GET /ClientBin/XXXX-Web-MyService.svc/binary/GetUsers
if i put that directly after my domain : https://www.mydom.com/ClientBin/XXXX-Web-MyService.svc/binary/GetUsers
it will download all data from tabel users. how can i hide and protect this information from being visible!! isn't using SSL enought ? why is this visible anyways if im using https!?
thank you.
EDIT: my initial question was kind of an 'uneducated' one and for that i apologies,
i found more info on the subject and did more research. in this Q on SO there is an explanation to why fiddler is able to decrypt and view requests and responses sent over https.
What is point of SSL if fiddler 2 can decrypt all calls over HTTPS?
and to make things even more difficult, the common solution to this problem is using
"Certificate Pinning"
which requires the use of System.Net.ServicePointManager which is not included in the silverlight implementation of System.Net namespace.
so here i am stuck with an SSL cert. that i paid for that can be "cracked" by anyone with basic knowledge of web debugging.

From a purely Theoretical Computer Science point of view, what you are asking for is near impossible to actually impossible. You would need to implement a trusted platform to protect against the attack.
Now for the Science bit, Concentrate
Okay, so lets start with some basic theory. SSL and thus by extension HTTPS solves a very very specific problem. How do you communicate information over an unsecure NETWORK confidential information with a party you have never communicated with before. In this case, the emphasis is on NETWORK. It does so by solving two problems,
Authentication of the server (the server is who it says it is)
Asymmetric Encryption of key exchange
There is some overlap, to ensure that this is one step. I will focus on the 1st, as this is where fiddler "attacks" your system.
The SSL authentication works on a concept of a web of trust. Your computer has a list of TRUSTED verifiers. These are companies like Verisign, Thawte, Geotrust etc. These companies verify certificates by signing them (complex asymmetric encryption term, but its very like a handwritten signature, hard to forge, easy to verify).
Fiddler works by inserting a new trusted CA (verifier) into your computer. From then on, when you visit an HTTPS site, it will send requests on your behalf, reads it then forwards it back on to you with its OWN SIGNATURE. Since your computer completely trusts this signature, it thinks nothing is wrong.
Now, you want to implement certificate pinning. This IMHO is "bloody awful". It works by telling your software to expect a specific SSL cert. Two reasons why this is bad.
If I can work Fiddler, I can work dotPeek and recompile WITHOUT certificate pinning.
When your certificate gets revoked, your clients won't be able to connect.
Why would your certificate be revoked? If your CA loses their private keys, then they will be obliged to make sure its revoked and a replacement sent to you. Also each and every certificate has a sell by date as well, and must be replaced before they start to smell.
So finally what can you do?
SSL is NOT designed for protecting against what you are doing on your machine. The simpliest way to do what you are asking is to simply wrap your WCF calls in an extra layer of symmetric (or even asymmetric) encryption. But once again. The keys must live somewhere, so your client WILL be able to get the keys from a simple disassemble of your binaries and be able to construct a proxy of their own.
In conclusion
This is pretty much exactly the same as the DRM problem. You want to give your customer access to something on their machine but not show them how it works. If you do manage to solve this problem, do post a follow up, since Sony, Nintendo and Microsoft (to name a few) would be very interested in your findings.

Related

Is SSL enough for protecting a request and its headers?

I ask this because I work on an application where the X-AUTH-TOKEN can be copied from one request to another and impersonate another person. This makes me nervous, but I'm told since we're going to use HTTPS we don't have to worry about anything.
So, my question is: Is it good enough trust SSL to protect against stealing headers used for auth/sessions?
Thanks,
Using HTTPS encryption will indeed prevent someone from stealing your authentication token if they can intercept the traffic. It won't necessarily prevent a man-in-the-middle attack though unless the client enables peer certificate checking.
This question from the security stackexchange describes how to implement MITM attacks against SSL. If I can convince a client running HTTPS to connect to my server, and they accept my certificate then I can steal your authentication token and re-use it. Peer certificate validation is sometimes a bit of a pain to setup but it can give you a higher chance of whomever you are connecting to are who they say that are.
"Good enough" is a relative definition and depends on your level of paranoia. Personally I would be happy that my connection is secure enough with HTTPS and peer certificate validation turned on.
Presumably also your authentication token times out so the attack window would be time limited. For example the OpenStack authentication token is by default valid for 24 hours before it expires and then you are required to obtain a new one.
The HTTPS standard implements HTTP entirely on top of SSL/TLS. Because of this, practically everything except for the DNS query is encrypted. Since headers are part of the request and response, and only sent after the secure-channel has been created, they are precisely as secure as the implementation of HTTPS on the given server.
HTTPS is an end-to-end encryption of the entire HTTP session, including the headers, so on the face of it, you should be safe from eavesdropping.
However, that is only part of the story: depending on how the clients are actually connecting (is this a website or an API service?), it may still be possible to trick them into sending the data to the wrong place, for instance:
Presenting a "man in the middle" site with an invalid SSL certificate (since it won't be from a trusted authority, or won't be for the right domain) but convincing users to by-pass this check. Modern browsers make a big fuss about this kind of thing, but libraries for connecting to APIs might not.
Presenting a different site / service end-point at a slightly different URL, with a valid SSL certificate, harvesting authentication tokens, and using them to connect to the real service.
Harvesting the token inside the client application, before it is sent over HTTPS.
No one approach to security is ever sufficient to prevent all attacks. The main consideration should be the trade-off between how complex additional measures would be to implement vs the damage that could be done if an attacker exploited you not doing them.

SSL - How and when to use it

I have a client that needs SSL to protect online donations, but I have limited experience with how/when to use SSL.
I understand that in purchasing a certificate that I am assigning that certificate to an entire domain (IP address really). Is there a way to isolate the encryption to only a single page of the website, or should I just go ahead and secure the entire site even though only one page needs it?
Unsure of best practice here. Please advise.
SSL incurs quite a bit of extra processing time. For low bandwidth sites, the extra processing required by SSL is not really noticeable. But for sites with heavy traffic like Facebook, Twitter and Flickr, the load caused by SSL is heavy enough that they would have to use dedicated SSL encoding/decoding hardware.
So basically yes, it makes sense to minimize the number of pages using SSL. That is why you often see banking sites only protect the actual account pages via https. The home/landing page is usually plain old http.
On the other hand, unless you really are a site like Twitter or Facebook or Gmail, worrying about this is a bit of a premature optimization. First do it simple if you can. Be aware of this issue and be aware of upgrade strategies when your site finally get heavy traffic.
My boss has a saying:
This is a happy problem to have. First solve the sad problem of
not having enough users then you'd be happy to have a problem that
requires you to refactor your architecture.
You don't encrypt a website with SSL. you encrypt the connection. Therefore if you have SSL enabled for the webserver simply adding https:// to the url will encrypt the connection and whatever page the url points to will be encrypted while in transit.
so
https://www.website.com/index.html is encrypted and http://www.website.com/index.html is NOT encrypted
I prefer for that to never happen so I always put my encrypted pages in a subdomain eg.
https://secure.website.com/index.html
SSL comes with a couple of gotcha's
1/ a basic SSL certificate will only be valid for a specific domain name so if the certificate for is www.website.com and someone follows a link for website.com a warning will be displayed. (see note below)
2/ SSL requires a dedicated IP (which you appear to have). that means you may have problems if you are on a shared platform. this is because in HTTP the host or domain name is part of the headers but the headers are encrypted so the server can't know where to route the request to. (see note below)
It sounds like you really need to employ the services of someone familiar with ecommerce and SSL to help you. navigating the minefield with limited knowledge and forum responses is not the safest thing to do. especially if financial transactions are taking place because there are other requirements that must be considered such as the legal requirements in storing and using financial information such as credit card numbers.
DC
Addendum:
For donations consider Paypal. They have a complete donation solution and more people will trust it than a roll your own solution.
EDIT 2016:
The world moves on and some of the advice above is not as true as it was when originally answered.
SSL no longer requires a dedicated IP address. SNI (Server name indication) resolves that and is almost universal now (IE8 on winXP does not support it and a few phones).
You will find most certificate vendors now include the main domain name as a SAN (subject alternative name) in a certificate. Which is to say they will provide a certificate for both www.website.moc and website.moc if you get a certificate for www.website.moc. Do not assume this, make sure your certification authority specifies it.
also, you mentioned that an SSL certificate protects an IP address. This is incorrect. An SSL certificate corresponds to a domain. Many schemes exist where several domains share a single IP address. If one of these shared domains has an SSL certificate, that certificate is only good for that domain, not the others.
Cookie security is the main thing that I'd point to for your approach.
A user that logs in on your secure login page gets a cookie for their session, right? That cookie's then being transmitted in plain text for someone watching the wire (Firesheep) to intercept and steal the session.
There is additional overhead in terms of negotiation time and CPU load from SSL, but it's rather minimal. If there's anything sensitive going on on your site, just use SSL everywhere.
The other answers are inaccurate in this regard: An SSL certificate binds to BOTH a dedicated IP address that is assigned to a static single domain name, unless you purchase a wild card SSL. Both the domain name and IP must match the certificate.

Can you get a client to trust a Server certificate without needing it to be a Registered Trusted Certificate?

I have a WCF Server Deployed through IIS. I want to Create a Certificate for it. I could do this by making the server a certificate server.
But then when the client connects to that server I want the client to automatically trust the certificate without having to register that the server as a "trusted authority".
Is this possible?
All this seems a lot of work to put username password protection on a WCF Service!
The short answer is no the client will need to add the server cert root as a trusted authority.
The slightly longer answer is that there is a workaround for needing to implement transport security in WCF when using message based authentication - this workaround is usually used when you want to rely upon another security mechanism that the WCF server is not aware of, like an ISA server providing SSL.
Have a look at Yaron Naveh's post. The essential idea is that you create a transport binding that pretends that it is secure.
With all that, you still need security (you don't want to send your creds in the clear) and so will still need a trust chain for your cert. So, it may not actually help you, but hopefully it gives you some options to consider.
Edit
Sorry if my answer was misleading. The server certificate root cert must by in the client trusted store. My additional detail was giving another option for providing the security (you can use an ISA server with a trusted cert to give your SSL connection)
In a similar situation to yours (needing secure communication when pushing client applicaitons to non technical customers) I have programatically installed the needed root certs.
Here is an SO post that details how to do that: How can I install a certificate into the local machine store programmatically using c#?
You can if you add this to your code but be aware of what you are doing!
System.Net.ServicePointManager.ServerCertificateValidationCallback += ( se, cert, chain, sslerror ) => { return true; };
Well if there would be such a way, it would be a security hole.
If a certificate is not linked to a trusted authority it is easily forged. So your choice is either to link it one way or another (directly or through a parent certificate you control), or configure your client so that it does not require the certificate i.e. using http rather than https.
Just keep in mind that it leaves your clients open to a variety of attacks
Edit
One of the possible attack scenarios is a man in the middle attack - a program inserts itself between your service and the client and channels the information though itself. This way the intruder has complete control over the information flow.
It can make copies of passwords or it can "adjust" the results in both directions any way it wants. The only thing which prevents this from happening is the certificates. But if they are not rooted, they can be forged.

WCF message security without certificate and windows auth

I have a WCF service and client which is going to be deployed to several companies (hundreds). Some companies will run the software in their network and some will run it over the Internet (WCF server at on office, WCF client at another).
We want to encrypt the communication between the WCF server and client. We don't have any need to authenticate the cient / subscriber using WCF security, because we have our own username/password log-in which the clients will use to log on the server.
We can't rely on Windows auth because some of the users will run it over the Internet, and the WCF server may not be on the same domain as the WCF client.
If we use "real" certificates*, companies running the software would have to purchase certificates from a CA and install it, and then configure our software to use it, but this is too complicated for most of them.
We could auto-create certificates during installation of the WCF server, but then we would have to automatically install it into a certificate store and somehow automatically grant IIS permissions to read the certificate. This is more complicated than we would like.
In short, we want a simple solution where the encryption is just based upon a shared secret, in our case the username / password the user is logging on with. I do understand that this won't give the best available encryption, but we're willing to trade some of the security to make the software easier to deploy.
Is this possible?
*With "real" certificates, I mean certificates purchased from a certificate authority, and not one I've created myself / self-signed.
If you want to encrypt the messages on the transport (which is a really good idea!), there has to be some shared knowledge between the sender (the client) and the server. This can be hardcoded, but that's really not a good idea at all - if that "common shared" knowledge is ever compromised, an attacker could decipher and read all your messages.
Also, since it's definitely not recommended practice, there's no support of any kind in WCF to simplify using a shared secret. You're on your own - you have to roll your own 100% of the way.
The only viable way to have a common shared secret exchanged in a safe way is to use a certificate. No way around this, sorry. The certificate doesn't even have to be used for user authentication or anything - but it establishes a shared secret between the caller and the service and thus allows the caller to encrypt the messages in such a way only the intended recipient can actually decrypt and use them.
So I really don't see any way you can get around having certificates on your servers - doesn't need to be on every client, but on every server where your service runs.
Marc
PS: if you really want to investigate the "hardcoded shared secret" approach, you'll need to think about this:
how do you store a shared secret safely on each and every single one of your clients?
how do you use information from that stored shared secret to encrypt your messages?
Typically, the approach would be two-fold:
exchange some form of a private/public key pair; the server generates a key pair and keeps the private key to itself and shares the public key with the client (e.g. over a WCF message, for instance)
using that private/public key pair, exchange a common shared secret, e.g. an "encryption key" that will symmetrically encrypt your messages (and since it's symmetrical, the server can use the same key to decrypt the messages)
setup infrastructure on your client (e.g. a WCF extension called a behavior) to inspect the message before it goes out and encrypt it with your shared secret
All in all, it's really not trivial - anything simpler than that is not worth being called "security" at all.
If you look at all that work you will have to do - wouldn't it be easier to just use the WCF built-in certificate mechanisms??
Decent security worth its salt is hard - so why not leverage what's available instead of doing all the work yourself, or worse: come up with a half-baked solution that's so easy to crack you could just as easily send everything in cleartext..... don't under estimate the complexity and amount of code needed to handle even the most basic security scenarios - WCF does this all for you - for free and in a reliable and safe manner - use it! You won't regret it!
Well, with WCF you could use Password credential at message level and SSL at transport level, which I think would be enough in your case.
See here.
For message security, your client provides some credentials and server provides some credentials. For this setup and with your scenario could you not use the client username and password with a Custom Username Validator, and a server certificate to provide the server credentials. This Application Scenario provides a fair chucnk of the configuration setup you would need to achieve this, except the aspNet membership sections, which you would have to replace with your custom validation config.
You would still need valid certificates on your servers (no certificates required on the clients), but I can't see any way around this.
Take a look at the following sample:
http://www.codeproject.com/KB/WCF/wcfcertificates.aspx
It uses certificates but without a certificate store - so no setup is necessary.
Hmm.. maybe something simple could be used. Move the encryption from software to hardware. VPN from each client network to your own and then you can do whatever you like for WCF transport. The line is not clear text and the problem is solved.
Of course this is easier said than done, but most network vendors provide a pretty easy VPN config and it maybe easier than trying to develop an installer for SSL certs and configure the client.
I hope it helps!

Self-signed SSL Cert or CA? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I would like to have the authentication and registration parts of my website encrypted (for obvious reason). This site is currently and older site which some friends and I started in middle school and still use today. I may or may not register it to be a Non-Profit Organization in the near future, but either way, a CA costs money and the organization doesn't have any and we are currently college kids.
Verisign is unreasonable and GoDaddy is $30/year. GoDaddy isn't too unreasonable, and I think their certs are accepted by most web browsers. The thing with GoDaddy is that I don't know why they have different SSL products (i.e.: why is it cheap to not verify me? does this have any implications on the cert and how the browser treats it if it just contains a domain name?)
Also, is there an issue with using my own cert? Could the login page be http, and have a line stating that I use a self-signed cert and here is it's fingerprint and then post the form to an https page? Safari's method isn't too bad or sound too scary. I'm afraid, however, that firefox 3's method will scare people away and give me a tonne of emails saying that my site is being hacked or something. I don't know how IE responds to self-signed certs. (There is also the issue of why pay for something I can create myself with no effort, but I'm not going to pose the philosophical part of it, this is a more practical question.)
In sum, do I give GoDaddy $30 a year or do I just tell people in a small paragraph what I'm doing and give the few people that will actually want my fingerprint it?
Edit: Some on a forum I was reading for more info mentioned that GoDaddy certs are only given if it's on a GoDaddy server, which this isn't. Two things: (1) is this true? and There are other CA's at about the same price, so the argument should still be the same.
There's a common misconception that self-signed certificates are inherently less secure than those sold by commercial CA's like GoDaddy and Verisign, and that you have to live with browser warnings/exceptions if you use them; this is incorrect.
If you securely distribute a self-signed certificate (or CA cert, as bobince suggested) and install it in the browsers that will use your site, it's just as secure as one that's purchased and is not vulnerable to man-in-the-middle attacks and cert forgery. Obviously this means that it's only feasible if only a few people need secure access to your site (e.g., internal apps, personal blogs, etc.).
In the interest of increasing awareness and encouraging fellow small-time bloggers like myself to protect themselves, I've written up a entry-level tutorial that explains the concepts behind certificates and how to safely create and use your own self-signed cert (complete with code samples and screenshots) here.
The SSL certificate solves two purposes: encryption of traffic (for RSA key exchange, at least) and verification of trust. As you know, you can encrypt traffic with (or without, if we're talking SSL 3.0 or TLS) any self-signed certificate. But trust is accomplished through a chain of certificates. I don't know you, but I do trust verisign (or at least Microsoft does, because they've been paid lots of money to get it installed in their operating systems by default), and since Verisign trusts you, then I trust you too. As a result, there's no scary warning when I go to such an SSL page in my Web browser because somebody that I trust has said you are who you are.
Generally, the more expensive the certificate, the more investigating that the issuing certificate authority does. So for the Extended Validation certificates, the requesters have to submit more documents to prove that they are who they say they are, and in return they get a bright, happy green bar in modern Web browsers (I think Safari doesn't do anything with it quite yet).
Finally, some companies go with the big boys like Verisign purely for the brand name alone; they know that their customers have at least heard of Verisign and so that for people shopping on their online store, their seal looks a little less sketch-ball than, say, GoDaddy's.
If the branding is not important to you or if your site is not prone to phishing attacks, then the cheapest SSL cert that you can buy that has its root installed in most Web browsers by default will be fine. Usually, the only verification done is that you must be able to reply to an e-mail sent to the DNS's administrative contact, thus "proving" that you "own" that domain name.
You can use those cheap-o certificates on non-GoDaddy servers, sure, but you'll probably have to install an intermediate certificate on the server first. This is a certificate that sits between your cheap-o $30 certificate and the GoDaddy "real deal" root certificate. Web browsers visiting your site will be like "hmm, looks like this was signed with an intermediate, you got that?" which requires may require an extra trip. But then it'll request the intermediate from your server, see that it chains up to a trusted root certificate that it knows about, and there is no problem.
But if you are not allowed to install the intermediate on your server (such as in a shared hosting scenario), then you are out of luck. This is why most people say that GoDaddy certs can't be used on non-GoDaddy servers. Not true, but true enough for many scenarios.
(At work we use a Comodo certificate for our online store, and a cheapo $30 GoDaddy cert to secure the internal connection to the database.)
Edited in italics to reflect erickson's insightful clarifications below. Learn something new every day!
Get a certificate from Let's Encrypt, a free CA this new decade, which is widely supported by browsers.
I haven't tried them yet, but StartCom was mentioned in a response to a similar question. Apparently you can get a one year certificate for free, and it's accepted by Firefox 3.
Even if you have to pay, I would suggest using a CA rather than self-signed certificates. Some people won't see your explanation, and a fake site could post their own fake certificate's fingerprint just like you propose. I doubt the average user knows what a certificate fingerprint is or how to check it.
Instead of creating a self-signed cert, create a self-signed CA, and sign your HTTPS certificate with that. It's easier to ask users to install a CA than a single server cert, and you can create new certs (eg. for subdomains, or to update expired certs) without users having to install a server cert again.
You can then decide later whether it's worth the $30 to switch from a cert signed by your own CA to the same cert signed by GoDaddy or whoever.
Either way, don't have an HTTP page with a form posted to HTTPS. The user cannot see that that's where it's going; they'd have to view source to check the form hasn't been hijacked to point elsewhere and no-one's going to do that. You would have to have an HTTP front page with the CA link and a separate link to the HTTPS login form.
Asking users to install a CA with a cert downloaded via plain HTTP is a bit naughty: if there were a man-in-the-middle they could replace your CA on the fly and hijack the ensuing HTTPS connections. The chances of this actually happening are quite low as it would have to be a targeted attack as opposed to plain old automated sniffing, but really you ought to be hosting the CA download link on some other HTTPS-protected service.
Customer acceptance is a matter only you can answer, knowing who your users are. Certainly the Firefox interface is excessively scary. If CAs like GoDaddy are down to $30 these days I would probably go for it; it used to be a lot, lot worse.
Assuming support on old and niche browsers is not much of an issue, just go for the cheapest CA available. You are supposed to be paying to have the CA properly verify who you are, but in practice that's not the way it works and it never has been, so paying extra for more thorough checks gets you almost nothing. Verisign's extortionate prices survive through corporate inertia alone.
CAs are there to receive money for doing nothing but owning a few hundred bits of private key. The identity-verifying stuff that was supposed to have been part of the CA mandate has been moved to EV certificates. Which are even more of a rip-off. Joy.
Self-signed certificates are insecure. Yes, really. "At least it's encrypted" isn't helping at all. From the article:
World-class encryption * zero authentication = zero security
If your website is for you and a few of your friends, then you might create your own CA and distribute your certificate to friends.
Otherwise either get a certificate from known CA (for free) or don't bother with self-signed certificates at all, because all you'd get is a false sense of security.
Why just encrypted traffic is not secure? You're always allowing the other end to decrypt your traffic (you have to, otherwise you'd be sending gibberish).
If you don't check who's on the other end, you're allowing anybody to decrypt your traffic. It doesn't make a difference if you send data to an attacker securely or not securely — the attacker gets the data anyway.
I'm not talking about checking whether e.g. paypal.com belongs to a trustworthy financial institution (that's a bigger problem). I'm talking about checking whether you're sending data to the paypal.com, or just to a van around the corner that sends a certificate saying "yeah, I'm like totally paypal.com and you have my word that it's true!"
I just finally broke down and switched my server from self-signed to a GoDaddy cert last night and it wasn't that big a deal, aside from their process not being as clear as it could be. $30/year is a reasonable cost and using the cert on a non-GoDaddy server is not an issue.
If you're going to be talking SSL to the public, get a real cert signed by a real CA. Even if you're working for minimum wage, you'll save more than $30/year worth of wasted time in dealing with user fears or distrust, and that's even before considering any possible lost revenue due to them being scared away from your site.
To answer your question about Internet Explorer, it will warn users about any site whose certificate is not signed by an IE-known (unfortunately called "trusted") CA. This includes for your own CA and for self-signed certificates. It will also make a warning if the domain in the certificate is not the one being accessed.
If this is a private site, you may not care so long as you are getting link-level encryption (and are you that fearful of someone sniffing your traffic?). If there is public access and you want SSL, then get a signed certificate from a recognized CA, as others have already advised.
If that van around the corner is capable of hijacking your internet connection already, you've got worse problems than self-signed certificates.
Banks should use client certificates for authentication. That would make it impossible for that van to do anything.... since it doesn't have the banks private key.
Self-signed certs are perfectly fine... assuming your internet connection hasn't been compromised. If your connection has been compromised... you're probably dogged anyway.