{"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/a-web-component-for-obfuscating-form-fields/","title":"✍🏻 A Web Component for Obfuscating Form Fields","summary":"There’s no standard way to make a field readable while editing but obfuscated at rest. The <code>form-obfuscator</code> web component fills that gap, giving you control over how sensitive data appears when fields aren't focused.","content_html":"<p>We have the password reveal pattern for passwords, but what about other sensitive fields that need to be readable while editing and obfuscated while at rest? The <code>form-obfuscator</code> web component does exactly that.</p>\n<h2 id=\"basic-usage\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#basic-usage\" aria-hidden=\"true\">#</a> Basic usage</h2>\n<p>Wrap any text field in the component and it will automatically obfuscate the value when the field loses focus:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>form-obfuscator</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>label</span> <span class=\"token attr-name\">for</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>secret-key-1<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>What was your first pet’s name?<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>label</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">type</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>text<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">id</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>secret-key-1<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>secret-key-1<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>form-obfuscator</span><span class=\"token punctuation\">></span></span></code></pre>\n<p>When users click into the field, they see the actual value. When they click away, it’s replaced with asterisks (*). The real value is preserved in a hidden field for form submission.</p>\n<h2 id=\"custom-obfuscation-characters\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#custom-obfuscation-characters\" aria-hidden=\"true\">#</a> Custom obfuscation characters</h2>\n<p>If you don’t like asterisks, you can specify any character you like:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>form-obfuscator</span> <span class=\"token attr-name\">character</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>•<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>label</span> <span class=\"token attr-name\">for</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>account<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>Account Number<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>label</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">type</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>text<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">id</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>account<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>account<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>form-obfuscator</span><span class=\"token punctuation\">></span></span></code></pre>\n<p>Or get creative:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>form-obfuscator</span> <span class=\"token attr-name\">character</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>🤐<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>label</span> <span class=\"token attr-name\">for</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>ssn<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>Social Security Number<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>label</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">type</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>text<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">id</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>ssn<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>ssn<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>form-obfuscator</span><span class=\"token punctuation\">></span></span></code></pre>\n<h2 id=\"pattern-based-obfuscation\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#pattern-based-obfuscation\" aria-hidden=\"true\">#</a> Pattern-based obfuscation</h2>\n<p>Sometimes you want to show part of the value while hiding the rest. The <code>pattern</code> attribute lets you specify which characters to keep visible:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>form-obfuscator</span> <span class=\"token attr-name\">pattern</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>\\d{4}$<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>label</span> <span class=\"token attr-name\">for</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>ssn<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>Social Security Number<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>label</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">type</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>text<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">id</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>ssn<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>ssn<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>form-obfuscator</span><span class=\"token punctuation\">></span></span></code></pre>\n<p>This keeps the last four digits visible while replacing everything else with your obfuscation character. Perfect for Social Security Numbers, credit cards, or phone numbers where showing the last few digits helps users confirm they’ve entered the right value.</p>\n<h2 id=\"limiting-displayed-characters\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#limiting-displayed-characters\" aria-hidden=\"true\">#</a> Limiting displayed characters</h2>\n<p>Use the <code>maxlength</code> attribute to cap how many characters appear when obfuscated:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>form-obfuscator</span> <span class=\"token attr-name\">maxlength</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>4<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>label</span> <span class=\"token attr-name\">for</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>password<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>Password<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>label</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">type</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>text<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">id</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>password<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>password<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>form-obfuscator</span><span class=\"token punctuation\">></span></span></code></pre>\n<p>Even if the user enters a 20-character value, only four asterisks will be displayed when the field is obfuscated. This prevents giving away information about the length of the information entered.</p>\n<h2 id=\"custom-replacement-functions\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#custom-replacement-functions\" aria-hidden=\"true\">#</a> Custom replacement functions</h2>\n<p>For complete control, you can provide a JavaScript function via the <code>replacer</code> attribute:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>script</span><span class=\"token punctuation\">></span></span><span class=\"token script\"><span class=\"token language-javascript\">\n  window<span class=\"token punctuation\">.</span><span class=\"token function-variable function\">emailReplacer</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">var</span> username <span class=\"token operator\">=</span> arguments<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">var</span> domain <span class=\"token operator\">=</span> arguments<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">2</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> username<span class=\"token punctuation\">.</span><span class=\"token function\">replace</span><span class=\"token punctuation\">(</span><span class=\"token regex\"><span class=\"token regex-delimiter\">/</span><span class=\"token regex-source language-regex\">.</span><span class=\"token regex-delimiter\">/</span><span class=\"token regex-flags\">g</span></span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"*\"</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> domain<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n</span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>script</span><span class=\"token punctuation\">></span></span>\n\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>form-obfuscator</span>\n  <span class=\"token attr-name\">pattern</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>^(.*?)(@.+)$<span class=\"token punctuation\">\"</span></span>\n  <span class=\"token attr-name\">replacer</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>return emailReplacer(arguments)<span class=\"token punctuation\">\"</span></span>\n<span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>label</span> <span class=\"token attr-name\">for</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>email<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>Email Address<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>label</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">type</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>text<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">id</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>email<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>email<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">value</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>user@example.com<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>form-obfuscator</span><span class=\"token punctuation\">></span></span></code></pre>\n<p>This example uses a pattern to separate the username from the domain, then obfuscates only the username portion, leaving <code>@example.com</code> visible.</p>\n<p>Here’s another practical example for credit cards:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>script</span><span class=\"token punctuation\">></span></span><span class=\"token script\"><span class=\"token language-javascript\">\n  <span class=\"token keyword\">function</span> <span class=\"token function\">cardNumberReplacer</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">var</span> beginning <span class=\"token operator\">=</span> arguments<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">var</span> final_digits <span class=\"token operator\">=</span> arguments<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">2</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> beginning<span class=\"token punctuation\">.</span><span class=\"token function\">replace</span><span class=\"token punctuation\">(</span><span class=\"token regex\"><span class=\"token regex-delimiter\">/</span><span class=\"token regex-source language-regex\">\\d</span><span class=\"token regex-delimiter\">/</span><span class=\"token regex-flags\">g</span></span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"*\"</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> final_digits<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n</span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>script</span><span class=\"token punctuation\">></span></span>\n\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>form-obfuscator</span>\n  <span class=\"token attr-name\">pattern</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>^((?:[\\d]+\\-)+)(\\d+)$<span class=\"token punctuation\">\"</span></span>\n  <span class=\"token attr-name\">replacer</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>return cardNumberReplacer(arguments)<span class=\"token punctuation\">\"</span></span>\n<span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>label</span> <span class=\"token attr-name\">for</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>cc<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>Credit Card<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>label</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">type</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>text<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">id</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>cc<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>cc<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">value</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>1234-5678-9012-3456<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>form-obfuscator</span><span class=\"token punctuation\">></span></span></code></pre>\n<p>This displays as <code>****-****-****-3456</code>, showing only the last group of digits.</p>\n<h2 id=\"combining-attributes\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#combining-attributes\" aria-hidden=\"true\">#</a> Combining attributes</h2>\n<p>You can combine these attributes for sophisticated obfuscation patterns:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>form-obfuscator</span> <span class=\"token attr-name\">pattern</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>\\d{4}$<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">character</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>•<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">maxlength</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>16<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>label</span> <span class=\"token attr-name\">for</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>card<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>Credit Card<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>label</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">type</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>text<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">id</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>card<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>card<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>form-obfuscator</span><span class=\"token punctuation\">></span></span></code></pre>\n<p>This keeps the last 4 digits visible, uses bullets for obfuscation, and limits the display to 16 characters total.</p>\n<h2 id=\"event-handling\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#event-handling\" aria-hidden=\"true\">#</a> Event handling</h2>\n<p>The component dispatches custom events when values are hidden or revealed:</p>\n<pre class=\"language-javascript\" tabindex=\"0\"><code class=\"language-javascript\"><span class=\"token keyword\">const</span> obfuscator <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">querySelector</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"form-obfuscator\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nobfuscator<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"form-obfuscator:hide\"</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Field obfuscated:\"</span><span class=\"token punctuation\">,</span> e<span class=\"token punctuation\">.</span>detail<span class=\"token punctuation\">.</span>field<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nobfuscator<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"form-obfuscator:reveal\"</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Field revealed:\"</span><span class=\"token punctuation\">,</span> e<span class=\"token punctuation\">.</span>detail<span class=\"token punctuation\">.</span>field<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre>\n<p>You can access both the visible field and the hidden field through <code>event.detail.field</code> and <code>event.detail.hidden</code> respectively.</p>\n<h2 id=\"how-it-works\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#how-it-works\" aria-hidden=\"true\">#</a> How it works</h2>\n<p>The component creates a hidden <code>input</code> field to store the actual value for form submission. When the visible field loses focus, it:</p>\n<ol>\n<li>Copies the current value to the hidden field</li>\n<li>Applies your obfuscation rules to create the display value</li>\n<li>Updates the visible field with the obfuscated value</li>\n<li>Dispatches the <code>form-obfuscator:hide</code> event</li>\n</ol>\n<p>When the field gains focus, it:</p>\n<ol>\n<li>Restores the real value from the hidden field</li>\n<li>Updates the visible field</li>\n<li>Dispatches the <code>form-obfuscator:reveal</code> event</li>\n</ol>\n<p>The source order ensures the hidden field is the one that gets submitted with the form.</p>\n<h2 id=\"progressive-enhancement\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#progressive-enhancement\" aria-hidden=\"true\">#</a> Progressive enhancement</h2>\n<p>The component makes no assumptions about your markup—it works with any text-style <code>input</code> element. If JavaScript fails to load, the field behaves like a normal <code>input</code>, which is exactly what you want. Users can still enter and submit values; they just won’t get the obfuscation behavior.</p>\n<h2 id=\"demo\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#demo\" aria-hidden=\"true\">#</a> Demo</h2>\n<p>I’ve created <a href=\"https://aarongustafson.github.io/form-obfuscator/demo/\">a comprehensive demo page showing the various configuration options</a> over on GitHub:</p>\n<figure class=\"video-embed video-embed--4x3\">\n<fullscreen-control class=\"talk__slides__embed video-embed__video\">\n<iframe src=\"https://aarongustafson.github.io/form-obfuscator/demo/\" class=\"talk__slides__embed video-embed__video\" frameborder=\"0\"></iframe>\n</fullscreen-control>\n</figure>\n<h2 id=\"grab-it\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#grab-it\" aria-hidden=\"true\">#</a> Grab it</h2>\n<p>Check out the full project over on <a href=\"https://github.com/aarongustafson/form-obfuscator\">GitHub</a> or install via <code>npm</code>:</p>\n<pre class=\"language-bash\" tabindex=\"0\"><code class=\"language-bash\"><span class=\"token function\">npm</span> <span class=\"token function\">install</span> @aarongustafson/form-obfuscator</code></pre>\n<p>Import and use:</p>\n<pre class=\"language-javascript\" tabindex=\"0\"><code class=\"language-javascript\"><span class=\"token keyword\">import</span> <span class=\"token string\">\"@aarongustafson/form-obfuscator\"</span><span class=\"token punctuation\">;</span></code></pre>\n<p>No dependencies, just a straightforward way to add field obfuscation to your forms.</p>\n","social_text":"Need to obfuscate form field values when they’re not being edited? Here’s a web component for that.","url":"https://www.aaron-gustafson.com/notebook/a-web-component-for-obfuscating-form-fields/","tags":["forms","HTML","JavaScript","progressive enhancement","web components","web forms","security"],"date_published":"2025-12-06T20:03:47Z"},{"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":"<p>A recent post from the <a href=\"https://www.otto-js.com\">Otto JS</a> research team highlighted <a href=\"https://www.otto-js.com/news/article/chrome-and-edge-enhanced-spellcheck-features-expose-pii-even-your-passwords\">how spellcheck services can inadvertently exfiltrate sensitive user data, including passwords</a>, 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.</p>\n<h2 id=\"background\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#background\" aria-hidden=\"true\">#</a> Background</h2>\n<p>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 href=\"https://codepen.io/aarongustafson/pen/gOzWNgM\">a CodePen form with several fields to test different permutations of form field attributes and behaviors</a>. What I am sharing, below, is a result of that testing.</p>\n<h2 id=\"what-gets-sent%3F\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#what-gets-sent%3F\" aria-hidden=\"true\">#</a> What gets sent?</h2>\n<p>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.</p>\n<h2 id=\"password-fields-are-safe\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#password-fields-are-safe\" aria-hidden=\"true\">#</a> Password fields are safe</h2>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">type</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>password<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">id</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>password<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>password<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span></code></pre>\n<p>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 <strong>not</strong> passed to a spellcheck service.</p>\n<p>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.</p>\n<h2 id=\"fields-marked-readonly-and-disabled-are-not-exposed\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#fields-marked-readonly-and-disabled-are-not-exposed\" aria-hidden=\"true\">#</a> Fields marked readonly and disabled are not exposed</h2>\n<p>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.</p>\n<p>I should note, however, that <code>readonly</code> fields <em>are</em> send to the server when the form is submitted and their contents are editable via JavaScript and DevTools, so you should always assume <code>readonly</code> fields are informational for the user only and never trust their contents on the server side. Fields that are marked <code>disabled</code>, in contrast, are never sent to the server.</p>\n<h2 id=\"you-can-protect-interactive-fields-with-the-spellcheck-attribute\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#you-can-protect-interactive-fields-with-the-spellcheck-attribute\" aria-hidden=\"true\">#</a> You can protect interactive fields with the <code>spellcheck</code> attribute</h2>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">id</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>no-spellcheck<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>no-spellcheck<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">spellcheck</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>false<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span></code></pre>\n<p>The <code>spellcheck</code> 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 <code>body</code> element, but that is overkill. It would be better to use the attribute on specific fields you want to protect, as shown above.</p>\n<h2 id=\"don%E2%80%98t-forget-about-password-controls-that-support-show%2Fhide\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#don%E2%80%98t-forget-about-password-controls-that-support-show%2Fhide\" aria-hidden=\"true\">#</a> Don‘t forget about password controls that support show/hide</h2>\n<p>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” <code>type</code> value for “text” to show the contents and then swap it back again to hide the contents. Here’s a quick &amp; dirty example of what the toggle button’s event handler might look like:</p>\n<pre class=\"language-js\" tabindex=\"0\"><code class=\"language-js\"><span class=\"token keyword\">function</span> <span class=\"token function\">togglePassword</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">var</span> $btn <span class=\"token operator\">=</span> e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">,</span>\n    $field <span class=\"token operator\">=</span> $btn<span class=\"token punctuation\">.</span>parentNode<span class=\"token punctuation\">.</span><span class=\"token function\">querySelector</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"input\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    state <span class=\"token operator\">=</span> $field<span class=\"token punctuation\">.</span>type<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>$btn <span class=\"token operator\">&amp;&amp;</span> $field<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>state <span class=\"token operator\">==</span> <span class=\"token string\">\"password\"</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      $field<span class=\"token punctuation\">.</span>type <span class=\"token operator\">=</span> <span class=\"token string\">\"text\"</span><span class=\"token punctuation\">;</span>\n      $btn<span class=\"token punctuation\">.</span>innerText <span class=\"token operator\">=</span> <span class=\"token string\">\"Hide\"</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n      $field<span class=\"token punctuation\">.</span>type <span class=\"token operator\">=</span> <span class=\"token string\">\"password\"</span><span class=\"token punctuation\">;</span>\n      $btn<span class=\"token punctuation\">.</span>innerText <span class=\"token operator\">=</span> <span class=\"token string\">\"Show\"</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    e<span class=\"token punctuation\">.</span><span class=\"token function\">preventDefault</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    e<span class=\"token punctuation\">.</span><span class=\"token function\">stopPropagation</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre>\n<p>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.</p>\n<p>Protecting the field’s contents are fairly easy, however: turn off the spellchecker for that field, even in its “password” state.</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span>\n  <span class=\"token attr-name\">type</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>password<span class=\"token punctuation\">\"</span></span>\n  <span class=\"token attr-name\">id</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>password-show-nospellcheck<span class=\"token punctuation\">\"</span></span>\n  <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>password-show-nospellcheck<span class=\"token punctuation\">\"</span></span>\n  <span class=\"token attr-name\">spellcheck</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>false<span class=\"token punctuation\">\"</span></span>\n<span class=\"token punctuation\">/></span></span></code></pre>\n<p>With <code>spellcheck=&quot;false&quot;</code> in place, you can turn the field into a text field safely, without the contents being exposed to the spellcheck service.</p>\n<hr>\n<p>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…</p>\n","social_text":"A collection of ways you can keep sensitive user data protected from accidental exfiltration.","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":"<p>Third party code, people… third party code.</p>\n<blockquote>\n<p>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.\n“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.</p>\n</blockquote>\n<p>Sigh.</p>\n","social_text":"Third party code, people… third party code: UK researcher says one line of code caused Ticketmaster breach","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":"<p>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.</p>\n","social_text":"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":"<p>I’ve been complaining about <a href=\"https://www.aaron-gustafson.com/notebook/more-proof-we-dont-control-our-web-pages/\">“man in the middle” attacks brought on by internet service providers</a> 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.</p>\n<p>I was using <a href=\"https://github.com/\">Github</a> to host my site as a <a href=\"https://pages.github.com/\">Github page</a>. 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 <code>*.github.io</code> domain name (they have a <a href=\"https://en.wikipedia.org/wiki/Wildcard_certificate\">wildcard certificate</a> for that domain). There’s been <a href=\"https://github.com/isaacs/github/issues/156\">a ton of interest in Github allowing custom cert installation, but no movement yet</a>, so… <i>onward!</i><sup class=\"footnote-ref\"><a href=\"#fn1\" id=\"fnref1\">1</a></sup></p>\n<p>I opted to move to <a href=\"https://www.digitalocean.com/?refcode=5270a681c6fe\">DigitalOcean</a> since <a href=\"http://easy-designs.net\">my consultancy</a> recently relocated all of its sites there in a mass exodus from MediaTemple. Migrating the site was as simple as <a href=\"https://www.digitalocean.com/community/tutorials/how-to-set-up-automatic-deployment-with-git-with-a-vps\">setting up the DigitalOcean server as a new “live” <code>remote</code> on my local git install</a> 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.</p>\n<p>With the contents in place, I went through <a href=\"https://www.digitalocean.com/community/tutorials/how-to-set-up-apache-with-a-free-signed-ssl-certificate-on-a-vps\">the rather convoluted process of getting SSL set up following the instructions from DigitalOcean</a>. I opted for the free <a href=\"http://www.startssl.com/\">StartSSL</a> 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.</p>\n<p>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 <code>VirtualHost</code> configuration for the non-secure site to make all traffic redirect:</p>\n<p>Redirect permanent / <a href=\"https://www.aaron-gustafson.com/\">https://www.aaron-gustafson.com/</a></p>\n<p>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.</p>\n<p>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 <a href=\"https://adactio.com/articles/7435\">read Jeremy Keith’s step-by-step guide</a>.</p>\n<hr class=\"footnotes-sep\">\n<section class=\"footnotes\">\n<h4 class=\"hidden\">Footnotes</h4>\n<ol class=\"footnotes-list\">\n<li id=\"fn1\" class=\"footnote-item\"><p>It’s worth noting that <a href=\"https://github.com/aarongustafson/aaron-gustafson.com/tree/main/\">the source of the site</a> will remain on Github for the forseeable future. <a href=\"#fnref1\" class=\"footnote-backref\">↩︎</a></p>\n</li>\n</ol>\n</section>\n","url":"https://www.aaron-gustafson.com/notebook/moved-to-https/","tags":["web design","security","this site"],"date_published":"2015-09-03T20:06:03Z"}]}