Make an HTTP request non-replayable - security

I have an application that runs on for example Google TV or Apple TV, which sends HTTP requests to a service of mine.
Now if someone listens in on this request, they can replay it and in that way execute a Denial of Service (DOS) attack our service.
Is there any way to make each request unique, so it cannot be replayed?
I thought of sending the time encrypted in the request and check the difference between the server time and the time the request was sent, but I'm getting too big time differences to compare.
Does anyone have a better idea?

You are in a good situation as you have control both on the server side and the client side (your application is talking). Include into your message
The current time in milliseconds plus + random number
The combined hash produced by these values plus (as a the third input) some key only your application knows. Use some good one way hashing algorithm.
Only the code who knows the mentioned key will be able to compute a correct hash. The used request records (hash and time stamp) can be stored for some expiration time that can be long. Very old request records can be easily expired as they contain the time stamp.
The positive feature of the proposed approach is it does not require to connect in advance in order to receive a token, needs no authentication, needs no registration and can use the open protocol. Using token just by itself does not help much against DoS as an attacker quickly writes a script to connect and obtain the token in advance as well.

Related

How to secure my API against "fictitious" payload?

I have developed an app for Android/iOS which calculates a value based on the users input. If an event occurs, this calculated value will be sent to my Backend as normal HTTPS payload. My question is now, how can I make sure, that this value is really only calculated by the source code of my app? Is there a way to handle such a problem?
To make it clear: I want to avoid, that somebody is rooting his phone, extract the Auth-Token from the private storage of my app and sends a valid HTTPS-Payload to my Backend with fictitious payload, manually or by manipulating the source code.
From the view of the backend, it's difficult to evaluate the payload based on its values if it is valid or not.
Any suggestions appreciated!
----------EDIT-----------
For the sake of completeness: apart from the answers here, the following are also very interesting:
Where to keep static information securely in Android app?
How to secure an API REST for mobile app? (if sniffing requests gives you the "key")
You can’t trust data coming from the client. Period.
You should consider moving the calculation logic to the server and just sending the raw values needed to perform the calculation. You can easily get sub-second response times sending the data to the server, so the user won’t notice a lag.
If you need offline connectivity, then you’ll need to duplicate the business logic on both the client and the server.
Short of doing everything on the backend, you can't very easily.
I'd recommend some reading around CSRF (Plenty of articles floating around) as that's at least a good mitigation against bots outside of your app domain hitting your backend. The upshot is that your application requests a unique, random, identifier from your backend (which ideally would be tied to the user's auth token) before submitting any data. This data is then submitted with your app's data to perform the calculation on the backend. The backend would then check this against the random identifier it sent for that user earlier and if it doesn't match, then reject it with a 400 (Bad Request), or 404 if you're paranoid about information leakage.

HTTPS or other clever authentication methods

A little background: I am going to be constructing a webserver, likely the most up to date version of apache when I get around to it. It is going to be updated with sensory information from a makeshift security system I have.
As a counterpart, I am designing an app to go along with it, that will automatically contact the webserver and pull the sensory information about once every 1.5 minutes.
I want to have an authentication method so that the average Bob can't see this information, mostly due to the fact that there will be some command and control as part of the server as well.
The question: I feel like a simple username and password is the wrong way to go about this since it isn't dynamic and theoretically seeing the same credentials sent that frequent could be dangerous, so is there any other authentication method that could mitigate this?
The question pt. 2: Obviously I want an encrypted channel, will https stumble over itself if it tries to renegotiate every minute and a half?
I haven't begun this project yet much less chosen any language to write it in, meaning I am super open minded to suggestions, any help is greatly appreciated.
The question: I feel like a simple username and password is the wrong
way to go about this since it isn't dynamic and theoretically seeing
the same credentials sent that frequent could be dangerous, so is
there any other authentication method that could mitigate this?
You could use Google Sign-In to allow log on via a Google account.
Or you could implement two factor authentication with say Google Authenticator or via SMS to prove that the user logging in has more than one factor of authentication. These factors could be:
Something you know (e.g. password)
Something you have (e.g. phone that provides a One Time Password)
Edit: Having re-read your question - yes you are fine to authenticate with username and password (over HTTPS), however you should then store a session identifier client-side and simply send this in future rather than the username/password each time. This is more secure as it can be stored safely client-side, and if exposed the identifier can be easily revoked.
The question pt. 2: Obviously I want an encrypted channel, will https
stumble over itself if it tries to renegotiate every minute and a half?
Nope, this is what it is designed for. Browsers will keep open an HTTPS connection for a length of time. Additionally, they will use session resumption rather than executing a full HTTPS handshake in the case that a new connection needs to be established. Session resumption is much quicker than establishing a completely new session. See this article on the CloudFlare blog for more info.

How to do server-side validation of a client application?

I've got a Windows client (desktop) application that when run for the first time will hit a server and request a client ID. A short time later that client will call back up to the server with additional requests. The server can hand out client IDs all day long, but it's important that the server be able to know that any future requests are coming from a valid client.
This means verifying that it's the client application making the request, and not someone/something else pretending to be the client application. Ideally it would also involve verifying that the client ID of a client application hasn't changed.
I thought about including a hash of the salted client ID with future requests, but it doesn't seem like it would be terribly hard for a determined person to disassemble the client enough to figure out the salt value.
Thanks in advance for any solutions, tips or pointers!
Can't be done sensibly without a heavy dose of cryptography. As long as the other end has complete control, there just is no way they can't fake the answers. Something vaguely similar is what Kerberos does, the protocols are quite involved. Ross Anderson's "Security Engineering" would be my first stop to take a look at how to do it.

Security sign from Phonegap App to external domain

I'm making an App with PhoneGap. I need to send some dates to an external domain that helps me to put it in a MySQL database.
I would like to create a sign that I send with my request to server, to check that these dates came from my own App. I don't want a third party to be able to make a request from outside to my external domain.
Seems to me that you need a OTP system (one time password). I've never done something like this before, but i can give you some hints on how it works.
It works with pseudo-random number generators(PRNG) that are synchronized in the client and the server. To do this, you pass a secret seed to both your PRNG (client and server side) which will generate, after a pre-determined time lapse, a random number, which will be your password during that time lapse (before the new random number is created). Since both PRNG have the same seeds and algorithms, they both generate the same random number, allowing to match the password. I hope this helps.

Secure Token URL - How secure is it? Proxy authentication as alternative?

I know it as secure-token URL, maby there is another name out there. But I think you all know it.
Its a teqniuque mostly applied if you want to restrict content delivery to a certain client, that you have handed a specific url in advance.
You take a secret token, concatenate it with the resource you want to protect, has it and when the client requests the this URL on one of your server, the hash is re-constructed from the information gathered from the request and the hash is compared. If its the same, the content is delivered, else the user gets redirected to your webseite or something else.
You can also put a timestamp in the has to put a time to live on the url, or include the users ip adress to restrict the delivere to his connection.
This teqnique is used by Amazon (S3 and Cloudfront),Level 3 CDN, Rapidshare and many others. Its also a basic part of http digest authentication, altough there is it taken a step further with link invalidation and other stuff.
Here is a link to the Amazon docs if you want to know more.
Now my concerns with this method is that if one person cracks one token of your links, the attacker gets your token plain-text and can sign any URL in your name himself.
Or worse, in the case of amazon, access your services on an administrative scope.
Granted, the string hashed here is usually pretty long. And you can include a lot of stuff or even force the data to have a minimum length by adding some unnecessary data to the request. Maby some pseudo variable in the URL that is not used, and fill it up with random data.
Therefore brute force attacks to crack the sha1/md5 or whatever you use hash are pretty hard. But protocol is open, so you only have to fill in the gap where the secret token is and fill up the rest with the data known from the requst. AND today hardware is awesome and can calculate md5s at a rate of multiple tens of megabytes per second. This sort of attack can be distributed to a computing cloud and you are not limited to something like "10 tries per minute by a login server or so" which makes hashing approaches usually quite secure. And now with amazon EC2 you can even rent the hardware for short time (beat them with their own weapons haha!)
So what do you think? Do my concerns have a basis or am I paranoic?
However,
I am currently designing an object storage cloud for special needs (integrated media trans coding and special delivery methods like streaming and so on).
Now level3 introduced an alternative approach to secure token urls. Its currently beta and only open to clients who specifically request it. They call it "Proxy authentication".
What happens is that the content-delivery server makes a HEAD request to a server specified in your (the client's) settings and mimics the users request. So the same GET path and IP Address (as x_forwarder) is passed. You respond with a HTTP status code that tells the server to go a head with the content delivery or not.
You also can introduce some secure-token process into this and you can also put more restrictions on it. Like let a URL only be requested 10 times or so.
It obviously comes with a lot of overhead because additional request and calculations take place, but I think its reasonable and I don't see any caveats with it. Do you?
You could basically reformulate your question to: How long a secret token is needed to be safe.
To answer this consider the number of possible characters (alphanumeric + uppercase is is already 62 options per character). Secondly ensure that the secret token is random, and not in a dictionary or something. Then for instance if you would take a secret token of 10 characters long, it would take 62^10 (= 839.299.365.868.340.224 )attempts to bruteforce (worstcase; average case would be half of that of course). I wouldn't really be scared of that, but if you are, you could always ensure that the secret token is at least 100 chars long, in which case it takes 62^100 attempts to bruteforce (which is a number of three lines in my terminal).
In conclusion: just take a token big enough, and it should suffice.
Of course proxy authentication does offer your clients extra control, since they can way more directly control who can look and not, and this would for instance defeat emailsniffing as well. But I don't think the bruteforcing needs to be a concern given a long enough token.
It's called MAC as far as I understand.
I don't understand what's wrong with hashes. Simple calculations show that a SHA-1 hash, 160 bits, gives us very good protection. E.g. if you have a super-duper cloud which does 1 billion billions attempts per second, you need ~3000 billions billions years to brute force it.
You have many ways to secure a token :
Block IP after X failed token decoding
Add a timestamp in your token (hashed or crypted) to revoke the token after X days or X hours
My favorite : use a fast database system such as Memcached or better : Redis to stokre your tokens
Like Facebook : generate a token with timestamp, IP etc... and crypt it !

Resources