How to protect registration page from multiple malicious requests? - java

I allow users to register on my website using a registration form.
Once form is submitted a token will be generated and will be sent by email to user, they need to click on the token link to activate their account.
My question is that if I do it, do the malicious codes can still send multiple emails to my website to register, should I use Captcha to protect the website or there is any other method ?

If all you want is to prevent double submissions, you can generate a unique token for the form that you check on submission. This requires some thought if there are multiple forms per page. Also, a simple method is to just disable the form/button on submission. This is even more effective if the form is submitted via Ajax (so that the action parameter of the form can be absent and thus not easily harvestable).
If you want to prevent automatic submissions (by bots), while Captcha is probably the strongest of the common methods, it is also very user-hostile. Instead, unless you have a reason to believe your site is being specifically targeted, it is usually enough to just use honey-pot fields (invisible fields that a human would never fill but a bot would) and hidden fields that you fill with a known value after a short delay using JS (a bot wouldn't normally execute JS nor take time to type into fields like a human). Simply doing an Ajax submission is also usually enough. I recommend using one or a mixture of these methods before falling back to Captcha.

Captcha is one of the standard methods.
Another way is do not do a direct submit of the form.Use AJAXfied server calls sos that form does not get posted by itself but has some data scrambling of inner fields & delays the submissions.
$("#contactForm").submit(function(event)
{
/* stop form from submitting normally */
event.preventDefault();
/* get some values from elements on the page: */
var $form = $( this ),
$submit = $form.find( 'button[type="submit"]' ),
name_value = $form.find( 'input[name="name"]' ).val(),
email_value = $form.find( 'input[name="email"]' ).val(),
phone_value = $form.find( 'input[name="phone"]' ).val(),
message_value = $form.find( 'textarea[name="message"]' ).val();
/* Send the data using post */
var posting = $.post( "contact-form-handler.php", {
name: name_value,
email: email_value,
phone: phone_value,
message: message_value
});
posting.done(function( data )
{
/* Put the results in a div */
$( "#contactResponse" ).html(data);
/* Change the button text. */
$submit.text('Sent, Thank you');
/* Disable the button. */
$submit.attr("disabled", true);
});
});</script>

I'm no expert in this matter, but the solution seems rather obvious to me:
Everyone uses CAPTCHA. There's simply no other way to protect your server from automated attack. It won't save you from DDoS, but will handle pretty much everything else because CAPTCHA is, well, CAPTCHA.
You do have multiple CAPTCHA solutions available though, so choose one that suits you best.

As Velis mentioned, easiest way is to use Captcha.
Other solutions exist but can be easily beaten if bots are targeted for your website, for example, having an hidden field like "re-enter email" which will be filled by bots, but can be caught on the server side and registration can be rejected.
Certain, complicated methods also exist, like recording mouse clicks or time taken to fill the form, but these require significant JS work and can be overkill until your website becomes a bot target.

Captcha is one plausible solution, but most humans don't like it.
How about instead if you add some intelligence to your system?
Implement a cooldown between emails. Before sending an email, wait one minute. If another email request comes then wait another minute and don't send the first one. (This could be another form of attack but only if this is the only line of defense).
Would a person try to register 30 times in the last minute? No.
Would a person re-register if the last register was successful? No.
You can also combine these with the IP of the registering user: Would a user try to create 10 new account for other users from the same IP in 10 minutes? Unlikely.
If this is a corporate website and you MUST prevent the email spamming, then consider secondary ways of communication. For example, if you have the means, you can request the user to SMS the email address to a specific number, which would create a reset password request.
You could also, upon the user completing the registration, generate a list of numbers that should be used to retrieve the account. Something like: "If your account is lost, it can be retrieved by entering one of these numbers into the RETRIEVE field" And then provide a list of numbers that would be confidential to your company and the customer. The same way Google does it.
Although these mechanisms can become complex, they will be smarter than any captcha; will be easier to adapt, and more comprehensive. On the plus side your users will thank you for not having to read twisted images of numbers and letters.

Related

How to get total number of authenticated web hits?

I am using Google Analytic API in java to get Google data for one of the website where my Google account is registered. I am able to get total number of hits between two specific dates, But I want to retrieve total number of authenticated web hits. I am not getting any proper way to get this data using Google Analytic.
The function that I have written for getting for number of hits is:
private static GaData getWebHitsByMonth(Analytics analytics, String profileId) throws IOException
{
return analytics.data().ga().get(profileId, "2013-07-01", currentDate, "ga:hits")
.setDimensions("ga:yearMonth")
.execute();
}
Can someone give me an idea about this?
Since Google Analytics has no way of knowing whether or not a user is authenticated, you have to tell it. There are two ways to approach sending this information to Google Analytics: the first (easier) is with a custom dimension, and the second (more involved, but more useful) is by using the User ID feature.
If you go the route of using a custom dimension, you'll basically just have to set that on your tracker object as soon as you know that a user is logged in. Assuming this is the first custom dimension you've made, the code might look like this.
// Set that the user is logged in.
ga('set', 'dimension1', true);
Now all subsequent hits sent to GA will include this value. (Note: you'll want to set it to false if the user logs out.)
To report on that data, you can use a filter to limit the returned results to only authenticated hits. It might look something like this: filter=ga:dimension1==true.
The second option is to use the User ID feature. The User ID is another dimension, and it allows you to track logged in users across multiple devices.
The main catch with using User ID is you are not allowed to send any personally identifiable information (PII), so it may require a bit more development work to create the User ID; however, if you're able to do that, it's probably the better route to go.
Here are some developer guides to help get you started with the implementation:
https://developers.google.com/analytics/devguides/collection/analyticsjs/user-id
https://developers.google.com/analytics/devguides/collection/analyticsjs/custom-dims-mets

How to check if request is coming from the same client browser?

I need to implement captcha functionality like in Gmail.
If the user has requested first time, no captcha image will be shown.
But, if user is requesting second time to login, (User has entered wrong password first time) need to show the captcha.
Please let me know how to check if the request has come from the same user so that I can implement some business logic in my spring classes.
Why are you trying to tie up login attempts to concrete user? If I'm a malefactor and I want to guess the password, I'll use the bruteforcer which can use proxies.
Each time I'll have new IP, so your captcha will not work for me.
In my opinion the better solution is to store counter of incorrect login attempts. Each time anybody inputs wrong password for particular login-name, you increase the counter value for this login. If password is correct, you set this value to 0. If counter value more than 0, you'll show your captcha.
Attach the counter to the HTTP session. You may required to store the session on the server side, and in a distributed ENV, you should SYNC the HTTP session across servers. You can also store that info into Client side cookies.
At server side(servlet) create HttpSession
HttpSession session = request.getHttpSession();
and keep count of hit inside this session
session.setAttribute("count",i); //you can use getAttribute() method to check the count.
There are a couple of ways to do that:
When the page is first loaded, start a session (or send out a coookie). Use a count against the session/cookie. You can spit out a captcha once you find the cookie for the second time.
Use hidden form fields. Put a special name/value pair that you can identify on the second request and send a Captcha across.
Use AJAX! This would involve using an XMLhttprequest to submit your form, if invalid, you can show a captcha! This would probably give you more control, but at the expense of re-working a bit.
The last two bullets are assuming you want captcha on wrong passwords rather than on a different request/page-reload.
Every one of the above methods has its own pros and cons. You need to choose one or a combination or more than one according to your need.

Generating Dynamic URLs

I have a list of users across various companies who are using one of the functionality that our website provides. Whenever they contact our business group , we need to send a url via email to the requestor in order for them to upload some data. All these external users do not have any dedicated account. However we do not want a static link to be provided to them as this can be accessed by anyone over the internet. We want dynamic links to be generated. Is this something that is usually done? Is there an industry accepted way of doing this? Should we ensure that the dynamic link expires after a certain amount of time - if so , are there any design options?
Thanks a lot!
Usually, parameters to urls and not the actual urls are what's dynamic. Basically you generate params that are stored somewhere, typically on the database, and send email with the url and the parameter(s). This url is valid for only a limited period of time and possibly only for one request.
Answers to questions:
yes, this is something that is quite commonly used in, for example, unsubscribing from a mailing list or validating an account with a working email address
I'm not aware of any single way that is "industry accepted", there are many ways of doing it, but the idea is not that complex - you just need to decide on a suitable token format
normally you should ensure that the link expires after a certain amount of time. Depending on the use case that can be some days, a week or something else. In practice, you'd remove or disable the generated parameters in your database. However, if this data is something that might be needed for extended periods of time, you might want to think up a functionality so that it can be retrieved later on.
You may have a static URL taking a token as parameter. Eg. http://www.mycompany.com/exchange/<UUID> or http://www.mycompany.com/exchange?token=<UUID>.
The UUID could have a validity in a time range or be limited to a single use (one access or one upload).
Other variant is to use exists cookies on that site in web browser (of course, if they are).
But there are some drawbacks in this solution:
User can open link in different machine, different browser. User can clean all cookies or they can expire after it was visited your site last time when user try to go on granted URL. In these cases user won't access your page.

Java EE - creating a register-by-email setup

Assuming I have a web app (Java EE 6), I want to realize the following use case:
On a generic "register" page, user enters his/her email and submits
System sends email to user. In this mail, there should be a link to a full registration page
User follows link, fills out required credentials, and submits
System stores user in database, and sends confirmation email
All temporary data is discarded.
The part I am having problems with is mostly step 2. What I need to know is the following:
What is the best way of setting up a personal registration page for the user? Should I generate a temporary page and link to it? Should I give the user a special cookie? In either case, how can I implement this? No code is needed, I just need some pointers on where to start looking and coding.
EDIT:
A very important question here, no matter how I do it, is the following: How can I generate and deploy a temporary webpage? I am rather new to Java EE, so forgive me if this has an obvious answer.
If the registration page is standard for every user then there is no need in creating a temporary page and linking to it or creating a special cookie etc... Just create the page with the registration form on it and send your clients a link to that.
If you want a special customized registration page for a specific user, then you can just send an e-mail with a link to your client with their information as a query parameter (ie http://yoursite.com/registration?fname=jordan&lname=denison) or you could use something like PrettyFaces to make the URL more readable as well as making it easier to extract those parameters and fire a method with them.
If I had to do it, then I would have
Created a generic registration page
Created a unique ID for the user
Send the link to user which contains the unique ID as a parameter
The registration page throws error if the unique ID is not presented to it, or the ID is not valid (already used, or not issued)

Prevent Form spam with the session

I've already read most of the questions regarding techniques to prevent form spam, but none of them seem to suggest the use of the browser's session.
We have a form that sends an email to given email address and we didn't like the idea of using "captchas" or Javascript, as we wanted to keep the user journey simple and accessible to those without Javascript.
We would like to use the session object to help prevent form spam. Our webapp is developed on Weblogic Server 10 using Struts.
The solution being, when the form loads, it would set a variable in the session object. Once you click submit, we check if the session for the variable. No variable, redirect to the form. Variable exists send the email.
I would really appreciate any opinions/reasons why this might be a bad idea, so we can evaluate this solution against others.
Many thanks,
Jonathan
There is nothing to prevent a spammer from automating the process of downloading your form (thus generating the cookie) and submitting it. It may impose a slight burden on the spammer, but a trivial one.
As an example, a form can be easily downloaded and submitted, with cookies preserved, using a command-line tool such as cURL. This can then be run from a script repeatedly.
Session objects can, depending on implementation, be relatively heavy in terms of resource usage, as well as somewhat slow. Additionally, the spammer, if they realize how you are blocking them, can simply start a new session every time they hit the form by not sending back the session cookie.
So, because that technique relies on the client to behave nicely, and the expected behavior is fairly easy to prevent, it is possibly less useful than some other ways to solve the problem.
Thank you for your reply cdeszaq, but I'm not sure if you mis-understood my question.
For the form submission to complete successfully, clients will be forced to load the form to set up the session object correctly. Only when the session is in the correct state, will it be possible to send an email.
If the spammer is not sending back the session cookie, then they will not be able to spam my form as they haven't gone to my form page that creates the right session.
I agree that using the session object would create extra resource. Our implementation would simply, (using JSP) call session.setAttribute("formLoaded", true); and in my Struts action I would simply use session.getAttribute("formLoaded"); to check.
I wonder if this might work:
Each time you render page/form, create a random bit of text
Put that text in the session
Include that text as a hidden field in the form
User submits the form
Action compares the hidden text to the value in the session - if there's a match, send the email
Since a hacker wouldn't be able to put any random value in the session, they wouldn't be able to spam. Right?

Categories

Resources