views:

71

answers:

5

We have some error reporting code that, when an unhandled exception occurs, we send everything over in an email to our groups. This is great except if an unhandled exception occurs on a page with a password field then it's sent over as plain text.

Is there a way to iterate through Request.Form and figure out which item(s) are passwords? This is done at a low level so we can't look for specific controls.

Naturally, we could check to see what type the input box is but I'm not sure if that's the cleanest way. Advice?

A: 

The cleanest way is to check the type attribute of the input element.

The HTML5 specification has this to say about input type=password:

The input element with a type attribute whose value is "password" represents a one-line plain-text edit control for entering a password.

Data type: Text with no line breaks (sensitive information)
Control type: Text field that obscures data entry

This is a mandatory requirement from all User Agent implmentations, and it has been so since HTML 2. So this is indeed the cleanest way to do what you want.

If you want to do it on the client side (you talked about sending the data to the server) then it is relatively easy:

function hidePasswords() {
    var inputs = document.getElementsByTagName('input');
    for (var i = 0; i < inputs.length; ++i)
        if (inputs[i].type == 'password') input[i].value = '*****';
}
Roy Sharon
Erm, I know the input type would be of password. How, exactly, can you check for that in ASP.Net is what I'm asking. As far as I know you can't access the input elements unless they have a runat=server set and I can't guarantee every page that uses this logic does that.
Kris
I saw your edit. Not really sure how hiding them on the client side would be helpful; you'd never receive the password on the backend unless you sent it via AJAX.
Kris
Oops, I edited my answer above and added an example how to do it on the client side at the same time you were adding your comment.Unless you are using some kind of HTTP channel security, like HTTPS, the password will be sent unencrypted always, whether you have an error or not. Am I misunderstanding something?
Roy Sharon
If you can detect the error condition on the client side, then you can call the password hiding function upon submit, and only then do the submit.
Roy Sharon
Yes. We have error handling that sends ALL Request.Form values over email but if an unexpected error occurs on a page with a password field we, inadvertently, sent the password in clear-text via email.I'm looking for a way to hide the value of all input types of password but I do not see a way to do that. Since this is used by hundreds of legacy pages, I can't go back and update all of them to use <input type="password" runat="server" /> or an actual, password control so I'm trying to figure out if there is another way to figure out what is an input of password in ASP.Net.
Kris
We can't check for unexpected exceptions on the client side.
Kris
A: 

As Jerome already pointed out in the comments, just keep track of the names of your password input fields and filter them before sending the error/exception report. This is the best solution as the type of the input field is not submitted.

Gumbo
+1  A: 

Use a whitelist of field names that you want to email.

There could be hundreds of field names that get POSTed to your server. And password isn't the only field that is sensitive. Depending on your application, there could be other things that should be treated with a little respect.

So, make a list of field names that will assist in you in debugging. These are typically unique identifiers / database keys and such. If you have any parameter names in this list, you can include it in the email.

sri
This appears to be only way to resolve this =/I was hoping for a way to determine input type in the code behind.
Kris
@Kris - You can't. The type of the field isn't sent to the server in the HTTP request. Its either a blacklist (don't send password or pwd or PASSWORD); or a whitelist (only send UserID and ProjectID and SomeOtherProjectSpecificID)... I personally prefer the whitelist because it is safer.
sri
A: 

A few solutions, though I'm not sure how bright any of them is:

1) Maintain in the page a List of input control IDs that are passwords, pass this list to the exception handler with the expectation to ignore these fields.

2) Keep a resource file in the website that lists a page name, a field id and have the exception handler check against this resource file (may not work if the exception is related to the ResourceManager)

3) Keep a database table as with idea 2. Same problems exist.

Joel Etherton
+1  A: 

I've suggested a different solution earlier, but I thought you were going to handle this on the client side. Following your comments I now understand that you need to take care of this on the server side. There may be a way for you to do it, which is not really elegant, but it should work:

Add to all pages a script that collects all password field names into a new client-generated field, like so:

function collectPasswordFields() {
    var inputs = document.getElementsByTagName('input'), list = [];
    for (var i = 0; i < inputs.length; ++i)
        if (inputs[i].type == 'password') list.push(inputs[i].name);
    var field = document.createElement('input');
    field.name = '__password_fields';
    field.value = list.join(',');
    document.getElementsByTagName('form')[0].appendChild(field);
}

Then intercept the additional field in the server-side error handler, and remove the named fields from the email.

Can something like this work for you?

Roy Sharon
That's pretty clever. You're right, not elegant but interesting. Unfortunately it wouldn't work out for many of our legacy pages but pretty nifty.
Kris