The curious case of hidden form fields changing their value....

So today I was looking into an odd issue our CEO experienced using a website. He would get a password reset email and upon following the link and entering a new password it would fail to change with a cryptic message.

I said I'd have a quick look and see what I could see. I signed up and triggered a password reset and found no issue. I was using Chrome and assumed he had but it turns out he was using Safari on his Mac not Chrome. So I loaded up Safari on my Mac and used my link to again find no issue.

To be thorough I asked him to send me his link, in Chrome no issue however this time in Safari I hit the issue. My first thought led me to then check what was posted to the server and sure enough in Chrome I could see an encoded access token sent but in Safari I saw my email address sent. I tried this on my CEO's machine and his machine posted his email address, it looked like Safari was autofilling hidden form fields as well as visible ones!

This is crazy!

So I performed a quick Google... Oh dear oh dear ... Now it seems Chrome and the others have fixed this but Safari hasn't. So avoiding the elephant in the room regarding Safari's data leak I next wondered why it would only happen on some links (like his) and not mine.

The difference it turns out is that my token ended in = where as his was a number, the token appeared to be base64 encoded. So Safari was only autofiling if the field contained alphanumerics and the field name was like email, userid etc.

Following finding this issue it made me want to find out what we could do to ensure our applications couldn't experience this issue, again it appears for hidden fields with names containing specific names, (email, userid, username, etc...) so it's scope is limited but for users affected it means they would be stuck with no obvious reason why.

It turns out the easiest way is to set the hidden field to be readonly, this stops Safari from auto filling it and allows the value to be posted back to the server.

So in HTML:
<input type="hidden" name="Model.UserID" value="1236712638768" readonly />

OR in Razor :
@Html.HiddenFor(m => m.UserID, new { @readonly="readonly"})

Note for Razor you need to prefix readonly with an @ due to readonly being a reserved word.

Now time to find out how many hidden form fields we have that need this applying..

A horrible issue but fortunately fixing it is fairly simple :)


Popular posts from this blog

WebUSB - An unexpected update...

Can you use BuildRoot with Windows Subsystem for Linux......

DotNet CLI , private NuGet feeds and Linux...