Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id": "83f6923a-bd92-4066-9280-5723d8541e83",
"queryName": "Beta - Ansible apt Allows Unauthenticated Packages",
"severity": "HIGH",
"category": "Supply Chain",
"descriptionText": "Ansible apt tasks should not allow unauthenticated packages (allow_unauthenticated: true). Installing unsigned packages bypasses repository authentication and enables supply chain attacks through package tampering.",
"descriptionUrl": "https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.html#parameter-allow_unauthenticated",
"platform": "Ansible",
"descriptionID": "a9b0c1d2",
"cloudProvider": "common",
"cwe": "494",
"riskScore": "8.0",
"experimental": "true"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package Cx

import data.generic.ansible as ansLib
import data.generic.common as common_lib

CxPolicy[result] {
task := ansLib.tasks[id][t]
modules := {"ansible.builtin.apt", "apt"}
mod := modules[m]
apt_task := task[mod]
ansLib.checkState(apt_task)

apt_task.allow_unauthenticated == true

result := {
"documentId": id,
"resourceType": mod,
"resourceName": task.name,
"searchKey": sprintf("name={{%s}}.{{%s}}.allow_unauthenticated", [task.name, mod]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("%s.allow_unauthenticated should be false or omitted (defaults to false)", [mod]),
"keyActualValue": sprintf("%s.allow_unauthenticated is true, allowing unsigned packages to be installed", [mod]),
"searchLine": common_lib.build_search_line(["playbooks", t, mod, "allow_unauthenticated"], []),
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- name: Install packages with authentication required
hosts: all
become: true
tasks:
- name: Install package with authentication check
ansible.builtin.apt:
name: curl
state: present
allow_unauthenticated: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- name: Install packages allowing unauthenticated
hosts: all
become: true
tasks:
- name: Install package without authentication check
ansible.builtin.apt:
name: curl
state: present
allow_unauthenticated: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"queryName": "Beta - Ansible apt Allows Unauthenticated Packages",
"severity": "HIGH",
"line": 6,
"filename": "positive1.yaml"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id": "c319ca0f-2fc1-4a06-9ab0-b5cbe6dfb10b",
"queryName": "Beta - Ansible get_url Module SSL Verification Disabled",
"severity": "HIGH",
"category": "Encryption",
"descriptionText": "The Ansible get_url module should not disable SSL certificate validation (validate_certs: false). Disabling certificate validation when downloading files exposes playbooks to man-in-the-middle attacks and file tampering.",
"descriptionUrl": "https://docs.ansible.com/ansible/latest/collections/ansible/builtin/get_url_module.html#parameter-validate_certs",
"platform": "Ansible",
"descriptionID": "e7f8a9b0",
"cloudProvider": "common",
"cwe": "295",
"riskScore": "7.5",
"experimental": "true"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package Cx

import data.generic.ansible as ansLib
import data.generic.common as common_lib

CxPolicy[result] {
task := ansLib.tasks[id][t]
modules := {"ansible.builtin.get_url", "get_url"}
mod := modules[m]
get_url_task := task[mod]
ansLib.checkState(get_url_task)

get_url_task.validate_certs == false

result := {
"documentId": id,
"resourceType": mod,
"resourceName": task.name,
"searchKey": sprintf("name={{%s}}.{{%s}}.validate_certs", [task.name, mod]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("%s.validate_certs should be true or omitted (defaults to true)", [mod]),
"keyActualValue": sprintf("%s.validate_certs is false, disabling SSL certificate validation", [mod]),
"searchLine": common_lib.build_search_line(["playbooks", t, mod, "validate_certs"], []),
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
- name: Download file with SSL verification
hosts: localhost
tasks:
- name: Download binary package
ansible.builtin.get_url:
url: "https://releases.example.com/package.tar.gz"
dest: "/tmp/package.tar.gz"
validate_certs: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
- name: Download file without SSL verification
hosts: localhost
tasks:
- name: Download binary package
ansible.builtin.get_url:
url: "https://releases.example.com/package.tar.gz"
dest: "/tmp/package.tar.gz"
validate_certs: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"queryName": "Beta - Ansible get_url Module SSL Verification Disabled",
"severity": "HIGH",
"line": 6,
"filename": "positive1.yaml"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id": "bd7d338f-3d7f-40d3-9c54-0eee3da1bb20",
"queryName": "Beta - Ansible Package Manager GPG Check Disabled",
"severity": "HIGH",
"category": "Supply Chain",
"descriptionText": "Ansible yum/dnf tasks should not disable GPG signature checking (disable_gpg_check: true). Disabling GPG verification allows unsigned or tampered packages to be installed, enabling supply chain attacks.",
"descriptionUrl": "https://docs.ansible.com/ansible/latest/collections/ansible/builtin/yum_module.html#parameter-disable_gpg_check",
"platform": "Ansible",
"descriptionID": "f8a9b0c1",
"cloudProvider": "common",
"cwe": "494",
"riskScore": "8.0",
"experimental": "true"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package Cx

import data.generic.ansible as ansLib
import data.generic.common as common_lib

CxPolicy[result] {
task := ansLib.tasks[id][t]
modules := {"ansible.builtin.yum", "yum", "ansible.builtin.dnf", "dnf"}
mod := modules[m]
pkg_task := task[mod]
ansLib.checkState(pkg_task)

pkg_task.disable_gpg_check == true

result := {
"documentId": id,
"resourceType": mod,
"resourceName": task.name,
"searchKey": sprintf("name={{%s}}.{{%s}}.disable_gpg_check", [task.name, mod]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("%s.disable_gpg_check should be false or omitted (defaults to false)", [mod]),
"keyActualValue": sprintf("%s.disable_gpg_check is true, skipping GPG signature verification", [mod]),
"searchLine": common_lib.build_search_line(["playbooks", t, mod, "disable_gpg_check"], []),
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- name: Install packages with GPG check enabled
hosts: all
become: true
tasks:
- name: Install nginx with signature verification
ansible.builtin.yum:
name: nginx
state: present
disable_gpg_check: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- name: Install packages with GPG check disabled
hosts: all
become: true
tasks:
- name: Install nginx without signature verification
ansible.builtin.yum:
name: nginx
state: present
disable_gpg_check: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"queryName": "Beta - Ansible Package Manager GPG Check Disabled",
"severity": "HIGH",
"line": 6,
"filename": "positive1.yaml"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id": "643aefc9-043e-44d7-bb3d-21fe6c879310",
"queryName": "Beta - Ansible pip Uses Extra Index URL Without Hash Verification",
"severity": "HIGH",
"category": "Supply Chain",
"descriptionText": "When Ansible pip tasks use --extra-index-url, they should also specify --require-hashes to prevent dependency confusion attacks where a malicious package on PyPI could shadow a private package.",
"descriptionUrl": "https://docs.ansible.com/ansible/latest/collections/ansible/builtin/pip_module.html#parameter-extra_args",
"platform": "Ansible",
"descriptionID": "b0c1d2e3",
"cloudProvider": "common",
"cwe": "494",
"riskScore": "7.0",
"experimental": "true"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package Cx

import data.generic.ansible as ansLib
import data.generic.common as common_lib

CxPolicy[result] {
task := ansLib.tasks[id][t]
modules := {"ansible.builtin.pip", "pip"}
mod := modules[m]
pip_task := task[mod]
ansLib.checkState(pip_task)

# extra_args contains --extra-index-url without --require-hashes
extra_args := pip_task.extra_args
is_string(extra_args)
contains(extra_args, "--extra-index-url")
not contains(extra_args, "--require-hashes")

result := {
"documentId": id,
"resourceType": mod,
"resourceName": task.name,
"searchKey": sprintf("name={{%s}}.{{%s}}.extra_args", [task.name, mod]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("%s using --extra-index-url should also specify --require-hashes", [mod]),
"keyActualValue": sprintf("%s uses --extra-index-url without --require-hashes, allowing dependency confusion attacks", [mod]),
"searchLine": common_lib.build_search_line(["playbooks", t, mod, "extra_args"], []),
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
- name: Install Python packages from private index with hashes
hosts: all
tasks:
- name: Install package from private PyPI with hash verification
ansible.builtin.pip:
name: my-private-package==1.0.0
extra_args: "--extra-index-url https://pypi.company.com/simple/ --require-hashes"
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
- name: Install Python packages from private index
hosts: all
tasks:
- name: Install package from private PyPI without hash verification
ansible.builtin.pip:
name: my-private-package==1.0.0
extra_args: "--extra-index-url https://pypi.company.com/simple/"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"queryName": "Beta - Ansible pip Uses Extra Index URL Without Hash Verification",
"severity": "HIGH",
"line": 5,
"filename": "positive1.yaml"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id": "733d2bd2-5a0e-4c0f-9b0b-98415dfca55e",
"queryName": "Beta - Ansible URI Module SSL Verification Disabled",
"severity": "HIGH",
"category": "Encryption",
"descriptionText": "The Ansible uri module should not disable SSL certificate validation (validate_certs: false). Disabling certificate validation makes connections vulnerable to man-in-the-middle attacks.",
"descriptionUrl": "https://docs.ansible.com/ansible/latest/collections/ansible/builtin/uri_module.html#parameter-validate_certs",
"platform": "Ansible",
"descriptionID": "d6e7f8a9",
"cloudProvider": "common",
"cwe": "295",
"riskScore": "7.5",
"experimental": "true"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package Cx

import data.generic.ansible as ansLib
import data.generic.common as common_lib

CxPolicy[result] {
task := ansLib.tasks[id][t]
modules := {"ansible.builtin.uri", "uri"}
mod := modules[m]
uri_task := task[mod]
ansLib.checkState(uri_task)

uri_task.validate_certs == false

result := {
"documentId": id,
"resourceType": mod,
"resourceName": task.name,
"searchKey": sprintf("name={{%s}}.{{%s}}.validate_certs", [task.name, mod]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("%s.validate_certs should be true or omitted (defaults to true)", [mod]),
"keyActualValue": sprintf("%s.validate_certs is false, disabling SSL certificate validation", [mod]),
"searchLine": common_lib.build_search_line(["playbooks", t, mod, "validate_certs"], []),
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- name: Fetch data with SSL verification enabled
hosts: localhost
tasks:
- name: Make HTTP request with certificate validation
ansible.builtin.uri:
url: "https://api.example.com/data"
method: GET
validate_certs: true
register: response
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- name: Fetch data with SSL verification disabled
hosts: localhost
tasks:
- name: Make HTTP request without certificate validation
ansible.builtin.uri:
url: "https://api.example.com/data"
method: GET
validate_certs: false
register: response
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"queryName": "Beta - Ansible URI Module SSL Verification Disabled",
"severity": "HIGH",
"line": 6,
"filename": "positive1.yaml"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id": "781e75f7-bf43-4ab7-bae7-a08ad6607af3",
"queryName": "Beta - ENV Instruction Contains Secret",
"severity": "HIGH",
"category": "Secret Management",
"descriptionText": "Dockerfile ENV instructions should not store secrets, passwords, API keys or tokens as plaintext values. These values are embedded in every image layer and visible in 'docker inspect' output, risking credential exposure. Use build-time secrets (BuildKit) or a secrets manager instead.",
"descriptionUrl": "https://docs.docker.com/build/building/secrets/",
"platform": "Dockerfile",
"descriptionID": "7abccf53",
"cloudProvider": "common",
"cwe": "798",
"riskScore": "8.5",
"experimental": "true"
}
Loading
Loading