Given bash's remote code execution vulnerability announced on Sept 24 2014, how can I update my apt-based systems using Ansible?
1 Answers
Here's my preferred solution in a fairly homogenous environment. The advantage of this is the update won't take a lot of time in the future, unlike the version=latest
pattern others are using.
- name: update apt cache if not done today
apt: update_cache=yes cache_valid_time=86400
# http://seclists.org/oss-sec/2014/q3/650
- name: ensure secure ansible, ubuntu 1204 edition
apt: pkg=bash=4.2-2ubuntu2.5 state=present
when: ansible_distribution=='Ubuntu' and ansible_distribution_version=='12.04'
- name: ensure secure ansible, ubuntu 1404 edition
apt: pkg=bash=4.3-7ubuntu1.3 state=present
when: ansible_distribution=='Ubuntu' and ansible_distribution_version=='14.04'
# based on the following gist and comments below. there have been several exploits, this covers them well.
# https://gist.github.com/kacy/2b9408af04c71fab686e
- name: ensure bash is not vulnerable to 201409 problem
shell: "foo='() { echo not patched; }' bash -c foo"
register: command_result
ignore_errors: yes
failed_when: "'command not found' not in command_result.stderr"
Explanation: updating the apt-cache is expensive if done many times per day. The cache time can be adjusted. The code actually tests to make sure the vulnerability is fixed- tests are good. This will highlight any hosts that aren't covered by the distributions/versions coded.
SO user @jarv posted a great solution too. Instead of always updating apt, it only does so if the problem hasn't been fixed. This is the fastest solution possible (in this answer, at least). jarv has also added a distribution test in the linked repo, useful for heterogeneous environments.
- name: Check if we are vulnerable
shell: executable=/bin/bash env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
register: test_vuln
- name: Apply bash security update if we are vulnerable
apt: name=bash state=latest update_cache=true
when: "'vulnerable' in test_vuln.stdout"
- name: Check again and fail if we are still vulnerable
shell: executable=/bin/bash env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
when: "'vulnerable' in test_vuln.stdout"
register: test_vuln
failed_when: "'vulnerable' in test_vuln.stdout"
There are other ways. Michael DeHaan, creator of Ansible, and the official @ansible account tweeted a few solutions:
ansible all -m apt -a 'update_cache=yes name=bash state=latest'
Here's a update-and-check solution:
- name: update apt
command: apt-get update
- name: update bash
command: apt-get --only-upgrade install bash
- name: check bash fix
command: env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
register: command_result
failed_when: "'error' not in command_result.stderr"

- 23,519
- 13
- 86
- 102
-
Here is another solution - https://github.com/edx/configuration/blob/master/playbooks/roles/security/tasks/security-ubuntu.yml Checks to see if the vulnerability exists before the apt-get update. – jarv Sep 24 '14 at 21:09
-
and how to extend for testing against CVE-2014-7169 which according to could be tested with https://shellshocker.net/ ? env X='() { (a)=>\' sh -c "echo date"; cat echo and no date should be printed... may be smth like env X='() { (a)=>\' sh -c "echo echo vulnerable"; cat echo could be used to and should not get "vulnerable" as the last string? – Yaroslav Halchenko Sep 25 '14 at 21:01
-
@YaroslavHalchenko if I understand your question, yes, that's what "vulnerable" tests for. If it prints vulnerable, you need to update. – tedder42 Sep 25 '14 at 21:12
-
The previous vulnerability check is incomplete. Since the first patch was released, further vulnerabilities have been found. A complete vulnerability check would also include this one liner. `foo='() { echo not patched; }' bash -c foo` – apotek Sep 29 '14 at 19:44
-
@apotek thanks- researched and verified locally. I'll edit. – tedder42 Sep 29 '14 at 21:41