Passing password value through URL - html

OK I see a lot of people asking about passing other values, URLS, random stuff through a URL, but don't find anything about sending a password to a password field.
Here is my situation:
I have a ton of sites I use on a daily basis with my work and oh about 90% require logins. Obviously remembering 80 bajillion logins for each site is dumb, especially when there are more than one user name I use for each site. So to make life easier, I drew up a nifty JSP app that stores all of my logins in a DB table and creates a user interface for the specific page I want to visit. Each page has a button that sends a username, password into the id parameters of the html inputs.
Problem:
I can get the usernames and other info to show up just dandy, but when I try and send a password to a password field, it seems that nothing gets received by the page I'm trying to hit.
Is there some ninja stuff I need to be doing here or is it just not easily possible?
Basically this is what I do now:
http://addresshere/support?loginname=steveoooo&loginpass=passwordhere
and some of my html looks like this:
<form name="userform" method="post" action="index.jsp" >
<input type="hidden" name="submit_login" value="y">
<table width="100%">
<tr class="main">
<td width="100" nowrap>Username:</td>
<td><input type="text" name="loginname" value="" size="30" maxlength="64"></td>
</tr>
<tr class="main">
<td>Password: </font></td>
<td><input type="password" name="loginpass" value="" size="30" maxlength="64"></td>
</tr>
<tr class="main">
<td><center><input type="submit" name="submit" value="Login"></center></td>
</tr>
</table>
</form>
Any suggestions?

Steven,
AFAIK, most browsers will not pass POST or GET data to prefill a form field with type=password, as it really just makes things even easier for bots. Further, most sites will protect against this. When you see it prefilled, it's usually your browser saving the password client-side and then filling the password for you - this information never goes out over the net. Hopefully you understand the security implications of sending your username and password in plaintext on a request to a remote server.
Since what's built into browsers already doesn't seem to be doing the job for you (password access from multiple computers, perhaps?) what you're more likely looking for is a browser extension that supports storing those passwords for you and will do the insertion via JS or something client-side. Not endorsing any particular product, but here's an example: https://addons.mozilla.org/en-US/firefox/addon/8542. This of course means your passwords are stored on someone else's servers, though, which may be something you want to avoid.
If you want or need total control of that data, another product you might look at is keepass (which I use as a DB stored on a USB key for not only web sites, but passwords for just about everything I have): http://www.keepass.info

Most browsers have a built-in feature, or an extension to remember passwords for you, so there's no need to roll your own.
Additionally, trying to send your passwords in GET variables is a bad idea -- your password will be saved in your browsing history in plain text and most likely in several server logs scattered around the internet.

You should probably look into using KeePass or a similar password-manager program. Sending your full login info in the clear as part of a URL is a really bad idea, there are various points along the line that someone else would be able to access it.

Related

Anti Forgery - better understanding how it works

I am learning about protecting a website from unauthorized access and I have came across anti forgery. Here is my thought (and my problem I have with it). Please correct me if I am wrong.
Anti-forgery is in the ASP.NET MVC Applications handled (there might be many other ways, but this one is quite common) by inserting #Html.AntiForgeryToken() to the Form that is present on a webpage.
This token is afterwards used once user tries to POST the data to the system, where if we decorate our IActionResult or JsonResult method with [ValidateAntiForgeryToken] attribute, it checks whether the key matches the expected result. Here is an example of what I mean by decoration:
[Route("")]
[HttpPost("")]
[ValidateAntiForgeryToken]
public JsonResult UpdateRecords([FromBody]CustomRequest request)
{
if (ModelState.IsValid)
{
//...do some logic here
}
}
The reason why a webistes are using anti-forgery keys are, so that we do not want to allow unauthorized access to our business objects such as databases. The problem is, that if a website uses a cookie authentification, that is stored to a local cache, hackers can easily retrieve this stored value and use it when posting the data to our website. Due to that, we are implementing another level of protection, which is by inserting a special (unique) key to a webpage, which is being check upon posting the data. If the key is not matching, then the whole posting procedure fails.
Here is the thing I do not understand. Let's say that we have implemented our anti forgery on super simple form on our webpage like this:
<form method="post" ng-submit="addItem()" id="main-form">
#Html.AntiForgeryToken()
<input placeholder="Add New Item" ng-model="newItem" id="new-item" />
</form>
I know it does nothing, but let's imagine that by clicking the input button user tries to post some data to the database. If we inspect the webpage, we will suddenly see, that this is what the HTML generated code would look like:
<form class="ng-pristine ng-valid" method="post" ng-submit="addItem()" id="main-form">
<input name="__RequestVerificationToken" value="CfDJ8Ig8dRjRrw9FjKYv6kYaxVu7APOddjpVxQ3ZxGaamjVzV03eQEG7tgRe5q2uXJkKkbUf4RqzRCtJ1DGMK5C-ymroTBe_J9XQ-...(more text here )" type="hidden">
<input class="ng-pristine ng-valid ng-touched" placeholder="Add New Item" ng-model="newItem" id="new-item">
</form>
Now here, what I (and potential hacker) can see, is the special anti-forgery key we have just talked about. How come that this key is visible to anyone using the website? What I understand from this is, that we are basically serving our code to the hacker and he can now easily use it when posting to the database in order to authenticate himself; or am I wrong?
I am quite confused at the moment and therefore any help / info or recommendation regarding this matter would be more than appreciated.
The token is there to prevent people from falsifying form requests. It's also regenerated each time it's required - at least per-user and probably per-request (I am not sure on this last point). This means the attacker can't just copy their own token, or make it up; they would have to take it from the user's page and if they can do that then they probably have enough information to bypass the token anyway.
An attacker could craft a form on another website with some values and point it at a page on your website. If the admin submits this form (unwittingly through javascript, for example) then they have effectively just performed that action with their privileges and with the values specified by the attacker. This is bad, with sufficient knowledge you could trick someone into deleting an account, posting something obscene, etc.

How to make hidden input actually hidden (making forms more secure)

I have created a form that contains the following within its <form> tag:
<input type="hidden" value="<?php echo $user_id ?>" name="author">
The problem I see here is that users can easily inspect element and change the value... and when doing so, affect how that value is processed in the form.
How do people make this type of form processing more secure so that users can't alter values?
The problem I see here is that users can easily inspect element and change the value... and when doing so, affect how that value is processed in the form.
Your application should not allow any such action without full server-side authorisation checks.
If the user is not supposed to be able to change the author value, you shouldn't even bother read the author value in the form submission, take the value you originally put into the form. If the user is supposed to have limited ability to change the author value (eg. only Administrator users can change the author), then check to see if the author value is allowed for the current user, and if it isn't then generate an error.
How do people make this type of form processing more secure so that users can't alter values?
The user is completely in control of what happens on the client-side, you can't make a browser take that control away from them. The security control must be on the server side.
(Some comments are suggesting encryption to protect a value given to a user, but this is much harder to get right than it looks. Applying an encryption function alone is no protection against tampering at all; to do that you need message signing and some connection between data in the signed message and the user/session and field purpose so the user can't just paste in an encrypted value they find elsewhere. Don't go this way until you really need to, the road is littered with corpses.)
<?php echo $user_id ?>
BTW you should use htmlspecialchars() when echoing any variable data into an HTML template otherwise you are vulnerable to HTML-injection (XSS).
I'm not the php crack but I would use something like
<input type="hidden" value="<?php echo encrypt($user_id, $secret) ?>" name="author"/>
where encrypt() should be a php encryption function (maybe How do you Encrypt and Decrypt a PHP String? will help...
On the server side you may use
$user_id = decrypt($POST["author"], $secret)
If conversion fails, somebody did something. To even harden your data, you could add some checksum field to cover the complete data set of hidden values. .NET ASP.NET does something similar with their data passed to the client as part of a form...

When to use form submit instead of simple links?

Is it better to use:
<form class="delete" action="/post/delete/id/1234.html" method="POST">
<input type="submit" value="delete this post"/>
</form>
...instead of:
<a class="delete" href="/post/delete/id/1234.html">delete this post</a>
...when there is need to modify something in database? Like when adding, updating, deleting and voting? Also for logout action (which in my application is saving timestamps when the action is taken), etc.?
Well, per the HTTP spec, POST (in this case, your form submission) is for changing data and GET (in this case, your link) is for retrieving data. So you should use POST to delete things, and links should only be used to retrieve things. If nothing else, this makes it slightly harder for your end users to edit the URL to delete things that they shouldn't. But really, it's just "right" to use POST for anything that will change your data.
EDIT: including some text from above link:
GET
Requests a representation of the specified resource. Requests using GET should only retrieve data and should have no other effect.
<form class="delete" action="/post/delete/id/1234.html" method="POST">
<input type="submit value="delete this post"/>
</form>
About code will generate HTTP Post
<a class="delete" href="/post/delete/id/1234.html">delete this post</a>
Above code will generate HTTP Get. You should not use Get to update/delete record. In other words, you should not use above hyperlink to delete a record.
HTTP Verb
Here are the explanation of HTTP Verb from ASP.NET MVC 4 and the Web API book
GET - Get a specific task, identified by the URI
PUT - Replace or create the single task identified by the URI
POST - Create a new subordinate under the task identified by the URI
DELETE - Delete the tasks identified by the URI
Using GET, you have potential for accidental or malicious actions. Consider this:
<img src="http://yourdomain.com/post/delete/id/1234.html">
If a user views this "image" (on any website) and they have delete permissions, it will send a request to that page and delete the post. Yes you can check the referer and such things, but it is an issue that is better avoided. For this reason, I also prefer POST for logouts as well.
The only time you should use GET is to request something for viewing, not deleting, editing, or adding data.
For this context it doesn't mather.
It mather when you have form items (text box, checkbox) or if you want to send information through POST instead of GET.
Form submit is when you want to submit the user defined values to the server . here in your example
<form class="delete" action="/post/delete/id/1234.html" method="POST">
<input type="submit value="delete this post"/>
</form>
in form submit you can enter you values that has to be submitted to the server for manipulation. Examples of when to use form submits are Login page. Registration page, ie when user defined values are to be submitted to the server
but in this example
<a class="delete" href="/post/delete/id/1234.html">delete this post</a>
you are not having a input interface for the user to enter values and submit to the server. These are used when you want to pass static values which are not user defined or mainly to redirect to another page.

How to keep confirmation messages after POST while doing a post-submit redirect?

Hello,
I'm looking for advise on how to share certain bits of data (i.e. post-submit confirmation messages) between individual requests in a web application. Let me explain:
Current approach:
user submits an add/edit form for a resource
if there were no errors, user is shown a confirmation with links to:
submit a new resource (for "add" form)
view the submitted/edited resource
view all resources (one step above in hierarchy)
user then has to click on one of the three links to proceed (i.e. to the page "above")
Progmatically, the form and its confirmation page are one set of classes. The page above that is another. They can technically share code, but at the moment they are both independent during processing of individual requests.
We would like to amend the above as follows:
user submits an add/edit form for a resource
if there were no errors, the user is redirected to the page with all resources (one step above in hierarchy) with one or more confirmation messages displayed at the top of the page (i.e. success message, to whom was the request assigned, etc)
This will:
save users one click (they have to go through a lot of these add/edit forms)
the post-submit redirect will address common problems with browser refresh / back-buttons
What approach would you recommend for sharing data needed for the confirmation messages between the two requests, please?
I'm not sure if it helps, it's a PHP application backed by a RESTful API, but I think that this is a language-agnostic question.
A few simple solutions that come to mind are to share the data via cookies or in the session, this however breaks statelessness and would pose a significant problem for users who work in several tabs (the data could clash together). Passing the data as GET parameters is not suitable as we are talking about several messages which are dynamic (e.g. changing actors, dates).
Thanks,
M.
It sounds like type of user messaging system is needed. By this what I mean the process could look similar to the following:
The user submits the form
The system could register the user for a set of notifications/messages (store in a DB table or something along those lines.
The system send the redirect response to the user
On the next page load for the user the system would check to see if the user had any pending messages.
If they do then remove them from the pending list/table and add them to the page
This keeps you from having a page state issue while still providing the user with the messages to be displayed, note that you might need to tweak the specifics to your needs.
Hope this helps.
ASP.NET
Since the question is presented as language agnostic, you might be interested in ASP.NET's Server.Transfer which does exactly what you want to achieve.
PHP
However for PHP, the situation doesn't seem to be very easy and all solutions that come into my mind have design smells:
Sessions
Using sessions to mark your data with certain flags and then check and use them on overview page. You just have to be sure you always unset these data after you don't need them anymore, which might be tricky.
Database
Queue those data in database as confusedGeek described in his post, but I don't think it's a good idea to query every single request like this. It's going to be quite many requests on DB server if you application is bit bigger, which might slow things down.
cURL
Taking advantage of cURL in PHP, if you have the chance:
<?php
$curl = curl_init( );
curl_setopt( $curl, CURLOPT_URL, "http://localhost/something.php" );
curl_setopt( $curl, CURLOPT_POST, true );
curl_setopt( $curl, CURLOPT_POSTFIELDS, $_POST );
curl_exec( $curl );
curl_close( $curl );
?>
<form action="test.php" method="post">
<input id="textfield" name="textfield" />
<input type="submit" />
</form>
This piece of code takes something.php on server side, allows to send POST data to it and shows you its content (which could be just print_r( $POST ); in this example). This one could do what you need, but it has once again one flaw - the URL won't change, so users might get confused - and I wouldn't really recommend it.
I personally think your case might be a design flaw. Why would you want to take all resources from form page and move them to other? Isn't easier to work with your data in a file / class designed for it and then just decide what outcome you have? If something fails, it returns the user on page with form and if everything went well, you post the data to DB and show overview page with some happy message that everything went okay.
If you really want to proceed with the way of sending everything to other page, using AJAX/AJAJ could be another solution for you.

Best way of retrieving lost password

What is the best method to reset a user password when password is hashed:
Reset a password to a random string and send that string to their registered mail?
Create a unique hash link for resetting password which is valid for an hour and sending that link to mail?
Any other method?
Create a unique hash link for resetting password which is valid for an hour and sending that link to mail
This is the method that I prefer. It allows you only to reset the password if and only if the user visits the link. This way, if someone is maliciously trying to reset passwords, the user can simply delete the email and be unaffected (not have to enter a new password).
Also, you should give the reset link some sort of longer expiration date (like 12 to 24 hours).
2 is the best method. Never ever mail a password in plain form. Even better, don't keep it in your system this way. Always have it hashed and salted.
Follow-up to comments: Emailing hashes instead of plain passwords may also be insecure but you are pursuing a different goal through this. Many people use the same password for all sites, from Facebook up to online-banking. A particular hash may get compromized, but not the password itself, which is the point.
#2 is preferable to #1 if only because sending a password in plain text via email exposes it unnecessarily.
Other options are:
use password hint questions
use OpenID and punt the entire problem to the user's OpenID provider.
It depends on the sensitivity of the information you are protecting...
There is a fine balance between security and usability, and you need to decide where it is, and what assets you are protecting.
What I would normally do (assuming to financial data is involved) is option 2, minus the 1 hour limit.
I found a really interesting method on some websites: they are sending you a new password via SMS. This is awesome because the e-mail can be hacked but the phone... I don't think can be easily hacked.