We are currently working on a very simple Webapp, and we would like to "obfuscate" ( what would be the right term? ) or encode somehow the request parameter, so we can reduce the chance an idle user from sending arbitrarily data.
For instance, the url looks like /webapp?user=Oscar&count=3
We would like to have somthing like: /webapp?data=EDZhjgzzkjhGZKJHGZIUYZT and have that value decoded in the server with the real request info.
Before going into implementing something like this ourselves ( and probably doing it wrong ) I would like to know if there is something to do this already?
We have Java on the server and JavaScript on the client.
No, don't do this. If you can build something in your client code to obfuscate the data being transmitted back to the server, then so can a willful hacker. You simply can't trust data being sent to your server, no matter what your official client does. Stick to escaping client data and validating it against a whitelist on the server side. Use SSL, and if you can, put your request parameters in a POST instead of GET.
Expansion edit
Your confusion stems from the goal to block users from tampering with request data, with the need to implementing standard security measures. Standard security measures for web applications involve using a combination of authentication, privilege and session management, audit trails, data validation, and secure communication channels.
Using SSL doesn't prevent the client from tampering with the data, but it does prevent middle-men from seeing or tampering with it. It also instructs well-behaved browsers not to cache sensitive data in the URL history.
It seems you have some sort of simple web application that has no authentication, and passes around request parameters that control it right in the GET, and thus some non-technically savvy people could probably figure out that user=WorkerBee can simply be changed to user=Boss in their browser bar, and thus they can access data they shouldn't see, or do things they shouldn't do. Your desire (or your customer's desire) to obfuscate those parameters is naïve, as it is only going to foil the least-technically savvy person. It is a half-baked measure and the reason you haven't found an existing solution is that it isn't a good approach. You're better off spending time implementing a decent authentication system with an audit trail for good measure (and if this is indeed what you do, mark Gary's answer as correct).
So, to wrap it up:
Security by obfuscation isn't
security at all.
You can't trust
user data, even if it is obscured.
Validate your data.
Using secure communication channels (SSL)
helps block other related threats.
You
should abandon your approach and do
the right thing. The right thing, in
your case, probably means adding an
authentication mechanism with a
privilege system to prevent users
from accessing things they aren't
privileged enough to see - including
things they might try to access by
tampering with GET parameters. Gary
R's answer, as well as Dave and Will's comment hit
this one on the head.
If your goal is to "reduce the chance an idle user from sending arbitrarily data," there's another simpler approach I would try. Make a private encryption key and store it in your application server side. Whenever your application generates a url, create a hash of the url using your private encryption key and put that hash in the query string. Whenever a user requests a page with parameters in the url, recompute the hash and see if it matches. This will give you some certainty that your application computed the url. It will leave your query string parameters readable though. In pseudo-code,
SALT = "so9dnfi3i21nwpsodjf";
function computeUrl(url) {
return url + "&hash=" + md5(url + SALT );
}
function checkUrl(url) {
hash = /&hash=(.+)/.match(url);
oldUrl = url.strip(/&hash=.+/);
return md5(oldUrl + SALT ) == hash;
}
If you're trying to restrict access to data then use some kind of login mechanism with a cookie providing a Single Sign On authentication key. If the client sends the cookie with the key then they can manipulate the data in accordance with the authorities associated with their account (admin, public user etc). Just look at Spring Security, CAS etc for easy to use implementations of this in Java. The tokens provided in the cookie are usually encrypted with the private key of the issuing server and are typically tamper proof.
Alternatively, if you want your public user (unauthenticated) to be able to post some data to your site, then all bets are off. You must validate on the server side. This means restricting access to certain URIs and making sure that all input is cleaned.
The golden rule here is disallow everything, except stuff you know is safe.
If the goal it to prevent "static" URLs from being manipulated, then you can simply encrypt the parameters, or sign them. It's likely "safe enough" to tack on an MD5 of the URL parameters, along with some salt. The salt can be a random string stored in the session, say.
Then you can just:
http://example.com/service?x=123&y=Bob&sig=ABCD1324
This technique exposes the data (i.e. they can "see" that xyz=123), but they can not change the data.
There's is an advantage of "encryption" (and I use that term loosely). This is where you encrypt the entire parameter section of the URL.
Here you can do something like:
http://example.com/service?data=ABC1235ABC
The nice thing about using encryption is two fold.
One it protects the data (they user can never see that xyz=123, for example).
The other feature tho is that it's extensible:
http://example.com/service?data=ABC1235ABC&newparm=123&otherparm=abc
Here, you can decode the original payload, and do a (safe) merge with the new data.
So, requests can ADD data to the request, just not change EXISTING data.
You can do the same via the signing technique, you would just need consolidate the entire request in to a single "blob", and that blob is implicitly signed. That's "effectively" encrypted, just a weak encryption.
Obviously you don't want to do ANY of this on the client. There's no point. If you can do it, "they" can do it and you can't tell the difference, so you may as well not do it at all -- unless you want to "encrypt" data over a normal HTTP port (vs TLS, but then folks will wisely wonder "why bother").
For Java, all this work goes in a Filter, that's the way I did it. The back end is isolated from this.
If you wish, you can make the back end completely isolated from this with an outbound filter that handles the URL encryption/signing on the way out.
That's also what I did.
The down side is that it's very involved to get it right and performant. You need a light weight HTML parser to pull out the URLs (I wrote a streaming parser to do it on the fly so it didn't copy the entire page in to RAM).
The bright side is all of the content side "just works", as they don't know anything about it.
There's also some special handling when dealing with Javascript (as your filter won't easily "know" where there's a URL to encrypt). I resolved this by requiring urls to be signed to be specific "var signedURL='....'", so I can find those easily in the output. Not as crushing a burden on designers as you might think.
The other bright side of the filter is that you can disable it. If you have some "odd behavior" happening, simply turn it off. If the behavior continues, you've found a bug related to encryption. It also let developers work in plain text and leave the encryption for integration testing.
Pain to do, but it's nice overall in the end.
You can encode data using base64 or something similar. I would encode the arguments inself in JSON to serialize them.
Something like jCryption ?
http://www.jcryption.org/examples/
Related
Here is the premise, I am not allowed to use JavaScript or Cookies for this website.
However I do not wish to ask the user for their password for every essential task that requires their password for at least 15-30 minutes.
I also don't like the idea of saving their password to a temp file in case the program dies and is not able to erase it as scheduled.
So my plan is upon first contact, assign the user a unique randomly generated secure id/hash and attach it inside their generated HTML. And server side match their password to their id inside the ServletContext. This way for all their incoming requests I can match them without asking for password across all classes.
Also I will make sure to automatically erase their info from the ServletContext when their 15-30 minute expires.
So far it seems like to me this method avoids both JS and Cookies, also all the external storage methods that are at risk when the program dies. Yes the ServletContext is supposed to be global, but without their unique temporary id/hash no one will be able to impersonate them.
I am asking this question because I couldn't find anyone else asking the same question so I needed to make sure there isn't anything wrong with this method.
Given the following restrictions:
No cookies allowed.
No JS allowed.
Caching credentials at client-side is not an option.
The proposed approach seems ok at first glance. However, I would suggest that you follow this guidelines:
Make sure replay attacks aren't possible. Since you can't hash and sign request at client-side, invalidate and refresh the tokens frequently (preferably with each request) at the back-end.
CSRF counter-measures should be in place.
SSL should be enforced.
I have a sort of challenge with a development, basically I need to authorize the user to go/call to certain page/functionality using a token, those pages can be set to require authorization by demand (perhaps setting a param in a database).
The application was made with Struts 1, so what I have been thinking is just intercepting the URL using a filter, check if the request needs authorization, send the token via e-mail and redirect the user to the "insert token" page, then again intercept via filter if the referer was the token page and validate the value, if correct, then redirect to the original request...
However I can't simply recover the previous request, also the filter intercept the ServletRequest and Struts has a more detailed construction, so I can't loose the action or the form objects.
I'm not sure if this is a good approach to solve this need, if so, I need to keep the original request in memory and I'm not sure how to do that.
This is a legacy project and has a lot of pages and controllers, so it's almost imposible just going through every method doing validations.
I would accept any suggest, have a nice day! :)
EDIT
To add more context, the project has many forms made with Struts, so internally Struts map the html form to a POJO, to get them as parameters in the actions's (controllers) methods: ActionMapping and ActionForm. When I create a filter, my params are ServletRequest, ServletResponse and FilterChain objects, directly I don't have the ActionMapping or the ActionForm, but I know they are part of the request structure, so since I don't know how to get them directly, I'm trying to work with the whole request, hence the security and size issues, and also because I don't know how to store a copy of the original request while I'm doing the redirect operation
Given the amount of information Struts likes to pass around, I would be tempted to keep a session somewhere safe for the user's return. This post talks about a similar idea, though you could possibly just keep the sessions keyed by token.
Aware this idea would depend on the environment though, e.g. how quickly the user is expected to come back with the token, and the total number of users this needs to scale for.
I would have considered encrypted HTTP cookies (if your application privacy policy allows cookies).
You can store the required information for later use and expire it after a while. Also, you don't need to be concerned about session storage and scaling. Seems to me fits the bill.
Having said that, there're details that you need to consider. In particular cookie encryption.
Update
A note on big objects in cookie. Creating big HTTP header is not always a good idea. Most web servers even force a maximum on header size (see Maximum on http header values?). You need to serialize the binary data in Base64 encoding which makes it even larger.
If your objects really big (like Struts constructs) that can't fit in the HTTP header. You probably don't want to store them in your in-memory session either. You might want to consider a database backed session if feasible.
Tomcat (if this is your web container) has one JDBCStore and you can configure it. It's not great though, having a database query on each request/response.
An alternative to storing all sessions in database, is to only store that particular object in database and store its associated key in HTTP cookie. This is what I would probably do given the size of the object.
This is basically a trade-off between memory and speed. (I don't know the exact requirements of your application in terms of resources and performance).
After few days looking for a properly solution, I have decided to change the idea, instead of rewriting (in a very unsafe way) the request, I designed a two side solution, from the frontend side I intercept any request using JavaScript, I do an initial validation of the URL and then ask for the token, so finally I'm sending an additional parameter that I can get in the filter, and then after doing the validation, I can continue the original request or create a redirection.
Thank you all for the time and suggestions, I think is better explain what I did instead of leaving this topic in the air.
Is it good practice to validate user input using the domain constraints such as email(unique:true) then rely on a message.properties input such as className.email.unique=Email address already in use to create an error message. Or is it better practice to have some client side validation or some check being carried in a web service before trying to persist to the domain?
It common practise to use both client and server sides.
Client side validation adds convenience to the user and can reduce bandwidth or improve the work flow but it isn't 100% reliable.
Client side validation has significant aesthetic appeal as well as being able to alert users of mistakes before the post operation, it will look better but and be nice for users but won't stop bad inputs, it is purely an aesthetic choice for improving how the user interacts with the page and hopefully reducing the bandwidth of sending multiple bad inputs before getting it right.
The source of a page can be edited locally in order to disable or bypass even the most well formed validation and to completely suppress it, so nothing you can do on the client side will be able to stop a determined user from making a mess of your system.
This means you also need to have good server side validation, it is good practise to try and protect yourself against injections and other sorts of nonsense users can intentionally or accidentally pull off, especially since you are out on the web. Reducing the points of failure by having both validations is the preferred way because they both add value.
You should look into using CommandObjects on your controller action when accepting request payload.
http://grails.org/doc/latest/guide/single.html#commandObjects
Command Objects allow you to put validation rules/constraints on the request payload. Now this is good because you apply new constraints which are specific to payload request from web without causing it to hit your logic. A cool feature is you can inherit domain constraints.
#grails.validation.Validateable
class LoginCommand {
String username
String password
static constraints = {
username(blank: false, minSize: 6)
password(blank: false, minSize: 6)
}
}
I have been working on a GWT application, which is a variation of an issue tracking system. There are some projects, which have some tickes(tasks or issues) assigned to some users. One of the requirements is to provide the administrator with an option to give access to a certain non-user person, to a specific task of a specific project. This can be a read or read/write access.
So, the question is, what are some best practices to achieve this, especially in a GWT application? Are there some specific protocols, or frameworks etc to be used.
My understanding is to generate a unique(non-guessable) url token, map it to the ticket(task, issue). And also, map the token to an access type(read, read/write). Then, load the mapped ticket, with the right access type.
But, i am wondering if there is a out of the box solution to this?
AFAIK there is no ready-solution in GWT.
Basically you will create a history token (i.e. http://MyGWTApp.com/tasks/#!SOME_LONG_UID).
When the user navigates to this URL, you have to check on the backend if the UID is valid. You can do this by using either RPC, RequestBuilder, or rf. Conveniently you can return the access type (red/write) back to the client.
With the access type you can then disable some UI interface elements.
Some things to keep in mind:
For each task/action that goes to the backend you have to check if the UID allows the access pattern (= never trust the client). So you also have to send along the UID with each request.
You can also have to make sure on the backend that when the anonymous users can only carry out the tasks (read/write) that are allowed (= whitelist).
Does the Spring Framework use (or in one of the options that it supports) encrypted cookies that store the logged in users userId in a cookie?
This is how ASP.NET authentication works, where it encrypts a value in a cookie, which is normally the userId or username.
Is that what Spring does? (I realize Spring let you choose, but is this the most common approach generally?)
I don't have the source handy to prove this, but the answer to the question is no.
Spring Security handles everything on the server side. The only cookie on the client is the one for JSESSIONID, and the security framework merely checks for the authentication/principal object in the request's session (at least under the default setup).
I don't understand why you would store any sort of authentication information in the client's cookie if you could simply store a sessionID and track authentication details and state on the server side.
Storing user ID or any kind of data the server relies upon is a terrible idea. It typically means as soon as someone figures out how your encryption works (which is only a matter of time, particularly when they have a crib as user IDs tend to be public too) they can probably compromise your system.
In case you're wondering what a "crib" is. see Cryptography FAQ (03/10: Basic Cryptology):
Cryptanalytic methods include what is
known as practical cryptanalysis'':
the enemy doesn't have to just stare
at your ciphertext until he figures
out the plaintext. For instance, he
might assumecribs''---stretches of
probable plaintext. If the crib is
correct then he might be able to
deduce the key and then decipher the
rest of the message. Or he might
exploit ``isologs''---the same
plaintext enciphered in several
cryptosystems or several keys. Thus he
might obtain solutions even when
cryptanalytic theory says he doesn't
have a chance.
Java Web apps typically just store a session ID and that session on the serverside contains such information as user ID. That's much more secure.