When calling loginWithPassword I receive an error with code 403 in both cases: when the user doesn't exist and when the password is wrong. I know that theirs messages/reasons are different, but I think that comparing with string is not a good practice. Is there a different way of differentiating these cases?
UPDATE Using accounts-password
No real way of differentiating other than checking the error description string (that is what it is for).
You can always implement your own mechanism server-side (e.g, a method), but the default one sends a numeric error code (normally corresponding to the HTTP code - in this case, 403 forbidden), accompanied by a string.
They have not changed recently and it is fairly safe to depend on them, especially if it is not something mission-critical.
You could implement a method that checks for the existence of a user and then call that after a failed login attempt. If the user exists then you can display a bad password warning.
You could even check existence before the password is typed and put a green checkmark next to the username field if the user is found or a red X otherwise.
There are many ways to do this.
Related
The background first:
I have an application where a logged-in user(employee) X can see a list of all other users (employees). If the logged-in user X is a manager (their designation), then they can also edit certain attributes of the users they manage. For example, the location, designation, and the department of the user being edited. It should be noted X can edit only those employees who report to him/her, which means there are users which X is not allowed to edit.
When X clicks on a user to edit it, they navigate to a page like http:myapp.com/dashboard/editUser/<ID_OF_THE_USER_BEING_EDITED>
Obviously, X can get smart and manually edit the URL and put in the id of a user they are NOT allowed to edit, so before loading the edit form I need to check whether X has the authorization to edit user Y.
if X is authorized to do so, then that page displays a form (with the current attributes of the users pre-filled in the appropriate fields) to edit the user. Else, I display an 'Access Denied' kind of message.
Right now I have created a very badly named temporary endpoint (/api/v1/maybe_edit_user/?jwt=<TOKEN>&userId=<USER_BEING_EDITED>).
This grotesque-looking endpoint does 2 things:
It extracts the currently logged-in user from the token, and checks whether it has the required access level to edit the user (passed through the GET parameter userId)
If yes, then it returns the current attributes (name, email, location, designation, and other stuff) in the response, which is then pre-filled in appropriate fields when the form is displayed.
Once X submits the form, a PUT request is sent to another endpoint (/api/v1/users/<USER_ID_OF_Y> PUT) and the user Y is updated.
While this works, I don't find it attractive. I am trying to learn to write better, cleaner, and more organized code that is compliant with the standards.
The best practices for REST suggest that all endpoints should be nouns. My endpoint, on the other hand, is not even a simple verb. It's a god-forsaken phrase at the very minimum.
So, the questions here are:
How should I name my endpoint.
Should I use a single endpoint to check for permission, AND fetching the attributes of the user being edited, like I am doing right now? Or should I break them into 2 separate endpoints?
The fact that there is an access control list is an unrelated concern; ignore it.
Resource identifier identify resources. Resources are generalizations of documents.
You want an identifier that is consistent with the production rules of RFC 3986, and it is often convenient (but not required) to choose spellings that enable leverage of URI Templates (RFC 6570), but otherwise the machines don't care.
That means you can choose a spelling that makes things easier for humans; you get to choose which humans get priority here.
it returns the current attributes (name, email, location, designation, and other stuff) in the response
That's your hint as to what the document is; some sort of digest of Bob's... profile? employee record? dossier? that is apparently optimized for use in this specific kind of form.
So the identifier could be as simple as
/this-specific-kind-of-form/source-data/Bob
and a request might look like
GET /this-specific-kind-of-form/source-data/Bob HTTP/1.1
Authorization: Bearer <token>
The implementation looks largely like your sketch - verify the token, compare the claims to those that are required, and return either the resource or some flavor of Client Error (4xx).
The best practices for REST suggest that all endpoints should be nouns.
Don't read too much into that.
Notice that all of the following resource identifiers work:
https://www.merriam-webster.com/dictionary/get
https://www.merriam-webster.com/dictionary/post
https://www.merriam-webster.com/dictionary/put
https://www.merriam-webster.com/dictionary/patch
https://www.merriam-webster.com/dictionary/delete
You can click on any of those links, and your browser will create the correct HTTP request, and the server will do the expected thing.
2nd in an occasional series:
Here's the first one
Is CAT.NET correct that the following is a genuine vulnerability in ASP.NET or is it a false positive?
var myInt = Int32.Parse(txtUserInput.Text);
Response.Redirect(string.Format("myPage.aspx?myId={0}", myInt);
CAT.NET is reporting this as a redirect vulnerability needing remediation via encoding myInt.
I wouldn't call that dangerous but its not how I would write it myself
int myInt;
if(Int32.TryParse(txtUserInput.Text,out myInt)){
Response.Redirect(string.Format("myPage.aspx?myId={0}", myInt);
}
Is to my mind cleaner as it wont throw an exception if the parse fails due to bad user input and we are explicitly typing the int.
Any error handling code can be bundled into an else statement on the end.
I don't believe so, it could cause an exception so TryParse might be a better approach. It's just yelling because you are taking user input and redirecting based on it. It's possibly being a little too aggressive which isn't exactly bad.
There is no exploitable vulnerability as a result of this code. Any vulnerability would be a result of what myPage.aspx does with the value of myId, not how your url is built. Anyone could just as easily directly hit myPage.aspx with anything they want in the querystring.
However this is bad practice, assuming that you haven't left anything out of the code between those two lines. You should verify that txtUserInput.Text contains only numeric characters, and falls within allowable values.
Exploits happen because of improper parsing of user-supplied data by the page it's posted to -- not improper generating of URLs. While it's a good idea to try to make sure your web site won't write a broken URL because of something that's put in a form, input validation at the front-end is irrelevant to security. All that matters is what the code that accepts the input does with it, since any post or query string can be forged.
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...
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.
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).