<h2class="post-title"><ahref="/blog/post/2019-01-02-adding-autocomplete-to-gophish/">Adding Autocomplete to Gophish</a></h2>
</header>
<sectionclass="post-excerpt">
<p>Gophish provides powerful template tags making it easy to create customized emails and landing pages. Unfortunately, I've had multiple issues file that are the result of incorrect tags being used.
This post describes how I implemented autocomplete for template tags within the Gophish editor, making it easier to use tags reliably and effectively. <aclass="read-more"href="/blog/post/2019-01-02-adding-autocomplete-to-gophish/">»</a></p>
<description>Gophish provides powerful template tags making it easy to create customized emails and landing pages. Sometimes, however, it can be difficult to remember the exact syntax and what template tags are supported.
I&rsquo;ve had multiple issues filed that are the result of incorrect tags being used. Generally, the crash looks something like this:
worker.go:90: template: html_template:6: function &quot;Name&quot; not defined panic: runtime error: invalid memory address or nil pointer dereference [recovered] panic: runtime error: invalid memory address or nil pointer dereference [signal 0xb code=0x1 addr=0x10 pc=0x61a4a5] The error from template suggests that a certain function, Name wasn’t defined.</description>
<title>Adding Autocomplete to Gophish · Gophish - Blog</title>
<metaname="description"content="Gophish provides powerful template tags making it easy to create customized emails and landing pages. Sometimes, however, it can be difficult to remember the ex"/>
<p>Gophish provides powerful template tags making it easy to create customized emails and landing pages. Sometimes, however, it can be difficult to remember the exact syntax and what template tags are supported.</p>
<p>I’ve had <ahref="https://github.com/gophish/gophish/search?q=template+crash&unscoped_q=template+crash&type=Issues">multiple issues filed</a> that are the result of incorrect tags being used. Generally, the crash looks something like this:</p>
<pre><code>worker.go:90: template: html_template:6: function "Name" not defined
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x10 pc=0x61a4a5]
</code></pre>
<p>The error from <code>template</code> suggests that a certain function, <code>Name</code> wasn’t defined. In this case, the author likely used <code>{{.Name}}</code>, while only <code>{{.FirstName}}</code> and <code>{{.LastName}}</code> currently exist.</p>
<p>And I can’t blame them! It’s a pain to go to the <ahref="https://docs.getgophish.com/user-guide/template-reference">template reference</a> every time you want to create a new landing page or email template. I’ve tried to add better error handling to catch this when the HTML is submitted, but we can do even better by adding autocomplete that appears when you try to use a template tag.</p>
<p>Before going into the specifics of how this works, let’s talk a bit about the editor used for Gophish.</p>
<h2id="the-editor-that-powers-gophish">The Editor that Powers Gophish</h2>
<p>When creating Gophish, I had a bit of a unique need. Most WYSIWYG editors focus on editing the <em>content</em> of a document, but I needed to be able to work with entire HTML documents.</p>
<p>At the time, the only editor I could find that could do this was <ahref="[CKEditor 4 documentation](https://ckeditor.com/docs/ckeditor4/latest/)">CKEditor</a>. The interface was clean, and it had the ability to <ahref="[Editing Complete HTML Pages - CKEditor 4 Documentation](https://ckeditor.com/docs/ckeditor4/latest/examples/fullpage.html)">work with entire HTML documents</a> by setting the <code>fullPage</code> attribute in the configuration, which essentially causes CKEditor to orchestrate an iframe with your HTML content.</p>
<blockquote>
<p><strong>Note</strong> - I’m limited to using CKEditor 4, since version 5 moves away from the ability to edit full pages, instead focusing on a better document editing experience. Fortunately, CKEditor 4 seems to still be under active development.</p>
</blockquote>
<p>It had been a while since I upgraded the version of CKEditor used by Gophish, so after applying the latest CKEditor 4 version, I was ready to focus on autocomplete.</p>
<p>With our upgrade, we got the ability to use some new plugins, including one that implements <ahref="[Autocomplete - CKEditor 4 Documentation](https://ckeditor.com/docs/ckeditor4/latest/examples/autocomplete.html)">autocomplete</a>. We can use this to add autocomplete for the various template tags that Gophish provides.</p>
<p>First, we need to define <ahref="[Template Reference - Gophish User Guide](https://docs.getgophish.com/user-guide/template-reference)">the template tags</a> in a variable:</p>
description<spanstyle="color:#666">:</span><spanstyle="color:#b83838">'The recipient\'s first name.'</span>
<spanstyle="color:#888">},</span>
<spanstyle="color:#888">...</span>
</code></pre></div>
<p>With the valid template tags defined, we can start implementing the functions as described in CKEditor’s <ahref="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_autocomplete.html#implementing-custom-autocomplete">autocomplete documentation</a>.</p>
<p>I won’t dive into every function, since many of them are near-verbatim from the documentation. It is, however, worth pointing out what we had to do differently.</p>
<h3id="updating-the-match-pattern">Updating the Match Pattern</h3>
<p>Golang template tags (and, by extension, Gophish template tags) are defined using the <code>{{.Variable}}</code> syntax, which is different than the autocomplete example which uses a <code>[[variable]]</code> syntax. This means we had to adjust the pattern we used to match text:</p>
<divclass="highlight"><prestyle="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><codeclass="language-javascript"data-lang="javascript"><spanstyle="color:#888;font-style:italic">// Matches everything after "{{."
<p>You’ll notice that the pattern includes <code>\.?</code>, which means to match zero or one “.” characters. This was a little touch, since I wanted matches to appear as soon as the user typed “{{“. Having a leading “.” Is something that, from what I can tell, is a bit unique to Golang and is tricky to remember, so this lets us get around that.</p>
<h3id="returning-the-output">Returning the Output</h3>
<p>Once we get our text, show the user the matching options, and one is selected, we need to add the tag to the editor. This is done by providing an <ahref="[Class ConfigDefinition (CKEDITOR.plugins.autocomplete.configDefinition) - CKEditor 4 API docs](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_plugins_autocomplete_configDefinition.html#property-outputTemplate)"><code>outputTemplate</code></a>, and uses CKEditor’s own template syntax.</p>
<p>This causes a problem, since CKEditor’s templates do <ahref="[ckeditor-dev/template.js at 53fcf89e546d494b473b6ca058d6fc9558df9cd6 · ckeditor/ckeditor-dev · GitHub](https://github.com/ckeditor/ckeditor-dev/blob/53fcf89e546d494b473b6ca058d6fc9558df9cd6/core/template.js#L12)">simple regex checks</a> looking for the <code>{variable}</code> syntax, which clashes with our own template variables. Basically, we can’t tell CKEditor that we actually want to insert braces, not get a value from a variable.</p>
<p>To get around this, I took a fairly naive approach, which is to define my <code>outputTemplate</code> using the <code>[[variable]]</code> syntax, replacing the brackets with braces when the value is actually returned:</p>
<p>While this is a great start, it’s unfortunately not perfect. For one thing, it doesn’t work in source mode - a limitation put in place by CKEditor.</p>
<p>The other issue is that the <code>enter</code> and <code>tab</code> keys don’t work for selecting a result from the drop down. This is a <ahref="[Autocomplete dropdown isn’t focused after going to wysiwig mode · Issue #2196 · ckeditor/ckeditor-dev · GitHub](https://github.com/ckeditor/ckeditor-dev/issues/2196)">known bug</a> that occurs when you switch from the source code view in the editor to the WYSIWYG view. Since we start in the source view, this will always be the case. Hopefully this bug will be fixed in a later release.</p>
<p>Minor issues aside, autocomplete is a great example of making things “just work”, which is one of my biggest goals with Gophish. I want to make it as easy as possible to use the software, and this change makes it easy to use all the power of template variables without the hassle of remembering them.</p>
<sectionclass="poweredby">Proudly generated by <aclass="icon-hugo"href="http://gohugo.io">HUGO</a>, with <aclass="icon-theme"href="https://github.com/vjeantet/hugo-theme-casper">Casper</a> theme</section>
<h2class="post-title"><ahref="/blog/post/2019-01-02-adding-autocomplete-to-gophish/">Adding Autocomplete to Gophish</a></h2>
</header>
<sectionclass="post-excerpt">
<p>Gophish provides powerful template tags making it easy to create customized emails and landing pages. Unfortunately, I've had multiple issues file that are the result of incorrect tags being used.
This post describes how I implemented autocomplete for template tags within the Gophish editor, making it easier to use tags reliably and effectively. <aclass="read-more"href="/blog/post/2019-01-02-adding-autocomplete-to-gophish/">»</a></p>
<description>Gophish provides powerful template tags making it easy to create customized emails and landing pages. Sometimes, however, it can be difficult to remember the exact syntax and what template tags are supported.
I&rsquo;ve had multiple issues filed that are the result of incorrect tags being used. Generally, the crash looks something like this:
worker.go:90: template: html_template:6: function &quot;Name&quot; not defined panic: runtime error: invalid memory address or nil pointer dereference [recovered] panic: runtime error: invalid memory address or nil pointer dereference [signal 0xb code=0x1 addr=0x10 pc=0x61a4a5] The error from template suggests that a certain function, Name wasn’t defined.</description>