JSON: Reject server requests from third parties - java

i intend to use JSON to implement a client server communication. My goal is for a Java-server to receive data via HTTP-Post from an Iphone-app.
I'm concerned about the fact of how I can be sure, that the data the Java-server receives only come from the Iphone-app? It may be possible that somebody else is catching the Java-Server URL and send rigged data?
Do I have a chance to recognize that? SSL encrypts transferred data only, but doesn’t solve the problem, i think.
kind regards
stormsam

You could send a token that is hardcoded into your application. Everything that comes without this valid toke should be rejected. Or you can use .htaccess and specify a user and password within your app.

You could use public key encryption, with users having their own keys and you keeping track of who are the legitimate users. This is the most reliable scheme I can think of. That, or giving each user a username and password. However, it's probably a lot more trouble than it's worth, and still doesn't protect against users that have registered with you but are still malicious.
Embedding a token in your application and then sending it with requests, as Cyprian suggests, is probably the easiest scheme and would probably work pretty well, but might be relatively easy to reverse engineer.
A somewhat better solution might be to program into your app a function that transforms any given input into an output; then, your server responds to a request by giving the app a piece of data to transform, and checks the result. A client that passes the test gets a session token which allows it to proceed. This does require an extra round-trip for authentication, though. And it's still not immune to being reverse engineered, since all the information needed to do so is stored in the app that's present on the user's machine.

Assuming you can reasonably protect your iOS app from being dissambled, you could use "signed requests" like the Facebook API (and probably others):
You'll need a shared secret on both client and server (e.g. a random string/byte array). The iOS app then hashes all request parameters plus the shared secret and appends the hash as additional request parameter, e.g. myserver.com/ws?item=123&cat=456 becomes myserver.com/ws?item=123&cat=456&hash=1ab53c7845f7a. Upon receiving a request, the server then recomputes the hash from the regular parameters and the shared secret and compares it to the value sig parameter. If both are equal, the request is considered valid (assuming integrity of your iOS app).
An advantage of this method is that it doesn't require additional round trips to fetch any one-time/CSRF-prevention tokens and does not require encrypting requests and responses (as long as you only care about the integrity of requests, not confidentiality).

You might have to take a look at this. It may give you some directions.

Related

Encrypt A String With JavaScript And Decrypt It From Server Side (Java)

I need to encrypt a string at client side and send it to the server.
Once there I need to decrypt it.
Is the Using Password-Based Encryption the best solution?
I need it because I have a voting mechanism, where I send ajax posts to vote an entry.
This mechanism use the Facebook id from the current user. My goal is to encrypt the FB id from client side to avoid that they hack it by sending requests with differents ids.
If a second post with the same id is sent I will block the vote.
Once the id is decrypted I will check if it is a real FB user using the graph.
Javascript encryption won't help here. Any good detective/hacker can see how it's all done on the client and see what the data was before it was encrypted and see how it's encrypted.
The only way to prevent a user from voting multiple times is to have the vote tied to an account or token that you can both verify on your server and tie to a particular user that isn't easy for the user to make lots of different accounts. In general, you probably can't stop this entirely, but you can make it enough trouble that most won't do it by making it require enough steps (including some sort of captcha so it can't be automated).
SSL will protect client/server communications, but won't do anything to stop the client from doing things you don't want them to do.
“Encryption” does not make any sense here as you have already been told (because the value that would be encrypted client-side could be manipulated before you encrypt it), and SSL does of course not solve this problem either.
Send the access token of the user to the server instead. And then either make a request for user data with it (/me), or debug it – then you will know that the request is genuine, because a user can not “fake” an access token for another user.
Considering that there is no authentication an HTTP fingerprint can be used to check if requests with different userId come from the same user.
Fingerprint will be create from HTTP request data like:
-user agent
-language
-IP
-charset
and other data present in the http request.

Is a Servlet "secure" if it checks for a given session attribute in the request handler?

Assume I have a single servlet in a web app, and all users need to be logged in before they can do anything. So in the get and post methods there is an if block to test if the user is logged by trying to extract a session attribute in to process request, and else to redirect to login page if not logged in.
Given this scenario, is there a way an intruder can manipulate the system to gain entry without knowing the password? Assume the password is hard-coded into the servlet. If yes, where would he start?
I would look at http://docs.oracle.com/javaee/5/tutorial/doc/bncbe.html#bncbj and the section linked from that section about specifying authentication mechanisms.
See also (on Stackoverflow) Looking for a simple, secure session design with servlets and JSP and How do servlets work? Instantiation, sessions, shared variables and multithreading
In short, you don't need to do much yourself about checking for a session attribute if you use the mechanisms described on those pages. Your login form can be used in the 'form-login' configuration requiring authentication.
The key of security is around your comment extract a session attribute -- how are you doing this? Are they sending you a query string param? Are they sending you credentials in the method headers?
To #Hogan's point, unless this is over HTTPS the answer is: "No, it is not secure. A man-in-the-middle (MITM) can get the password from your submission and simply re-use it to mask its own nefarious requests".
If the communication IS done over HTTPS, then you should be fine. Having a single hard-coded password is fine, but consider the case where the password gets compromised; now every single client/user/etc. has to change their code.
A better design is to issue clients a key they can send along with their requests that you can use to identify who they are and if a key gets compromise, re-issue a new one to that user/client/etc.
This assumes traffic is over HTTPS
If traffic is not, a lot of this breaks down and you need to look at things like HMAC's. I wrote this article on designing secure APIs -- it should give you a good introduction to how all this nightmare of security works.
If your eyes are rolling into the back of your head and you are thinking "My god, I just wanted a YES/NO", then my recommendation is:
Require all traffic to be over HTTPS
Issue individual passwords to each client so if one gets compromised, every single one isn't compromised.
That should get you pretty far down the road.
Hope that help. This topic is super hairy and I know you didn't want a history lesson and just want to solve this question and move forward. Hope I gave you enough to do that.

Rest token authentication with HTTP header

This is an existing system with a login screen, now I expose some services as REST service. I build an authentication-token login system for this Rest(jersey) service. User sends username-password then server returns a token calculated as;
sha1(username+password+currenttime(or any random number))
User will use this token to login the app for further requests. And server keeps a copy of the token in the database with a time stamp and user id, and logins that user if timestamp is valid.
Considering HTTPS will be used, a few questions;
Does everything looks ok in my design? (generation of hash and the way I save in DB) Looks to me the weakest point is I need to send plain username and password over POST request, but since it is HTTPS I guess it will not be a problem.
another thing, for the first request, since it is an existing system I dont have the user passwords in my DB but keep a salted hashed version of them. Which I guess not safe to give all the clients this salted algorithm to send me a hash of their passwords so I compare hashs but not the passwords. does this make sense=
1/2- I'd suggest POSTing the username/password to the server, which can then return the token in the body. Makes most sense to me: you're not actually storing much on the server, so PUT would be wrong, and a query parameter doesn't make sense at all. Headers are supposed to be somewhat consistent across requests, so they don't make sense either. When actually communicating using the token, feel free to use a query parameter or header. Doesn't really matter.
3- I'd pick a slightly longer hashing algorithm (sha256?)
I would typically pass the token in an HTTP header.
Whether you use POST or PUT shouldn't matter.
Something else I would suggest to help prevent replay type attacks would be to include a nonce (ever increasing value) with each POST request. The server would then track the last used nonce and prevent any requests that use a previously used nonce from executing.

Protecting Sections of Source Code [duplicate]

This question already has answers here:
Handling passwords used for auth in source code
(7 answers)
Closed 7 years ago.
I'm writing a Java class that connects to a server and reads messages in a given queue.
I would like to protect the username and password, which, right now, appear as plain text in the source code.
What I'm wondering, is, what is a good way to do this? If I encrypt the username and password in a text file, won't I need to store the key, in plain text, in any source code that accesses this file? And then anyone else who decides to use my class will be able to gain access to these fields.
There is no prompt where someone can enter the key, either, as this class will autonomously be used by the system.
EDIT: this will become a java lib file. But those can easily be decompiled and thus are basically the original class files anyway, right? And the people this is being protected from are fellow developers of other systems who will gain access to this lib file.
My End Goal: is to have the username and password strings not appear as plain text anywhere, and for them to be as difficult as possible to crack.
It is not possible to do this. Even if you encrypt the login/password and store it somewhere (may it be your class or an external file) you'd still need to save the encryption key somewhere in plain text. This is actually just marginally better than saving username/password in plain text, in fact I would avoid doing so as it creates a false sense of security.
So I'd suggest that your class takes username/password as a parameter and that the system which is using your class will have to care about protecting the credentials. It could do so by asking an end user to enter the credentials or store them into an external file which is only readable to the operating system user that your process is running as.
Edit: You might also think about using mechanisms such as OAuth which use tokens instead of passwords. Tokens have a limited life time and are tied to a certain purpose so they pose a good alternative to access credentials. So your end users could get an access token with their,say, Windows credentials, which is then used inside your class to call the protected service.
This is a classic authentication issue, except that here, Eve can wear Bob's skin like a suit. Is that stretching the metaphor? I'm not sure.
The short answer is that there is no true answer, because what you want is something that basically violates information theory, in that anything transmittable is copyable and thus anything accessible can be viewed as no-longer-unique. Even if you had a magic box, they could just yank out the magic box with some serious JVM hacking.
The long answer is that there are a few solutions that are almost pretty okay, by making it really quite darn hard. I suggest you read the article linked, acquaint yourself with the ideas behind SRP, the vulnerabilities the spec entails, and try to figure out how to get the right to use and implement it. The problem is still there though. It's that you want a system that ensures Bob can never become a flesh-chariot, or fall to the dark side.
Fundamentally, you're breaking the tenth law. I agree with Kork, there's no solution that really does what you want, because you're trying to solve a social problem with a technical feat, one that is quite nearly provably impossible.
There are a few ways of handling this problem. The challenge as you've noted is associating an account with this automated process. So, here are some of the possibilities (from least secure to more secure):
Encrypt the username and password with a calculated key.
The calculated key is based on something both the client and the server can infer (like machine name and IP address)
Associate an authentication token with the client (OAuth style).
The token is negotiated by a one time user interaction to set up the client
The negotiated token is used for all future requests
The negotiated token is only valid for that client on that machine using that user account (server uses socket info to determine the match)
Use multiple forms of authentication
OAuth style token
Calculated token based on time + secondary id (requires clients and servers to be synched to the same time server)
It is important to note that your security measures should be more restrictive than it is worth to crack. In short, if all the potential bad guy is only going to be able to get your food preferences of the day you might not need to be as vigilent as protecting something more high profile like a bank account. User names and paswords are not the only means of authentication.
It's not clear which code has to know the user name & password. Are these credentials just for the queue being read? If so, only the server code would need to know them. In that case, you could store them in a server file whose permissions allow only the server code to read them. The file permissions would then be enforced by the server operating system, which presuambly is much better at security than most programmers will ever be.
I know this question is long since abandoned, but I want to point out that of course you can do this by requiring typed credentials at runtime but only storing a hash of the password. Of course, it needs to be a really good hash. Use a standard one, don't make up your own. The whole point of a hash is that even if you plain text the hashed result, no one else will be able to come up with a string that yields that hash, even if they know how the hash is computed.
Of course users can try a brute force attack, and since they know the result they want they can run it fast, so you need to use a highly secure password.

How would you implement a secure static login credentials system in Java?

We recently had a security audit and it exposed several weaknesses in the systems that are in place here. One of the tasks that resulted from it is that we need to update our partner credentials system make it more secure.
The "old" way of doing things was to generate a (bad) password, give it to the partner with an ID and then they would send that ID and a Base 64 encoded copy of that password in with all of their XML requests over https. We then decode them and validate them.
These passwords won't change (because then our partners would have to make coding/config changes to change them and coordinating password expirations with hundreds of partners for multiple environments would be a nightmare) and they don't have to be entered by a human or human readable. I am open to changing this if there is a better but still relatively simple implementation for our partners.
Basically it comes down to two things: I need a more secure Java password generation system and to ensure that they are transmitted in a secure way.
I've found a few hand-rolled password generators but nothing that really stood out as a standard way to do this (maybe for good reason). There may also be a more secure way to transmit them than simple Base 64 encoding over https.
What would you do for the password generator and do you think that the transmission method in place is secure enough for it?
Edit: The XML comes in a SOAP message and the credentials are in the header not in the XML itself. Also, since the passwords are a one-off operation for each partner when we set them up we're not too worried about efficiency of the generator.
Password Generation
As far as encoding a password for transmission, the only encoding that will truly add security is encryption. Using Base-64 or hexadecimal isn't for security, but just to be able to include it in a text format like XML.
Entropy is used to measure password quality. So, choosing each bit with a random "coin-flip" will give you the best quality password. You'd want passwords to be as strong as other cryptographic keys, so I'd recommend a minimum of 128 bits of entropy.
There are two easy methods, depending on how you want to encode the password as text (which really doesn't matter from a security standpoint).
For Base-64, use something like this:
SecureRandom rnd = new SecureRandom();
/* Byte array length is multiple of LCM(log2(64), 8) / 8 = 3. */
byte[] password = new byte[18];
rnd.nextBytes(password);
String encoded = Base64.encode(password);
The following doesn't require you to come up with a Base-64 encoder. The resulting encoding is not as compact (26 characters instead of 24) and the password doesn't have as much entropy. (But 130 bits is already a lot, comparable to a password of at least 30 characters chosen by a human.)
SecureRandom rnd = new SecureRandom();
/* Bit length is multiple of log2(32) = 5. */
String encoded = new BigInteger(130, rnd).toString(32);
Creating new SecureRandom objects is computationally expensive, so if you are going to generate passwords frequently, you may want to create one instance and keep it around.
A Better Approach
Embedding the password in the XML itself seems like a mistake.
First of all, it seems like you would want to authenticate a sender before processing any documents they send you. Suppose I hate your guts, and start sending you giant XML files to execute a denial of service attack. Do you want to have to parse the XML only to find out that I'm not a legitimate partner? Wouldn't it be better if the servlet just rejected requests from unauthenticated users up front?
Second, the passwords of your legitimate partners were protected during transmission by HTTPS, but now they are likely stored "in the clear" on your system somewhere. That's bad security.
A better approach would be to authenticate partners when they send you a document with credentials in the HTTP request headers. If you only allow HTTPS, you can take the password out of the document completely and put it into an HTTP "Basic" authentication header instead. It's secured by SSL during transmission, and not stored on your system in the clear (you only store a one-way hash for authentication purposes).
HTTP Basic authentication is simple, widely supported, and will be much easier for you and your partners to implement than SSL client certificates.
Protecting Document Content
If the content of the documents themselves is sensitive, they really should be encrypted by the sender, and stored by you in their encrypted form. The best way to do this is with public key cryptography, but that would be a subject for another question.
I'm unclear why transmitting the passwords over SSL -- via HTTPS -- is being considered "insecure" by your audit team. So when you ask for two things, it seems the second -- ensuring that the passwords are being transmitted in a secure way -- is already being handled just fine.
As for the first, we'd have to know what about the audit exposed your passwords as insecure...
I'd abandon the whole password approach and start using client certificates allowing a 2 side authenticated SSL connection.
You have to generate and sign individual certificates for each client. In the SSL handshake, you request the client's certificate and verify it. If it fails, the connection ends with a 401 status code.
Certificates can be revoked at any time be your side, allowing easily disconnecting former customers.
Since all this happens in the handshake prior to the communication, is is not possible to flood your server with data.

Categories

Resources