I want to pass an email address as a parameter in a URL string but hide it. The URL string is constructed in a Java routine and the jsp page receiving the request will pass the string to a server side java routine to decode it. Someone must have already written this code but I cannot find it - probably not asking the right question. Thanks. Fred
If you're including the email in the URL you cannot hide it, but you can encrypt it.
If encryption doesn't rock your world, and you simply want to obscure the email address, you could obfuscate it.
The other way to submit it with out it being so obvious would be to use POST to send the data to the jsp page rather than using Querystring.
Typically, users have a session with data stored on the server. The e-mail address would be stored in the session object, on the server. The client supplies its session ID in a cookie or in the URL. This way, you can pass information to the next page without putting it in the URL.
If you don't want to deal with this via a session, or you're passing this string between servers, you have two options. Either Hash the email, or Base64 encode it. If you're worried about anyone other than you ever (or the user) finding the actual email, don't use Base64. However, if that's not a concern, then base64 is the easiest and fastest way to include an email address the doesn't look like an email address.
If, however, you're worried about the information leaking in any way, use MD5 or SHA hashes of the email. To speed the lookup in the DB, you may want to pre-compute the hashed version of the email and store it in an additional column in the table.
I'd recommend SHA over MD5, though for this lightweight usage, I doubt the flaws in MD5 will affect you.
Use hiddden form fields.
<input type="hidden" ...>
Hidden form fields come into handy when you dont want them to be exposed when transferring from jsp page to servlet and then to a java bean.
Related
Story for context:
I have an ePetition type service running on my site which I email people a link where they can 'agree' to the petition. This link will only contain the 'petitionID' and 'username' of the person who sent it.
This information isn't particularly sensitive but I still require it to be tamper-proof because I want them to be able to accept without signing in or storing values in the database.
I thought of using Java's String.hashCode() function.
Maybe having the url as: username, petitionId and then a hash
www.website.com/accept.jsp?user='username'&id='petid'&token='1039678106'
The token could be made up of username + id(from the link) + datePetitionStarted(like the salt not exposed in the url) like:
String test = "mike.Who#petitionwebsite.com+1524+09/02/2016";
System.out.println(test.hashCode());
This would give me a hash of '1039678106' which means server side, I can take the ID parameter, the username of the person and use the datePetitionStarted, get the hashcode and compare them.
Do you think this is a valid way of preventing tampering?
I'm really after a token-type method of accepting petitions so if anyone has any other ideas that would be awesome.
thanks,
Mike
Here's what I did (which is practically tamper-proof). I don't use java script as users can disable it anyway. I simply create a UUID, (which is stored in a database next to user details) and then create a link sent in an email during the registration process.
http://my_domain_name/Activate?key=6faeecf5-9ab3-46f4-9785-321a5bbe2ace
When the user clicks on the link above, the server side code checks that this key actually exists in the database, in which case it activates the user account.
While the String.hashcode() may return the same value for the same string across instances, this is not guaranteed.
Whenever it is invoked on the same object more than once during an
execution of a Java application, the hashCode method must consistently
return the same integer, provided no information used in equals
comparisons on the object is modified. This integer need not remain
consistent from one execution of an application to another execution
of the same application.
API docs for Object.hashcode.
As such, if you were to down down this route you should use your own hash.
This is probably quite a simple, newbie question for seasoned Web developers, which I am not, and googling around does not help.
I have a very simple webapp hosted on Heroku, the code of which is here. It has two JSP pages, one index, one with the validation results, nothing fancy. The two JSP pages are here (index.jsp) and here (results.jsp).
The problem is with the validation servlet: it is a POST, and is triggered, when using the app itself, via an input button in index.jsp. But I have tested that it will also work if I call the servlet directly... And I don't want that.
Is there a way to reliably ensure that this servlet may only be called when coming from the index page (and send a 403 otherwise)?
One way I've used is to have the input form on index.jsp include a hidden field which contains an md5 hash which the results.jsp can also calculate. I use the md5 hash of the client machine's IP address concatenated with a shared secret phrase.
I guess for a given client IP address the hash is always going to be the same so you could also salt it with another value (like current time) which is passed in another hidden field for inclusion in the calculation by results.jsp.
You could generate a fingerprint (for example UUID.randomUUID()) when the first page is loaded and save the value in the current session.
When you post the result to the validation servlet you include that fingerprint as a hidden field and check that the fingerprint exists on the session.
There is no way you can be 100% sure of that. Eventualy you can check the referer but it's possible to forge it. You can also set a cookie when loading the index.jsp and check the value in the servlet. But it's also possible for someone to load index.jsp to retrive the cookie and then use it to post on the validation servlet. Same think with an input hidden with a hash.
There's a case that the user change the parameters send to servlet through URL,
is there's any way to restrict user not to change paramters,
if not, how can I manage all parameters send to servlets? in a case they are many, is it reasonable to check each one in turn??
You can't restrict the user from sending you anything.
It is the server-side where you can add restrictions.
Usually you get only the parameters you need, so additional parameters should not bother you.
You definitely should check parameters send to your servlet. Thats basically what you do anyways since thats the way clients (such as webpages) communicate with your application.
The simplest way is to hash the parameters with some hidden secret, and pass that back with the URL, then compare the hash to the URL parameters to make sure they match.
Another way is to not use individual parameters, but encrypt them in to a encoded bunch of characters and the whole thing is decrypted on return.
The hash is easier to implement if you don't care that the user sees the actual parameters.
You cannot avoid someone from typing in the URL, but what you do in your servlet is filter the input recieved from the URL, with some java code.
Example:
Just found an interesting link where a Servlet Filter is used to filter out XSS attacks(As you see, there is no such code that avoids someone to type certain characters in the URL, or similar): Link
Simply put, you cannot stop the users from changing the parameters.
You must do input validation on all parameter values. If you have a variable that contains sensitive information, you do not put that on the URL. A really bad example: http://mydomain.com/myservlet?isAdmin=1. Information such as that needs to go into a session since that is stored on the server and out of the user's reach.
I'm writing a web application in Java where at some point user can enter there email address to receive an email. My question is about the verification of this email address (so it's not about the validation!). I'm tagging this question also with google-app-engine, because the application will live there, but I don't think that matters too much.
Anyway, for people who have a google account I use the app engine's User API to verify that address, but for other people I would like to send a verification email, that provides them with an URL. Very standard I would think, but are there also standard ways to generate the URL? Or is just creating a hash of the email address, storing that in a database and putting it as a parameter in the URL sufficient?
I wouldn't use e-mail hash in verification e-mail. That would be to easy to guess and someone could actually try to falsify that.
If I were to implement it, I would add random GUID and store it to the DB for verification. I don't know if it is standard way to do verification or not...
Create a servlet that will check, given a key (say, some random string), whether that key is given out previously. The key needs to be crytopgraphically secure so that it cannot be guessed by an attacker wanting to pose as somebody.
Then, when someone signs up with an email, you send a link containing that key to the address they claim they own. If at some point in the future, the link you send arrives at your sever, you can record that event, and be confident that the email address is a correct one.
I am an unwilling JSP/Java noob. I've been asked to hurriedly write up a system for generating secure urls from one site to another. The actual request string (must be passed as GET request) needs to be encrypted or otherwise obfuscated so that the user cannot easily change it to request someone else's document. Because of limitations in the environment, I cannot simply manage the request in a session and really must do it this way.
A sample of what I need:
page1.jsp:
a 7 digit number is generated by our system and needs to be passed to http://otherserver.com/page2.jsp. If the user sees this number, it will be obvious what it represents, and no other number can be used for this purpose.
The number should be encrypted or otherwise obfuscated in page1.jsp code and built into a URL to page2.jsp that can be decrypted / unobfuscated easily.
Thank you for your help!
I wouldn't bother to try to obfuscate it.
Instead, if the two servers can share a common secret, you can use keyed-hashing (see javax.crypto.Mac) to generate keyed hashes for the document number, which is passed to the other server along with the document number.
The target server can then easily verify that the keyed hash corresponds to the document number, and easily detect attempts to modify it.