We're considering creating a program which sends a POST request to a server-side program for some processing. We'd like to consider some sort of verification to make sure the POST request isn't a random spammer attempting to overwhelm our system or something. I don't know too much about this stuff, but I was thinking the client might send a date-num and an "encrypted" date-num (not securely encrypted, just using some special algorithm). The server would then both encrypt the date-num AND decrypt the client-encrypted date-num. If either the encrypted date-nums or the decrypted date-nums didn't match, obviously it wasn't a request from our client, so the server will not act on the request.
As I said, I don't know that much about this. Am I going about it the right way? Is there a better way? If this is an ok way, whereabouts might I go looking for "encryption" algorithms? (most of the algorithms I find are for secure-encryption and can only be decrypted on the same machine. I don't care that much about security--I just am looking for verification).
Thanks a bunch for your help.
PS I'm not sure if this is a duplicate, because I didn't really know what to search. I couldn't find any other questions about this, but that doesn't mean anything.
EDIT:
To clarify, the server code should be as "drop-in" as possible -- e.g. if it can be done using straight PHP or ASP.NET rather than mucking around with server configurations, then that would be better. Same on the client end. Keep in mind this does not have to be secure, we're just attempting to keep spammers from POSTing random data a million times.
You could use ssl and client certificates and let the webserver handle it transparently. This way both the server and the client can be (more or less) sure about whom they are talking to.
What will your webserver be? IIS, Apache, ... ?
If it's an apache take a look at httpd 2.2 docs, Client Authentication and Access Control.
If it's an IIS see Enabling Client Certificates in IIS 6.0 (IIS 6.0)
Try using a cryptographic nonce.
On the page from which the POST is launched, a random number is generated and stored in the database with the requesting IP address and an expiry time (15-30 minutes?).
The same random number is stored as a POST variable.
On POST, in order for the processing to occur, there must be a successful lookup matching the nonce and IP address before the expiry time.
Combined with a honeypot captcha, it should do a good job of preventing bots from straining your system.
The usual approach for a problem like this is the inclusion of an HMAC. It allows integrity checking and sender authentication by the use of a secret key.
Related
Recently, We developed an application that we want it's users to pay for a monthly subscription in order to use it. So the first thing that came to our minds how to implement a secure way for our application to check for the User validity and those ideas came up
Using WebClient to enter to our website and Login using the user
provided credentials : However, this might be vulnerable to MITM
attack.
Using the first approach but using SSL certificate (to make sure
that we are connecting to our server and not the attackers') :
However, Fiddler can easily do a MITM attack and decrypt the SSL
communication, which will result in the same vulnerability as the
first approach.
Due to the internet's lack of documentation of what we need, we had to ask here for someone to explain how could we make sure that:
Our application only connects to our server and not any fake hosted
server (by the attacker).
The communication is secure. Not altered or edited some how in order to
grand unfair access to our application. (by sending a fake response
to the app or editing the original response before the application receives it).
Note: we totally understand that the attacker may just deobfuscate the application and do whatever he want to it. So we are planning to get a goodobfuscatorin order to at least make it harder for the attacker to do so.
You can use SSL Certificate Pinning.
Set the ServerCertificateValidationCallback to only accept your certificate's public key, or one of its signers. (this means you can never change certificates)
This will completely prevent SSL MITM (which works by using a different certificate and making the computer trust it).
Of course, it doesn't prevent attackers from cracking open your app and bypassing the check altogether, especially if you store local state.
i want to encrypt data in javascript and posted data want to decrypt in c# code.
Is there any idea or any code that can do this think with same algorithm.
Since JavaScript is executed in the end-user's webbrowser, your encryption code and algorithm is exposed. That means that the code is likely to be very easy to reverse and used against you.
A much better alternative to what you're asking for is using SSL to send the data securely over Internet. If you'd need, you could then encrypt the data once it reaches your server and before it is stored in your database or is passed on to another system.
See here for information about activating SSL on your website (if you're running IIS 7).
What do you think is the best way to connect two servers through a C# web service?
I don't want to use SSL, because it consumes to much server CPU and I don't want to add more load on the machines. And besides, it's slower.
Perhaps OAuth2, WS-Security or any custom service like sending tokens (nonce+timestamp) maybe to prevent resend attacks. Thanks for any suggestions.
My bet would still be on SSL. Use client certificates in order to verify incomming requests. It's in use on a large scale to protect sensitive information exchange and is especially well suited to protect against MITM.
The overhead of SSL will most likely not affect your CPU-usage noticably, have you measured? The handshake might be an issue if you're handling large amounts of small requests but if I understand you correctly you only have two servers and in that case that overhead (if my understanding of SSL/TLS is correct) will be amortized over the lifetime of the SSL session.
Short answer: It's unlikely that your CPU-usage will be adversly affected by adding SSL but you should always profile your scenario before jumping to conclusions.
More reading
HTTP vs HTTPS performance (StackOverflow)
How much overhead does SSL impose? (StackOverflow)
WS-Security has mutual authentication and message signing. This mode requires that the sending server has a certificate (public ky) of the receiver. The sender can then check that the response has not been tampered with by verifying the signature and can check that the signing certificate use to sign the response was the correct one for receiver.
My customers can ask questions directly in my (windows forms) app. The app talks to a web service which stores the messages in a db on my server. Problem: A competitor decides to spam my Web Service. What can I do to prevent this and is there a cryptographically save way of doing this?
The things I came up with until now are:
Hide the WSDL information so an attacker does not know the Web Service interface. Analysing my code or sniffing the traffic will reveal this information quickly however.
Create a token which I sign with a public key stored in my app. The Web Service can test this way if the message has been sent by my app. Well in theory at least. Again an attacker could rip the public key out of my app and create valid messages himself.
So I'm pretty stuck here. Is there any way to do this right and prevent dos attacks on my web service or is a web service the wrong way to do this in general?
Thank y'all.
You're right- putting a private key in your app won't slow anyone down much, no matter how hard you obfuscate it. Nor is obscurity on your WS metadata.
Probably the best way (if you can't do authentication) would be to throttle by IP (one comment per X interval). Just keep an in-memory dictionary of client IPs and the last time you saw a comment from there, and reject requests quickly if they happen too soon. That'd at least require a big DDOS to cause major problems. Reap the dictionary for old entries every hour or so to keep it from growing without bound.
#nitzmahone is right. Just to add to this: This is no different from someone spamming a web-based form. If you're really worried about this, you can do what web forms do (e.g. server sends token and CAPTCHA image, user decodes the CAPTCHA, client app sends token, decoded CAPTCHA and the actual request).
Just like in web apps, you can turn this functionality on only if traffic from some IP exceeds a certain threshold.
Scenario:
A publically available Web Service that I have full control over.
But I only want this specific desktop application (my published application) to have access to the Web Service.
I could store a secret password in the desktop client, but that would be easy to crack.
Is there any known implementation that enforces this?
PKI, assymmetric keys?
If the public will have access to copies of this Desktop App, any good reverser will be able to crack it and "imitate" its transactions with the server. It doens't matter how secure is your cryptography, everything you app needs to encrypt/decrypt data is included in the binaries, so the cracker only needs to dig it out of it.
The objective of cryptography is to protect data while it is being transfered, from "middle-man" hackers, but if you have access to anyone of the peers, you can easily crack it.
Your server must never trust what comes from the client side.
[edit resuming]
Despite you cannot 100% guarantee a supposed client to your server is or isn't your App or some "emulator" made by thirdies, you can complicate things to them. Its a common practice in game anti-cheats to sometimes, randomly, make the client App a trick question like "whats the hash of your main.exe from offset A to offset B?" or "from now on packet type 0x07 swaps with packet type 0x5f". Once a fake is detected, server enter in a "silly mode", act malfunctional, and blacklist their IP/account to this mode for several hours so they cannot have sure of what their program is doing wrong.
If you detect someone is building an emulator, make them start all over again: jumble the packet type tables, cryptography tables, change some packet formats and force your clients to update. You won't see crackers bothering you for a while... LOL
WS-Security provides for X509 encryption.
Part of that implementation includes the possibility of only giving specific clients the generated public key. That way, only your selected clients can connect to the service.
The easiest way is message security using client and server certificates. The best way is to import the client certs in your server machines and hard code the client cert thumbprint in the app.config file. The other way is negotiation of certs which I haven't tried before.
If you are using IIS to host the service then client certificates using SSL is another option.
MSDN link on WCF Security.