The Advisory Boar

By Abhijit Menon-Sen <>

Improvements to ansible-vault in Ansible 2

ansible-vault is used to encrypt variable definitions, keys, and other sensitive data so that they can be securely accessed from a playbook. Ansible 2 (not yet released) has some useful security improvements to the ansible-vault command-line interface.

Don't write plaintext to disk

Earlier, there was no way to use ansible-vault without writing sensitive plaintext to disk (either by design, or as an editor byproduct). Now one can use “ansible-vault encrypt” and “ansible-vault decrypt” as filters to read plaintext from stdin or write it to stdout using the new --output option.

# Interactive use: stdin → x (like gpg)
$ ansible-vault encrypt --output x

# Non-interactive use, for scripting
$ pwgen -1|ansible-vault encrypt --output newpass

# Decrypt to stdout
$ ansible-vault decrypt vpnc.conf --output -|vpnc -

These changes retain backwards compatibility with earlier invocations of ansible-vault and make it possible to securely automate the creation and use of vault data. In every case, the input or output file can be set to “-” to use stdin or stdout.

A related change: “ansible-vault view” now feeds plaintext to the pager directly on stdin and never writes plaintext to disk. (But “ansible-vault edit” still writes plaintext to disk.)

Automated rekeying

The vault accepts a --vault-password-file option to be specified in order to avoid the interactive password prompt and confirmation.

With Ansible 2, “ansible-vault rekey” accepts a --new-vault-password-file option that behaves the same way, so it's possible to rekey an already-encrypted vault file automatically, if you pass in a script that writes a new vault password to its stdout. (This operation also doesn't leak plaintext to disk.)

An incidental bugfix also makes it possible to pass multiple filenames to ansible-vault subcommands (i.e., it's now possible to encrypt, decrypt, and rekey more than one file at once–this behaviour was documented, but didn't work).

(Unfortunately, many more important vault changes didn't make it to this release.)

jQuery UI autocompletion and Javascript hijacking

I was pleased to discover that the jQuery UI library includes an autocomplete widget that looks good and works well, and I started using it straightaway to liven up my search boxes. The simplest way to use it is to return an array of JSON objects matching a query from /some/url, and feed the client the following bit of Javascript:

$('#query').autocomplete({source: '/some/url'});

All was well, until I came across this paper on Javascript Hijacking. A quick summary: someone includes a <script> tag on their web site pointing to http://your.serv.er/that/url, and write some Javascript to steal the data (by redefining the array constructor, or overriding the property setter for objects). Due to the very specific circumstances of this attack, it is often misunderstood or ignored as "just another XSS attack", but it can lead to leakage of confidential data. The attack was originally demonstrated by Jeremiah Grossman to steal contacts from someone's GMail account.

The paper outlines a few possible solutions: deal with it like any other cross-site request forgery by requiring the request to include a random unguessable (which means using POST or including the token in the URL), or prefixing the response with "while(1);" or some other statement that would cause the browser to fail to execute the code (e.g. wrap it inside a comment).

Tony Cook pointed out to me that the attack hinges on the fact that an array literal is a valid statement in Javascript, but an object literal by itself is not. This suggests that returning the matches as an object rather than array will defeat the attack:

{"matches": [{"label": "one", "value": 1}, ...]}

Although I can't be certain that no Javascript implementation will treat this as a valid statement, I like this approach better than using POST to fetch a completion list or extending CSRF protections to GET requests. Fortunately, jQuery UI's autocomplete widget is more than flexible enough to accommodate an array of matches wrapped in an object:

$('#query').autocomplete({
    source: function (request, response_cb) {
        $.getJSON(
            '/some/url', {term: request.term},
            function (data) {
                response_cb(data.matches);
            }
        );
    }
});

Unfortunately, this is already much more code than people should have to write to handle this case, and it doesn't even handle errors (if any do occur and are not properly handled, the autocomplete widget will behave strangely). I think jQuery UI should handle this case by default.

This code can easily be adapted to cope with a "while(1);" prefix—treat the response as a string and remove the prefix, then eval the remainder and pass the resulting object to the response callback. If someone can convince me that an object literal is insecure—something of which I am quite willing to be convinced—then I'll change my code to do that. (If this seems a too-casual attitude, it's because none of my autocompletion data are confidential. Defeating casual attacks is fine for the moment.)

Mojolicious session cookies

Mojolicious comes with easy-to-use cryptographically signed session cookies out of the box.

Read more…

Mixing HTTP and HTTPS access to an application

Here's how I set up a web application behind a reverse proxy to serve unauthenticated pages over HTTP, and everything else over HTTPS-only.

Read more…

Cryptographically secure randomness in Perl

If you are on Linux, just use /dev/urandom — and don't worry, what you've heard about it being cryptographically insecure is a myth.

Read more…