Generation of Email Validation Links - asp.net

For a Web Application I'd like to generate an email validation link and send it to the user. Like on many public websites, the user should click it to validate his email address. Looks similar to this:
http://www.foo.bar/validation?code=421affe123j4h141k2l3bjkbf43134kjbfkl34bfk3b4fkjb43ffe
Can anybody help me with some hints about the proper generation of those validation tokens? Googling best practices turned out to be more difficult than I though it would be. The links should:
... not require the user to log in first.
... not reveal any login credentials to keep the application secure
... allow me as a developer to efficiently validate the token. I'm pretty sure I need a way to extract the user identifier out of the code to meet this criteria. Don't I?
Furthermore, would you go for a random code, which is saved somewhere, or a generated code which I can recalculate for validation?
Thanks for any replies!
Matthias
P.S. I'm working with ASP.NET 3.5, in case there's an out-of-the-box feature to perform this.

Some suggestions to get you started:
Use GUIDs
Use some sort of salted hash (MD5, SHA1, etc)
Use a random string of characters (the more characters the less likely you'll have collisions)
Store it in a database temporarily, and timestamp it so that it expires after a certain period of time

The simplest way to do it is generate a GUID, store that in the database tying it to their user account and then give them a time-frame within which to click a link with that GUID in.
That validates they are the correct person without making the URL calculable whilst making it resistant to dictionary style attacks.

I construct the hash in a way that can be re-created:
code = MD5( my_hash + user_email + register_timestamp )
Then send a link to http://example.com/validation/?code = 4kj34....
Validation does a lookup like:
SELECT id
FROM users
WHERE
MD5( CONCAT( my_hash, user_email, register_timestamp ) ) = code
AND activated = 0
If you get a single result, update their 'activated' field and sign them in. You can also do some math on their 'register_timestamp' field for a poor man's TTL

I would probably use a Guid. Just create a Guid (by calling Guid.NewGuid()), store it as the validation token for that user, and include it in the validation link.

Related

Correct logic to use when implementing 2fa on my site?

I am using the "sonata-project/google-authenticator" library. It allows me to generate a QR code as follows:
$g = new \Google\Authenticator\GoogleAuthenticator();
$salt = 'XJDDJKSLJNASDJNASDASDASD';
$secret = $uid.$salt;
$url = $g->getURL($uid, 'coinula.com', $secret);
My question is around this:
The secret I provide, is that the secret that these guys are showing to the user? So that secret is the "global" key and the qr code is just a picture version of this code?
Am I supposed to store the secret and keep it safe on my side? Or is that something that the user should be able to write down and decide if he wants to keep it. I.e. Is the purpose of the secret for me NOT to store it? Or is there a reason I must store it?
Turned out to be a dumb question, but I'll answer it anyway. The secret must be stored in order for you to match it to the user. Would've been nicer if you could specify your own secret. I suppose there might be a way, but I'm going ahead with this way. So I'll be using the secret that is generated and storing that in the DB in order to compare it.

Should in encode id in Edit and Update Operation

I am making a simple crud operation in Spring and hibernate Project. when i click in edit my Url is edit/{id} and for update is update/{id}.The id is primary key,auto generated which was save in database like 1,2,3...
I want to know that id should be encoded or not in html page.Can anyone help me.
If you want to provide security
Encode the id use Base64.
Encoded id return to front
When click to edit the id will come to controller
Then you can easily decode it.
No need to encode the ID.
Its okay to keep it as it is.
If you are afraid of security then apply security on method or application level.

ASP.NET MVC 2 EditModel include Id? Securing Id is not tampered with

I am looking for some best practices when is comes to creating EditMoels and updating data in an ASP.NET MVC app. Lets say I have a Url like so /Post/Edit?Id=25
I am ensuring the user has permissions to edit the specific post by Id on the Get request and the same for my Post in the controller. I am using the ValidateAntiForgeryToken.
Questions: Should I include the Id property in my EditModel? If so, Should I encrypt it?
The problem is I can use FireBug to edit the Id hiddedinput and edit a different post as long as I have permission to do so. This is not horrible, but seems wrong.
Any help would be great!
There are several ways to prevent this.
The first - don't send sensitive data to the client at all. Keep the post id in session variables, so the user can never edit it. This may or may not be an option depending on your architecture.
The next approach is to convert the direct reference to an indirect one. For example, instead of sending postids = {23452, 57232, 91031} to the client to render a drop-down list, you should send an opaque list {1,2,3}. The server alone knows that 1 means 23452, 2 means 57232 and so on. This way, the user can't modify any parameter you don't want him to.
The last approach is including some kind of hash value that adds as an integrity check. For example, suppose you have 3 hidden fields in a html page - {userId=13223, postId=923, role=author}. You first sort the field names and then concatenate the values to get a string like postId=923&userId=13223&role=author. Then, append a server secret to this string, and hash (SHA-1 or MD5) the entire string. For eg. SHA-1('postId=923&userId=13223&role=author&MySuperSecretKey'). Finally add this hashed value as a hidden parameter. You may also want to add another hidden field called ProtectedParameters=userId,postId,role.
When the next request is made, redo the entire process. If the hash differs, balk the process.
Security wise, I have listed the options in decreasing order. At the same time, its probably in the increasing order of convenience. You have to pick the right mix for your application.
I don't think you should worry with that, if the user does what you said, i suppose that you'll know who edited what, so if he edits the wrong post, doing as you said, you can always remove his edition rights...
If you can't thrist your users, don't let them edit anything...

Can I read Captcha data from JavaScript in a secure way?

We use Captcha control in a registration form that we make full client validation for all fields in JavaScript ( JQuery ) beside server validation ..
I tried a lot of ways but all will write the Captcha value in JavaScript that can be accessed by anyone :(
I search if is there any way that allow me validate Captcha value in client side using JQuery in secure way or it can't be done ?
It cannot be done.
Javascript is client-side, as you know, and any code client-side has to be treated as potentially compromised as you don't have control over it.
At best, you could resort to sending up a salted hash of the value along with the salt, but even that in itself could be used to test guess values before actually submitting it.
Everything else relies on calls to the server.
As per comment request, here's the general idea:
Firstly, on the server, calculate a random string to be used as the salt. This should be roughly unique every request. The purpose of this string is to prevent rainbow table attacks.
Now, saving this string separately, but also create another string that is the concatenation of random string and the Captcha answer. Of this new combined string you generate the hash (for example, SHA-1) of it.
using System.Web.Security;
...
string hashVal = FormsAuthentication.HashPasswordForStoringInConfigFile(combined, "SHA1");
Both the random string and the hash value need to be placed in the page for the javascript to be able to read.
On the client side, when a user answers the Captcha, take the random string and concatenate it with the answer (getting the idea here?). Taking this string, you can use something like the SHA-1 JQuery plugin to hash it and compare it with the pre-computed hash you sent up.
hashVal = $.sha1(combinedString)
If it matches, it is (almost) certainly the correct answer. If it doesn't, then it is 100% the wrong answer.
you could use ajax to post the current value to the server, which would respond true or false. that would keep you from doing a real post and also from giving away the catpcha's value in html.
My solution )) Every time when page shows captcha to the user, you can dynamically generate obfuscated JavaScript functions(i think the best way 5 or 10).
For example, one function(or 3)) ) can set cookies with pregenerated hash(server returns it)(from real value of the captcha), other functions must realize server side algorithm to check value which user's typed. I can say that it works for 100%, because it is very hard to parse dynamically javascript + we set user cookies on client side(It is very hard for Bots's to find out where and how you set and check cookies), by using JavaScript.

Validate Origin of FORM POST to ensure it came from same server/app

I want find a platform/language agnostic solution to ensuring the origin of a FORM POST is from an expected source. I.e. Page1.aspx posting to Page2.php within the same web site.
Specifically what I am attempting to do here is to prevent request forgery.
Use a hidden field in your form, which contains a token your app generated. Store the token in the user session. When the form is submitted, your app will check that the value of the hidden field is identical to the value stored in the user session.
If it is identical, then you know the submitted form comes from where it is expected to come.
Old Thread, but might still be useful.
If you do not have session info set (best option) then you can include a hidden field with an encrypted timestamp then compare it (after de-crypt) to the current time on the process end to make sure it is relatively close and thus as recent as you deem necessary.
You could include into the form a hidden field which would be the SHA1Hash("some-secret" + Remote_IP + PerSessionSecret).
The PerSessionSecret is something you autogenerate in the beginning of the session. "some-secret" is a global secret value - which will help a little bit in case the randomly generated PerSessionSecret turns out not to be very random enough.
Then do the same calculation upon the form submission and you know it's most probably submitted from the same client that it was sent to. (Of course, if you have multiple clients behind the single address, like a proxy or a NAT, you can not distinguish between them reliably).

Resources