{"version":"https://jsonfeed.org/version/1","title":"Aaron Gustafson: Content tagged security","description":"The latest 20 posts and links tagged security.","home_page_url":"https://www.aaron-gustafson.com","feed_url":"https://www.aaron-gustafson.com/feeds/security.json","author":{"name":"Aaron Gustafson","url":"https://www.aaron-gustafson.com"},"icon":"https://www.aaron-gustafson.com/i/og-logo.png","favicon":"https://www.aaron-gustafson.com/favicon.png","expired": false,"items":[{"id":"https://www.aaron-gustafson.com/notebook/spellcheckers-exfiltrating-pii_-not-so-fast/","title":"✍🏻 Spellcheckers exfiltrating PII… not so fast","summary":"A recent post from the Otto JS research team highlighted how spellcheck services can inadvertently exfiltrate sensitive user data, including passwords, from your site. To be honest, I found the post a tad alarmist and lacking when it came to recommending solid protections. Consider this your no-nonsense guide to protecting your users’ sensitive information.","content_html":"
A recent post from the Otto JS research team highlighted how spellcheck services can inadvertently exfiltrate sensitive user data, including passwords, from your site. To be honest, I found the post a tad alarmist and lacking when it came to recommending solid protections. Consider this your no-nonsense guide to protecting your users’ sensitive information.
In their research, the Otto JS team found that Chrome and Edge each use their own web services to drive their spellchecking services. In Chrome’s case it seems to only be with their “advanced spellcheck” feature turned on. I was able to validate this behavior using Charles on macOS Monterey using the latest Chrome Stable and the latest Edge Canary. I did not see the same exfiltration happen with Safari or Firefox. I created a CodePen form with several fields to test different permutations of form field attributes and behaviors. What I am sharing, below, is a result of that testing.
In both Chrome and Edge, the information sent to their services is the text value itself, disconnected from any specific field name. Chrome also sends the user’s language, and country. Edge, which uses the Microsoft Editor service under the hood, also sends a bunch of licensing details and the user’s language.
<input type=\"password\"
id=\"password\"
name=\"password\">
Browsers do a lot to protect the contents of password fields already, so I wasn’t surprised to see that the contents of password fields are not passed to a spellcheck service.
If you are not using a true password field, however, the contents of that field are not protected in the same way. If you build a custom password control, you’re on the hook to replicate the entirety of the browser’s feature set when it comes to protecting user data. Unless you’re a glutton for punishment, you should probably just use the built-in password field instead.
As you’d hope, neither read-only fields nor disabled fields are exposed ot the service. This even holds true when you change the values of these fields programmatically or via DevTools.
I should note, however, that readonly
fields are send to the server when the form is submitted and their contents are editable via JavaScript and DevTools, so you should always assume readonly
fields are informational for the user only and never trust their contents on the server side. Fields that are marked disabled
, in contrast, are never sent to the server.
spellcheck
attribute<input id=\"no-spellcheck\"
name=\"no-spellcheck\"
spellcheck=\"false\">
The spellcheck
attribute can be applied to any element and setting it to “false” instructs browsers to turn off spellchecking services for its contents. The post from Otto JS showed this being used globally on the body
element, but that is overkill. It would be better to use the attribute on specific fields you want to protect, as shown above.
Edge has a neat feature in its password field implementation where it enables a user to toggle the visibility of the password within the control itself. When users show their password using that built-in functionality, no content is shared with the spellchecker. Not all browsers have this feature, however, which has led to JavaScript-based implementations that simply swap the “password” type
value for “text” to show the contents and then swap it back again to hide the contents. Here’s a quick & dirty example of what the toggle button’s event handler might look like:
function togglePassword(e) {
var $btn = e.target,
$field = $btn.parentNode.querySelector(\"input\"),
state = $field.type;
if ( $btn && $field ) {
if ( state == \"password\" ) {
$field.type = \"text\";
$btn.innerText = \"Hide\";
} else {
$field.type = \"password\";
$btn.innerText = \"Show\";
}
e.preventDefault();
e.stopPropagation();
}
}
The problem with this approach, when it comes to the spellchecker, is that the text field is considered fair game for checking. Its contents aren’t sent right away, but if the field receives focus or its value is changed in any way while in the “text” state, its contents are sent to the spellcheck service.
Protecting the field’s contents are fairly easy, however: turn off the spellchecker for that field, even in its “password” state.
<input type=\"password\"
id=\"password-show-nospellcheck\"
name=\"password-show-nospellcheck\"
spellcheck=\"false\">
With spellcheck="false"
in place, you can turn the field into a text field safely, without the contents being exposed to the spellcheck service.
HTML is a pretty powerful language and, when wielded properly, can be an excellent tool for protecting user data, provided we use it properly. And know that you know how to protect your users’ sensitive data, minimize this tab and start filing those pull requests…
","url":"https://www.aaron-gustafson.com/notebook/spellcheckers-exfiltrating-pii_-not-so-fast/","tags":["browsers","forms","HTML","security","privacy"],"image":"https://www.aaron-gustafson.com/i/posts/2022-09-19/hero.jpg","date_published":"2022-09-19T21:34:51Z"},{"id":"https://www.aaron-gustafson.com/notebook/links/83416-uk-researcher-says-one-line-of-code-caused-ticketmaster-breach/","title":"🔗 UK researcher says one line of code caused Ticketmaster breach","content_html":"Third party code, people… third party code.
He pointed out that while Inbenta had provided Ticketmaster a customised JavaScript one-liner, the ticketing company had placed this chatbot code on its payment processing website without informing Inbenta it had done so.“This means that Inbenta’s webserver was placed in the middle of all Ticketmaster credit card transactions, with the ability to execute JavaScript code in customer browsers,” Beaumont said.
Sigh.
","url":"https://www.aaron-gustafson.com/notebook/links/83416-uk-researcher-says-one-line-of-code-caused-ticketmaster-breach/","external_url":"https://www.itwire.com/security/83416-uk-researcher-says-one-line-of-code-caused-ticketmaster-breach.html","tags":["security","JavaScript"],"image":"https://itwire.com/media/k2/items/cache/c68b5f6e7e74252721c5ad209fb798bc_XS.jpg","date_published":"2018-07-03T23:38:27Z"},{"id":"https://www.aaron-gustafson.com/notebook/links/mobile-devs-making-the-same-security-mistakes-web-devs-made-in-the-early-2000s/","title":"🔗 Mobile Devs Making the Same Security Mistakes Web Devs Made in the Early 2000s","content_html":"Anyone who’s seen one of my forms talks knows how adamant I am about this: you can never trust the client! Doesn’t matter if that client is a web browser or your mobile app.
","url":"https://www.aaron-gustafson.com/notebook/links/mobile-devs-making-the-same-security-mistakes-web-devs-made-in-the-early-2000s/","external_url":"https://www.bleepingcomputer.com/news/security/mobile-devs-making-the-same-security-mistakes-web-devs-made-in-the-early-2000s/","tags":["mobile","security"],"image":"https://www.bleepstatic.com/content/posts/2018/06/04/phone-apps.jpg","date_published":"2018-06-27T20:11:03Z"},{"id":"https://www.aaron-gustafson.com/notebook/moved-to-https/","title":"✍🏻 Moved to HTTPS","summary":"So, as much as it pains me to abandon good old fashioned HTTP, I’ve decided to lock things down a bit.","content_html":"I’ve been complaining about “man in the middle” attacks brought on by internet service providers a bunch over the last year. The only way to keep uninvited third parties from injecting JavaScript and more—potentially screwing up your page—is to move to HTTPS. So, as much as it pains me to abandon good old fashioned HTTP, I’ve decided to lock things down a bit.
I was using Github to host my site as a Github page. It worked really well given this is a static site, but you can’t run Github-hosted sites under HTTPS unless you go with their *.github.io
domain name (they have a wildcard certificate for that domain). There’s been a ton of interest in Github allowing custom cert installation, but no movement yet, so… onward!1
I opted to move to DigitalOcean since my consultancy recently relocated all of its sites there in a mass exodus from MediaTemple. Migrating the site was as simple as setting up the DigitalOcean server as a new “live” remote
on my local git install and pushing it up there. Since it’s a static site, I didn’t have to worry too much about the server config. Apache is really great at hosting static files.
With the contents in place, I went through the rather convoluted process of getting SSL set up following the instructions from DigitalOcean. I opted for the free StartSSL certificate to begin with (a rather convoluted process, but we got there in the end) and then flipped the DNS records to point to the new box. Given that the StartSSL certificate needs to be renewed every 30 days, I may opt for a paid certificate in the not too distant future.
Once the DNS propagated, I had to go back and button up a few scripts that were requesting non-HTTPS content. I also had to tweak my Jekyll plugins and Rake tasks to include the legacy “http://” URLs when querying for webmentions and the like (since I didn’t want to lose those references). I also updated the Apache’s VirtualHost
configuration for the non-secure site to make all traffic redirect:
Redirect permanent / https://www.aaron-gustafson.com/
All in all, it was a relatively painless migration. Admittedly, the initial re-build of the site (after updating the Rake tasks) did re-submit all of the webmentions I’d previously sent in order to provide the new address. If I referenced you a bunch in the past, I apologize for the flood of traffic, but it had to be done.
Anyway, so now this site is running under HTTPS. If you encounter any issues, please let me know. And if you want to read a really good account of migrating a site to HTTPS, you should definitely read Jeremy Keith’s step-by-step guide.
It’s worth noting that the source of the site will remain on Github for the forseeable future. ↩︎