Using asp-page TagHelper for form element action renders "" instead of correct URL - razor-pages

I have a razor page that that shows details of a search result (that is, clicking a search result link on the search page posts to the detail page). The detail page model has four properties that are written to from the post, which are used to post back to the search page:
[BindProperty]
public string PhysicianInput { get; set; }
[BindProperty]
public string LastNameInput { get; set; }
[BindProperty]
public string FirstNameInput { get; set; }
[BindProperty]
public int SelectedPhysician { get; set; }
In order to eliminate any other issues, I have removed all other code from the model except for the empty OnGet method that was there when the file was auto-generated.
The page file looks like this:
#page
#model Registrar.Pages.Followup.Physician.DetailModel
#{
ViewData["Title"] = "Physician Detail";
}
<h1 class="page-title">Physician Detail</h1>
<div class="center" style="width:700px;">
<form method="post" asp-page="/Followup/Physician/" id="PhysicianSearch">
<div style="text-align:right;">« Back to search results</div>
<input type="hidden" name="PhysicianNumber" id="PhysicianNumber" value="#Model.PhysicianInput" />
<input type="hidden" name="LastName" value="#Model.LastNameInput" />
<input type="hidden" name="FirstName" id="FirstName" value="#Model.FirstNameInput" />
</form>
<p>
Physician Number: #Model.PhysicianInput<br />
Last Name: #Model.LastNameInput<br />
First Name: #Model.FirstNameInput<br />
Selected Physician Number: #Model.SelectedPhysician
</p>
</div>
#section Scripts{
<script src="/js/physician.js"></script>
}
The js file there as one simple function that just submits the form:
function postBackToSearch() {
document.getElementById('PhysicianSearch').submit();
}
So when I debug the project, the page loads and the form tag looks like this:
<form method="post" id="PhysicianSearch" action="">
The action element is left blank. I have searched high and low and have found no pointers anywhere as to why the tagHelper would leave the action blank. And to top it off, the search page itself uses the same pattern and has no problem, the asp-page tagHelper works as expected.
This is my first website using asp.net core 5.0, and while much of it has been a breeze, every once in awhile I run into this kind of problem, and since the framework gives no feedback whatsoever on what the trouble might be it is next to impossible to debug. Does anyone have any idea what is going on here?
Any help would be much appreciated.

Well, to answer my own question, I found a workaround. And it's pretty unsatisfying, really.
The reason I'm relying on the asp-page tagHelper to fill in my form action is because their antiforgery functionality didn't like it when I added the form action directly to the page (and for reasons I don't understand due to my inexperience with the framework). So my solution is to allow the form action to be directly added to the page, which means disabling the antiforgery functionality in the post-receiving page model. At least that's easily done, all I did was add this attribute on top of the class:
[IgnoreAntiforgeryToken(Order = 1001)]
So this is my solution. The search page now accepts the post, but disabling the otherwise useful antiforgery functionality is pretty unsatisfying (like I said above). However, if someone happens upon this and has a better solution, please share!

Related

Angular 2: sanitizing HTML stripped some content with div id - this is bug or feature?

I use <div [innerHTML]="body"></div> to pass unescaped HTML to my template, and when I pass to body div with attribute id, Angular throw:
WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).
WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).
WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).
See. plunker
So why it says this? What can be dangerous id in div? Could this bug?
Simple solution is to write pipe like
import { Pipe, PipeTransform } from "#angular/core";
import { DomSanitizer, SafeHtml } from '#angular/platform-browser';
#Pipe({
name: 'sanitizeHtml'
})
export class SanitizeHtmlPipe implements PipeTransform {
constructor(private _sanitizer:DomSanitizer) {
}
transform(v:string):SafeHtml {
return this._sanitizer.bypassSecurityTrustHtml(v);
}
}
add in your html file add pile like
<td *ngIf="i>0" [innerHTML]="entry.attributes[i] | sanitizeHtml"></td>
It is because id attribute is not safe.
This is not my answer but it will answer your question : https://security.stackexchange.com/questions/88973/why-do-id-attributes-need-stricter-validation
For id and name, these attributes are frequently used as reference points in the DOM.
If an attacker can spoof these reference points, she may be able trick existing scripts into getting and setting values from places other than designed, which may be dangerous depending on the context that is is used.
Note from me: The rest of his post talks about the name attribute, but you'll get the idea behind all this if you don't already by what's above
This also applies to HTML forms where name is used to identify the name/value pair. For example, if a website does not encode a particular form field when it is output, but since the form field is server generated and the form is protected against CSRF by the use of tokens it cannot be exploited by normal means. However, an attacker may be able to entice a user to visit a URL with a parameter that is used in name, containing an XSS payload to execute on submission of the form.
e.g. Normal use:
https://example.com/product?item_name=watch&qty=1
which renders a form
<form>
<input type="hidden" name="watch" value="1" />
<input type="hidden" name="shop_name" value="Bob's Supplies" />
<input type="hidden" name="anti-csrf" value="asdjasodhoai" />
<input type="submit" value="Click here to buy" />
</form>
And then gets output as
Thank you for buying from Bob's Supplies.
However, an attacker could send a link to the user like so:
https://example.com/product?item_name=shop_name&qty=<script>alert('xss')</script>
As the application is correctly HTML encoding at this point it renders the form as
<form>
<input type="hidden" name="shop_name" value="<script>alert('xss')</script>" />
<input type="hidden" name="shop_name" value="Bob's Supplies" />
<input type="hidden" name="anti-csrf" value="asdjasodhoai" />
<input type="submit" value="Click here to buy" />
</form>
This then gets output as
Thank you for buying from <script>alert('xss')</script>.
since this page doesn't HTML encode the shop_name parameter because it is trusted and the application framework always takes the first value in case of duplicates. Very contrived, but it was the first thing that fell into my head to demonstrate the point.
To mark a value as trusted, inject DomSanitizer and call one of the following methods:
bypassSecurityTrustHtml
bypassSecurityTrustScript
bypassSecurityTrustStyle
bypassSecurityTrustUrl
bypassSecurityTrustResourceUrl
import { DomSanitizer } from '#angular/platform-browser';
public sanitizer: DomSanitizer
[innerHtml]="sanitizer.bypassSecurityTrustHtml(content)"
https://angular.io/guide/security#xss
You can also use NgDompurify library. It can sanitize your content better due DomPurify and solves all your problems with angular default sanitizer.

Submitting form to couchDB through update handler not working

I can not post to CouchDB through an update handler and I do not know what I am doing wrong. Below follows the long description.
I created an app using erica, with details taken primarily from the wiki. It worked fine until I decided to go for POSTing, but server-side, through an update handler according to Apache CouchDB wiki Working_with_Forms
I created a new 'webapp' with erica, constructed an index (cut-n-paste from the wiki, with small alterations):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Minimal Form</title>
</head>
<body>
<div id="contact-form">
<form id="contact" method="post" action="/mydatabase/_design/mydesigndoc/_update/postForm" enctype="multipart/form-data">
<fieldset>
<label for="name">name</label>
<input type="text" name="name" placeholder="Full Name" title="Enter your name" class="required">
<label for="phone">phone</label>
<input type="tel" name="phone" placeholder="+1 (555) 555-5555" required="" pattern="\+?[0-9 )(-]+">
<label for="email">e-mail</label>
<input type="email" name="email" placeholder="you#example.org" title="e-mail address" class="required email">
<label for="blog">blog</label>
<input type="url" name="url" placeholder="http://">
<label for="message">message</label>
<textarea name="message"></textarea>
<input type="submit" name="submit" class="button" id="submit" value="submit">
</fieldset>
</form>
</div>
I altered the form-attribute action= to: htttp://localhost:5984/DBNAME/_design/DESIGNDOCID/_update/UPDATENAME and added enctype="multipart/form-data".
Then a _design document was constructed, according to the wiki, like this:
{
updates: {
postForm: function(previous, request) {
/* during development and testing you can write data to couch.log
log({"previous": previous})
log({"request": request})
*/
var doc = {}
if (!previous) {
// there's no existing document _id as we are not using PUT
// let's use the email address as the _id instead
if (request.form && request.form.email) {
// Extract the JSON-parsed form from the request
// and add in the user's email as docid
doc = request.form
doc._id = request.form.email
}
}
return [doc, toJSON({
"request": request,
"previous": previous,
"doc": doc
})]
}
}
}
This was placed in the "ddoc"-folder, pushed the app with erica, opened the webpage according to the link, found the form but when it was submitted this is what answer I got:
{"error":"unnamed_error","reason":"(new TypeError(\"point is undefined\", \"/usr/share/couchdb/server/main.js\", 1475))"}
I have fiddled around with the action="..." attribute, even put absolute adress like this:
http://localhost:5984/mydatabase...
I have replaced the toJSON() with JSON.stringify().
I have restarted the process and done the project it all over again. To no avail.
I have the distinct feeling that I have gone "blind", and that the solution is probably just in front of my eyes but I cannot see it. Seems like there is no problem with the POST-http-request, cause the server has complained before when I have experimented with AJAX (forgot "content-type"), but this time it seems to be internal server problems. And I do not have a clue. Really.
All in all, the question is: Can somebody help me? Please.
I will answer my own question and at the same time ask forgiveness from those who wasted their time with it.
What I did is that I read through kanso and understood how the concept of scope applies to the situation. It is a matter of using exports on the update handler so it can be reached through <form action="/database/_design/designDocument/_update/updateFunction.
Why did I not read through Kan.so earlier? Well, I had my mind set on keeping it simple - erica being the successor of couchapp I decided that it would be a sound move to stay on course with the basics. Though I must say that documentation is scarce so the magic of couchapp-building was demystified by reading through Kan.so and on top of it I was introduced to several other nifty concepts and techniques. I bend my neck in gratitude.
And I hope that all those who have spent their time reading through my long and, as it turned out, unnecessary question will oversee with my ignorance.
(Now I only wonder if there is some kind of admin/moderator who can dispose of my writings to avoid future timel oss)
I also ran into this error and what causes it, as hinted at by #Pea-pod, is not defining properly your exports in the couchapp's design documents. In our case it was as list function that couldn't be called and instead displayed a 500 error with Type error and point is undefined in the couchdb log.
We use kanso and in the app.js we hadn't required the list file. We had:
module.exports = {
rewrites: require('./rewrites'),
views: require('./views'),
shows: require('./shows')
};
Changing it to the following solved the problem:
module.exports = {
rewrites: require('./rewrites'),
views: require('./views'),
shows: require('./shows'),
lists: require('./lists')
};
Can I suggest to a moderator to change the title of this question to include point is undefined which is the error that shows up in the CouchDB log when this type of error is made, in order to help others find it more easily?

How to get form field array in play framework

I'm using groovy to render templates in Play framework. I have a checkbox inside a list loop:
<input type="checkbox" name="chkUser[]" id="chkUser{users.getId()}" value="${users.getId()}">
How can i get the state of the checkbox array in Controller page.
Came across this a couple of monthes ago. It seems you can use find those back in controller using :
public static myFormFunction(boolean[] chkUser) {
...
Not sure of it and I cannot check this right now.
Take a look at the official documentation.
It can be achieved using hidden fields for every checkbox.
<input type="hidden" name="HdChkUser${users.getId()}">
<input type="checkbox" name="ChkUser${users.getId()}">
If the state of the checkbox changes then updating the hidden field value. Which can be used in for msubmission.

Hidden Input Field causes potentially dangerous Request.Form value error

In my ASP.NET 1.1 application, I am compressing and replacing the hidden Viewstate variable with an alternate compressed value, stored in a hidden field called __VSTATE. This works well but on a few occasions, submitting a page causes the common "potentially dangerous Request.Form value ..." error.
I examined the __VSTATE value and nothing seems to be potentially dangerous. I was able to reproduce the error with a completely stripped down version of the page and __VSTATE value as shown below. Pressing the submit button causes the error. The page works fine if I change the value to "".
<%# Page Language="vb" AutoEventWireup="false" Codebehind="Dangerous.aspx.vb" Inherits="Dynalabs.Dangerous" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body MS_POSITIONING="FlowLayout">
<form id="Form1" method="post" runat="server">
<input type="hidden" id="__VSTATE" runat="server" value="Onw=" />
<asp:Button ID="btnSubmit" Runat="server" Text="Submit" />
</form>
</body>
</html>
Changing the field name to "MyHiddenWT" made no difference. Removing the runat="server" did stop the error but that just means that .NET only examines server side controls. I also tried some additional values and found that of the following:
"Anw=", "Bnw=", "Cnw=", ... "Nnw=", "Onw=", "Pnw=", ... "Znw=",
"Onw=" is the only one that causes the problem. Is the captial O being seen as an octal value somehow?
Can someone explain why this value is triggering the error message? I'm also looking for a solution but, please, do not tell me to remove page validation. That's the same as saying a car with bad brakes can be fixed by not driving the car.
Thank you in advance.
My first guess is that it looks like a "OnSomething=" javascript event declaration.
It's a little weird that only the capital O triggers the error, did you test on the lowercase o as well?
Can you try these: "OnClick=", "abc OnClick=", "onclick=", "abc onclick=", "anw=", "bnw=", ...
If "OnSomething=x" javascript is a problem, then simply adding another character to your values should do the trick. Maybe a simple 'v' should do.
<input type="hidden" id="__VSTATE" runat="server" value="vOnw=" />
And then on submit, you remove the extra character before decoding.
Or better yet, upgrade to 2.0.
You've got the essence of the reason. Here's the best link in a response I got from another site:
http://groups.google.com/group/microsoft.public.dotnet.framework.aspnet.security/browse_thread/thread/d91d89511401e979

Disable browser 'Save Password' functionality

One of the joys of working for a government healthcare agency is having to deal with all of the paranoia around dealing with PHI (Protected Health Information). Don't get me wrong, I'm all for doing everything possible to protect people's personal information (health, financial, surfing habits, etc.), but sometimes people get a little too jumpy.
Case in point: One of our state customers recently found out that the browser provides the handy feature to save your password. We all know that it has been there for a while and is completely optional and is up to the end user to decide whether or not it is a smart decision to use or not. However, there is a bit of an uproar at the moment and we are being demanded to find a way to disable that functionality for our site.
Question: Is there a way for a site to tell the browser not to offer to remember passwords? I've been around web development a long time but don't know that I have come across that before.
Any help is appreciated.
I'm not sure if it'll work in all browsers but you should try setting autocomplete="off" on the form.
<form id="loginForm" action="login.cgi" method="post" autocomplete="off">
The easiest and simplest way to disable Form and Password storage prompts and prevent form data from being cached in session history is to use the autocomplete form element attribute with value "off".
From https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion
Some minor research shows that this works in IE to but I'll leave no guarantees ;)
#Joseph: If it's a strict requirement to pass XHTML validation with the actual markup (don't know why it would be though) you could theoretically add this attribute with javascript afterwards but then users with js disabled (probably a neglectable amount of your userbase or zero if your site requires js) will still have their passwords saved.
Example with jQuery:
$('#loginForm').attr('autocomplete', 'off');
In addition to
autocomplete="off"
Use
readonly onfocus="this.removeAttribute('readonly');"
for the inputs that you do not want them to remember form data (username, password, etc.) as shown below:
<input type="text" name="UserName" autocomplete="off" readonly
onfocus="this.removeAttribute('readonly');" >
<input type="password" name="Password" autocomplete="off" readonly
onfocus="this.removeAttribute('readonly');" >
Tested on the latest versions of the major browsers i.e. Google Chrome, Mozilla Firefox, Microsoft Edge, etc. and works like a charm.
I had been struggling with this problem a while, with a unique twist to the problem. Privileged users couldn't have the saved passwords work for them, but normal users needed it. This meant privileged users had to log in twice, the second time enforcing no saved passwords.
With this requirement, the standard autocomplete="off" method doesn't work across all browsers, because the password may have been saved from the first login. A colleague found a solution to replace the password field when it was focused with a new password field, and then focus on the new password field (then hook up the same event handler). This worked (except it caused an infinite loop in IE6). Maybe there was a way around that, but it was causing me a migraine.
Finally, I tried to just have the username and password outside of the form. To my surprise, this worked! It worked on IE6, and current versions of Firefox and Chrome on Linux. I haven't tested it further, but I suspect it works in most if not all browsers (but it wouldn't surprise me if there was a browser out there that didn't care if there was no form).
Here is some sample code, along with some jQuery to get it to work:
<input type="text" id="username" name="username"/>
<input type="password" id="password" name="password"/>
<form id="theForm" action="/your/login" method="post">
<input type="hidden" id="hiddenUsername" name="username"/>
<input type="hidden" id="hiddenPassword" name="password"/>
<input type="submit" value="Login"/>
</form>
<script type="text/javascript" language="JavaScript">
$("#theForm").submit(function() {
$("#hiddenUsername").val($("#username").val());
$("#hiddenPassword").val($("#password").val());
});
$("#username,#password").keypress(function(e) {
if (e.which == 13) {
$("#theForm").submit();
}
});
</script>
Well, its a very old post, but still I will give my solution, which my team had been trying to achieve for long. We just added a new input type="password" field inside the form and wrapped it in div and made the div hidden. Made sure that this div is before the actual password input.
This worked for us and it didn't gave any Save Password option
Plunk - http://plnkr.co/edit/xmBR31NQMUgUhYHBiZSg?p=preview
HTML:
<form method="post" action="yoururl">
<div class="hidden">
<input type="password"/>
</div>
<input type="text" name="username" placeholder="username"/>
<input type="password" name="password" placeholder="password"/>
</form>
CSS:
.hidden {display:none;}
You can prevent the browser from matching the forms up by randomizing the name used for the password field on each show. Then the browser sees a password for the same the url, but can't be sure it's the same password. Maybe it's controlling something else.
Update: note that this should be in addition to using autocomplete or other tactics, not a replacement for them, for the reasons indicated by others.
Also note that this will only prevent the browser from auto-completing the password. It won't prevent it from storing the password in whatever level of arbitrary security the browser chooses to use.
The cleanest way is to use autocomplete="off" tag attribute but
Firefox does not properly obey it when you switch fields with Tab.
The only way you could stop this is to add a fake hidden password field which tricks the browser to populate the password there.
<input type="text" id="username" name="username"/>
<input type="password" id="prevent_autofill" autocomplete="off" style="display:none" tabindex="-1" />
<input type="password" id="password" autocomplete="off" name="password"/>
It is an ugly hack, because you change the browser behavior, which should be considered bad practice. Use it only if you really need it.
Note: this will effectively stop password autofill, because FF will "save" the value of #prevent_autofill (which is empty) and will try to populate any saved passwords there, as it always uses the first type="password" input it finds in DOM after the respective "username" input.
Use real two-factor authentication to avoid the sole dependency on passwords which might be stored in many more places than the user's browser cache.
I have tested that adding autocomplete="off" in form tag in all major browsers. In fact, Most of the peoples in US using IE8 so far.
IE8, IE9, IE10, Firefox, Safari are works fine.
Browser not asking "save password".
Also, previously saved username & password not populated.
Chrome & IE 11 not supporting the autocomplete="off" feature
FF supporting the autocomplete="off". but sometimes existing saved
credentials are populated.
Updated on June 11, 2014
Finally, below is a cross browser solution using javascript and it is working fine in all browsers.
Need to remove "form" tag in login form. After client side validation, put that credentials in hidden form and submit it.
Also, add two methods. one for validation "validateLogin()" and another for listening enter event while click enter in textbox/password/button "checkAndSubmit()". because now login form does not have a form tag, so enter event not working here.
HTML
<form id="HiddenLoginForm" action="" method="post">
<input type="hidden" name="username" id="hidden_username" />
<input type="hidden" name="password" id="hidden_password" />
</form>
Username: <input type="text" name="username" id="username" onKeyPress="return checkAndSubmit(event);" />
Password: <input type="text" name="password" id="password" onKeyPress="return checkAndSubmit(event);" />
<input type="button" value="submit" onClick="return validateAndLogin();" onKeyPress="return checkAndSubmit(event);" />
Javascript
//For validation- you can modify as you like
function validateAndLogin(){
var username = document.getElementById("username");
var password = document.getElementById("password");
if(username && username.value == ''){
alert("Please enter username!");
return false;
}
if(password && password.value == ''){
alert("Please enter password!");
return false;
}
document.getElementById("hidden_username").value = username.value;
document.getElementById("hidden_password").value = password.value;
document.getElementById("HiddenLoginForm").submit();
}
//For enter event
function checkAndSubmit(e) {
if (e.keyCode == 13) {
validateAndLogin();
}
}
Good luck!!!
Not really - the only thing you could realistically do is offer advice on the site; maybe, before their first time signing in, you could show them a form with information indicating that it is not recommended that they allow the browser to store the password.
Then the user will immediately follow the advice, write down the password on a post-it note and tape it to their monitor.
What I have been doing is a combination of autocomplete="off" and clearing password fields using a javascript / jQuery.
jQuery Example:
$(function() {
$('#PasswordEdit').attr("autocomplete", "off");
setTimeout('$("#PasswordEdit").val("");', 50);
});
By using setTimeout() you can wait for the browser to complete the field before you clear it, otherwise the browser will always autocomplete after you've clear the field.
if autocomplete="off" is not working...remove the form tag and use a div tag instead, then pass the form values using jquery to the server. This worked for me.
Because autocomplete="off" does not work for password fields, one must rely on javascript. Here's a simple solution based on answers found here.
Add the attribute data-password-autocomplete="off" to your password field:
<input type="password" data-password-autocomplete="off">
Include the following JS:
$(function(){
$('[data-password-autocomplete="off"]').each(function() {
$(this).prop('type', 'text');
$('<input type="password"/>').hide().insertBefore(this);
$(this).focus(function() {
$(this).prop('type', 'password');
});
});
});
This solution works for both Chrome and FF.
This is my html code for solution. It works for Chrome-Safari-Internet Explorer. I created new font which all characters seem as "●". Then I use this font for my password text. Note: My font name is "passwordsecretregular".
<style type="text/css">
#login_parola {
font-family: 'passwordsecretregular' !important;
-webkit-text-security: disc !important;
font-size: 22px !important;
}
</style>
<input type="text" class="w205 has-keyboard-alpha" name="login_parola" id="login_parola" onkeyup="checkCapsWarning(event)"
onfocus="checkCapsWarning(event)" onblur="removeCapsWarning()" onpaste="return false;" maxlength="32"/>
Just so people realise - the 'autocomplete' attribute works most of the time, but power users can get around it using a bookmarklet.
Having a browser save your passwords actually increases protection against keylogging, so possibly the safest option is to save passwords in the browser but protect them with a master password (at least in Firefox).
I have a work around, which may help.
You could make a custom font hack. So, make a custom font, with all the characters as a dot / circle / star for example. Use this as a custom font for your website. Check how to do this in inkscape: how to make your own font
Then on your log in form use:
<form autocomplete='off' ...>
<input type="text" name="email" ...>
<input type="text" name="password" class="password" autocomplete='off' ...>
<input type=submit>
</form>
Then add your css:
#font-face {
font-family: 'myCustomfont';
src: url('myCustomfont.eot');
src: url('myCustomfont?#iefix') format('embedded-opentype'),
url('myCustomfont.woff') format('woff'),
url('myCustomfont.ttf') format('truetype'),
url('myCustomfont.svg#myCustomfont') format('svg');
font-weight: normal;
font-style: normal;
}
.password {
font-family:'myCustomfont';
}
Pretty cross browser compatible. I have tried IE6+, FF, Safari and Chrome. Just make sure that the oet font that you convert does not get corrupted. Hope it helps?
The simplest way to solve this problem is to place INPUT fields outside the FORM tag and add two hidden fields inside the FORM tag. Then in a submit event listener before the form data gets submitted to server copy values from visible input to the invisible ones.
Here's an example (you can't run it here, since the form action is not set to a real login script):
<!doctype html>
<html>
<head>
<title>Login & Save password test</title>
<meta charset="utf-8">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
</head>
<body>
<!-- the following fields will show on page, but are not part of the form -->
<input class="username" type="text" placeholder="Username" />
<input class="password" type="password" placeholder="Password" />
<form id="loginForm" action="login.aspx" method="post">
<!-- thw following two fields are part of the form, but are not visible -->
<input name="username" id="username" type="hidden" />
<input name="password" id="password" type="hidden" />
<!-- standard submit button -->
<button type="submit">Login</button>
</form>
<script>
// attache a event listener which will get called just before the form data is sent to server
$('form').submit(function(ev) {
console.log('xxx');
// read the value from the visible INPUT and save it to invisible one
// ... so that it gets sent to the server
$('#username').val($('.username').val());
$('#password').val($('.password').val());
});
</script>
</body>
</html>
My js (jquery) workaround is to change password input type to text on form submit. The password could become visible for a second, so I also hide the input just before that. I would rather not use this for login forms, but it is useful (together with autocomplete="off") for example inside administration part of the website.
Try putting this inside a console (with jquery), before you submit the form.
$('form').submit(function(event) {
$(this).find('input[type=password]').css('visibility', 'hidden').attr('type', 'text');
});
Tested on Chrome 44.0.2403.157 (64-bit).
I tested lots of solutions. Dynamic password field name, multiple password fields (invisible for fake ones), changing input type from "text" to "password", autocomplete="off", autocomplete="new-password",... but nothing solved it with recent browser.
To get rid of password remember, I finally treated the password as input field, and "blur" the text typed.
It is less "safe" than a native password field since selecting the typed text would show it as clear text, but password is not remembered. It also depends on having Javascript activated.
You will have estimate the risk of using below proposal vs password remember option from navigator.
While password remember can be managed (disbaled per site) by the user, it's fine for a personal computer, not for a "public" or shared computer.
I my case it's for a ERP running on shared computers, so I'll give it a try to my solution below.
<input style="background-color: rgb(239, 179, 196); color: black; text-shadow: none;" name="password" size="10" maxlength="30" onfocus="this.value='';this.style.color='black'; this.style.textShadow='none';" onkeypress="this.style.color='transparent'; this.style.textShadow='1px 1px 6px green';" autocomplete="off" type="text">
Markus raised a great point. I decided to look up the autocomplete attribute and got the following:
The only downside to using this
attribute is that it is not standard
(it works in IE and Mozilla browsers),
and would cause XHTML validation to
fail. I think this is a case where
it's reasonable to break validation
however. (source)
So I would have to say that although it doesn't work 100% across the board it is handled in the major browsers so its a great solution.
The real problem is much deeper than just adding attributes to your HTML - this is common security concern, that's why people invented hardware keys and other crazy things for security.
Imagine you have autocomplete="off" perfectly working in all browsers. Would that help with security? Of course, no. Users will write down their passwords in textbooks, on stickers attached to their monitor where every office visitor can see them, save them to text files on the desktop and so on.
Generally, web application and web developer isn't responsible in any way for end-user security. End-users can protect themselves only. Ideally, they MUST keep all passwords in their head and use password reset functionality (or contact administrator) in case they forgot it. Otherwise there always will be a risk that password can be seen and stolen somehow.
So either you have some crazy security policy with hardware keys (like, some banks offer for Internet-banking which basically employs two-factor authentication) or NO SECURITY basically. Well, this is a bit over exaggerated of course. It's important to understand what are you trying to protect against:
Not authorised access. Simplest login form is enough basically. There sometimes additional measures taken like random security questions, CAPTCHAs, password hardening etc.
Credential sniffing. HTTPS is A MUST if people access your web application from public Wi-Fi hotspots etc. Mention that even having HTTPS, your users need to change their passwords regularly.
Insider attack. There are two many examples of such, starting from simple stealing of your passwords from browser or those that you have written down somewhere on the desk (does not require any IT skills) and ending with session forging and intercepting local network traffic (even encrypted) and further accessing web application just like it was another end-user.
In this particular post, I can see inadequate requirements put on developer which he will never be able to resolve due to the nature of the problem - end-user security. My subjective point is that developer should basically say NO and point on requirement problem rather than wasting time on such tasks, honestly. This does not absolutely make your system more secure, it will rather lead to the cases with stickers on monitors. Unfortunately, some bosses hear only what they want to hear. However, if I was you I would try to explain where the actual problem is coming from, and that autocomplete="off" would not resolve it unless it will force users to keep all their passwords exclusively in their head! Developer on his end cannot protect users completely, users need to know how to use system and at the same time do not expose their sensitive/secure information and this goes far beyond authentication.
I tried above autocomplete="off" and yet anything successful. if you are using angular js my recommendation is to go with button and the ng-click.
<button type="button" class="" ng-click="vm.login()" />
This already have a accepted answer im adding this if someone cant solve the problem with the accepted answer he can go with my mechanism.
Thanks for the question and the answers.
One way I know is to use (for instance) JavaScript to copy the value out of the password field before submitting the form.
The main problem with this is that the solution is tied to JavaScript.
Then again, if it can be tied to JavaScript you might as well hash the password on the client-side before sending a request to the server.
Facing the same HIPAA issue and found a relatively easy solution,
Create a hidden password field with the field name as an array.
<input type="password" name="password[]" style="display:none" />
Use the same array for the actual password field.
<input type="password" name="password[]" />
The browser (Chrome) may prompt you to "Save password" but regardless if the user selects save, the next time they login the password will auto-populate the hidden password field, the zero slot in the array, leaving the 1st slot blank.
I tried defining the array, such as "password[part2]" but it still remembered. I think it throws it off if it's an unindexed array because it has no choice but to drop it in the first spot.
Then you use your programming language of choice to access the array, PHP for example,
echo $_POST['password'][1];
Since most of the autocomplete suggestions, including the accepted answer, don't work in today's web browsers (i.e. web browser password managers ignore autocomplete), a more novel solution is to swap between password and text types and make the background color match the text color when the field is a plain text field, which continues to hide the password while being a real password field when the user (or a program like KeePass) is entering a password. Browsers don't ask to save passwords that are stored in plain text fields.
The advantage of this approach is that it allows for progressive enhancement and therefore doesn't require Javascript for a field to function as a normal password field (you could also start with a plain text field instead and apply the same approach but that's not really HIPAA PHI/PII-compliant). Nor does this approach depend on hidden forms/fields which might not necessarily be sent to the server (because they are hidden) and some of those tricks also don't work either in several modern browsers.
jQuery plugin:
https://github.com/cubiclesoft/php-flexforms-modules/blob/master/password-manager/jquery.stoppasswordmanager.js
Relevant source code from the above link:
(function($) {
$.fn.StopPasswordManager = function() {
return this.each(function() {
var $this = $(this);
$this.addClass('no-print');
$this.attr('data-background-color', $this.css('background-color'));
$this.css('background-color', $this.css('color'));
$this.attr('type', 'text');
$this.attr('autocomplete', 'off');
$this.focus(function() {
$this.attr('type', 'password');
$this.css('background-color', $this.attr('data-background-color'));
});
$this.blur(function() {
$this.css('background-color', $this.css('color'));
$this.attr('type', 'text');
$this[0].selectionStart = $this[0].selectionEnd;
});
$this.on('keydown', function(e) {
if (e.keyCode == 13)
{
$this.css('background-color', $this.css('color'));
$this.attr('type', 'text');
$this[0].selectionStart = $this[0].selectionEnd;
}
});
});
}
}(jQuery));
Demo:
https://barebonescms.com/demos/admin_pack/admin.php
Click "Add Entry" in the menu and then scroll to the bottom of the page to "Module: Stop Password Manager".
Disclaimer: While this approach works for sighted individuals, there might be issues with screen reader software. For example, a screen reader might read the user's password out loud because it sees a plain text field. There might also be other unforeseen consequences of using the above plugin. Altering built-in web browser functionality should be done sparingly with testing a wide variety of conditions and edge cases.
<input type="text" id="mPassword" required="required" title="Valid password required" autocomplete="off" list="autocompleteOff" readonly onfocus="this.removeAttribute('readonly');" style="text-security:disc; -webkit-text-security:disc;" oncopy="return false;" onpaste="return false;"/>
Is there a way for a site to tell the browser not to offer to remember passwords?
The website tells the browser that it is a password by using <input type="password">. So if you must do this from a website perspective then you would have to change that. (Obviously I don't recommend this).
The best solution would be to have the user configure their browser so it won't remember passwords.
If you do not want to trust the autocomplete flag, you can make sure that the user types in the box using the onchange event. The code below is a simple HTML form. The hidden form element password_edited starts out set to 0. When the value of password is changed, the JavaScript at the top (pw_edited function) changes the value to 1. When the button is pressed, it checks the valueenter code here before submitting the form. That way, even if the browser ignores you and autocompletes the field, the user cannot pass the login page without typing in the password field. Also, make sure to blank the password field when focus is set. Otherwise, you can add a character at the end, then go back and remove it to trick the system. I recommend adding the autocomplete="off" to password in addition, but this example shows how the backup code works.
<html>
<head>
<script>
function pw_edited() {
document.this_form.password_edited.value = 1;
}
function pw_blank() {
document.this_form.password.value = "";
}
function submitf() {
if(document.this_form.password_edited.value < 1) {
alert("Please Enter Your Password!");
}
else {
document.this_form.submit();
}
}
</script>
</head>
<body>
<form name="this_form" method="post" action="../../cgi-bin/yourscript.cgi?login">
<div style="padding-left:25px;">
<p>
<label>User:</label>
<input name="user_name" type="text" class="input" value="" size="30" maxlength="60">
</p>
<p>
<label>Password:</label>
<input name="password" type="password" class="input" size="20" value="" maxlength="50" onfocus="pw_blank();" onchange="pw_edited();">
</p>
<p>
<span id="error_msg"></span>
</p>
<p>
<input type="hidden" name="password_edited" value="0">
<input name="submitform" type="button" class="button" value="Login" onclick="return submitf();">
</p>
</div>
</form>
</body>
</html>
autocomplete="off" does not work for disabling the password manager in Firefox 31 and most likely not in some earlier versions, too.
Checkout the discussion at mozilla about this issue:
https://bugzilla.mozilla.org/show_bug.cgi?id=956906
We wanted to use a second password field to enter a one-time password generated by a token. Now we are using a text input instead of a password input. :-(
I was given a similar task to disable the auto-filling up of login name and passwords by browser, after lot of trial and errors i found the below solution to be optimal. Just add the below controls before your original controls.
<input type="text" style="display:none">
<input type="text" name="OriginalLoginTextBox">
<input type="password" style="display:none">
<input type="text" name="OriginalPasswordTextBox">
This is working fine for IE11 and Chrome 44.0.2403.107
autocomplete="off" works for most modern browsers, but another method I used that worked successfully with Epiphany (a WebKit-powered browser for GNOME) is to store a randomly generated prefix in session state (or a hidden field, I happened to have a suitable variable in session state already), and use this to alter the name of the fields. Epiphany still wants to save the password, but when going back to the form it won't populate the fields.

Resources