Skip to content

Commit

Permalink
Merge pull request #6691 from Checkmarx/kics-968-ansible_tower_expose…
Browse files Browse the repository at this point in the history
…d_to_internet

feat(query): ansible hosts ansible tower exposed to internet
  • Loading branch information
asofsilva authored Sep 13, 2023
2 parents 432f8c2 + 1733b3b commit 7382541
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"id": "1b2bf3ff-31e9-460e-bbfb-45e48f4f20cc",
"queryName": "Ansible Tower Exposed To Internet",
"severity": "MEDIUM",
"category": "Best Practices",
"descriptionText": "Avoid exposing Ansible Tower to the public internet, effectively reducing the potential attack surface of your deployment",
"descriptionUrl": "https://docs.ansible.com/ansible-tower/latest/html/administration/security_best_practices.html#understand-the-architecture-of-ansible-and-tower",
"platform": "Ansible",
"cloudProvider": "common",
"descriptionID": "657a8b1d"
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package Cx

import data.generic.common as common_lib

CxPolicy[result] {
doc := input.document[id].all
doc.children.tower.hosts[ip]

not common_lib.isPrivateIP(ip)

result := {
"documentId": input.document[id].id,
"hostname": "tower",
"resourceName": "children",
"resourceType": "n/a",
"searchKey": "all.children.tower.hosts",
"issueType": "IncorrectValue",
"keyExpectedValue": "Ansible Tower IP should be private",
"keyActualValue": "Ansible Tower IP is public",
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[tower]
172.27.0.2
172.27.0.3
172.27.0.4
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
all:
children:
automationhub:
hosts:
automationhub.acme.org:
admin_password: <password>
pg_database: awx
pg_host: database-01.acme.org
pg_password: <password>
pg_port: '5432'
pg_sslmode: prefer
pg_username: awx
database:
hosts:
database-01.acme.org:
admin_password: <password>
pg_database: awx
pg_host: database-01.acme.org
pg_password: <password>
pg_port: '5432'
pg_sslmode: prefer
pg_username: awx
tower:
hosts:
172.27.0.5:
admin_password: <password>
pg_database: awx
pg_host: database-01.acme.org
pg_password: <password>
pg_port: '5432'
pg_sslmode: prefer
pg_username: awx
ungrouped: {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[tower]
150.50.1.1
[automationhub]
automationhub.acme.org
[database]
database-01.acme.org
[all:vars]
admin_password='<password>'
pg_host='database-01.acme.org'
pg_port='5432'
pg_database='awx'
pg_username='awx'
pg_password='<password>'
pg_sslmode='prefer'
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
all:
children:
automationhub:
hosts:
automationhub.acme.org:
admin_password: <password>
pg_database: awx
pg_host: database-01.acme.org
pg_password: <password>
pg_port: '5432'
pg_sslmode: prefer
pg_username: awx
database:
hosts:
database-01.acme.org:
admin_password: <password>
pg_database: awx
pg_host: database-01.acme.org
pg_password: <password>
pg_port: '5432'
pg_sslmode: prefer
pg_username: awx
tower:
hosts:
139.50.1.1:
admin_password: <password>
pg_database: awx
pg_host: database-01.acme.org
pg_password: <password>
pg_port: '5432'
pg_sslmode: prefer
pg_username: awx
ungrouped: {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"queryName": "Ansible Tower Exposed To Internet",
"severity": "MEDIUM",
"line": 1,
"fileName": "positive1.ini"
},
{
"queryName": "Ansible Tower Exposed To Internet",
"severity": "MEDIUM",
"line": 24,
"fileName": "positive2.yaml"
}
]
18 changes: 13 additions & 5 deletions pkg/engine/vulnerability_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

const (
formatFloat64 = 64
searchKeyMinLen = 5
searchKeyMinLen = 3
)

func modifyVulSearchKeyReference(doc interface{}, originalSearchKey string, stringVulList []string) (string, bool) {
Expand Down Expand Up @@ -245,10 +245,18 @@ func getResolvedSeverity(vObj map[string]interface{}, logWithFields *zerolog.Log

// sanitizeINIKey removes useless searchkey elements like "all" and "children"
func sanitizeINIKey(vulsSplit []string) (vulsRefact []string, searchKey string) {
if len(vulsSplit) >= searchKeyMinLen {
vulsRefact = vulsSplit[len(vulsSplit)-4 : len(vulsSplit)-1]
vulsRefact[0] = "[" + vulsRefact[0] + "]"
vulsRefact = append(vulsRefact[:1], vulsRefact[2:]...)
length := len(vulsSplit)
vulsRefact = vulsSplit
if length >= searchKeyMinLen {
vulsRefact = []string{"[" + vulsSplit[2] + "]"}

if length >= searchKeyMinLen+2 {
vulsRefact = append(vulsRefact, vulsSplit[4])

if length >= searchKeyMinLen+4 {
vulsRefact = append(vulsRefact, vulsSplit[6])
}
}
}
return vulsRefact, strings.Join(vulsRefact, ".")
}
31 changes: 31 additions & 0 deletions pkg/engine/vulnerability_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package engine
import (
"encoding/json"
"reflect"
"strings"
"testing"

"github.com/Checkmarx/kics/internal/tracker"
Expand Down Expand Up @@ -340,3 +341,33 @@ func TestEngine_calculate(t *testing.T) { //nolint
})
}
}

func TestSanitize(t *testing.T) {
tests := []struct {
searchKey string
wantStr string
}{
{
searchKey: "all.children.tower",
wantStr: "[tower]",
},
{
searchKey: "all.children.defaults.hosts",
wantStr: "[defaults]",
},
{
searchKey: "all.children.galaxy.hosts.galaxy_server",
wantStr: "[galaxy].galaxy_server",
},
{
searchKey: "all.children",
wantStr: "all.children",
},
}
for _, tt := range tests {
t.Run(tt.searchKey, func(t *testing.T) {
_, wanted := sanitizeINIKey(strings.Split(tt.searchKey, "."))
require.Equal(t, tt.wantStr, wanted)
})
}
}
3 changes: 3 additions & 0 deletions test/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/Checkmarx/kics/pkg/kics"
"github.com/Checkmarx/kics/pkg/model"
"github.com/Checkmarx/kics/pkg/parser"
ansibleHostsParser "github.com/Checkmarx/kics/pkg/parser/ansible/ini/hosts"
buildahParser "github.com/Checkmarx/kics/pkg/parser/buildah"
dockerParser "github.com/Checkmarx/kics/pkg/parser/docker"
protoParser "github.com/Checkmarx/kics/pkg/parser/grpc"
Expand Down Expand Up @@ -51,6 +52,7 @@ var (
"../assets/queries/ansible/aws": {FileKind: []model.FileKind{model.KindYAML}, Platform: "ansible"},
"../assets/queries/ansible/gcp": {FileKind: []model.FileKind{model.KindYAML}, Platform: "ansible"},
"../assets/queries/ansible/azure": {FileKind: []model.FileKind{model.KindYAML}, Platform: "ansible"},
"../assets/queries/ansible/hosts": {FileKind: []model.FileKind{model.KindINI, model.KindYAML}, Platform: "ansible"},
"../assets/queries/dockerfile": {FileKind: []model.FileKind{model.KindDOCKER}, Platform: "dockerfile"},
"../assets/queries/dockerCompose": {FileKind: []model.FileKind{model.KindYAML}, Platform: "dockerCompose"},
"../assets/queries/openAPI/general": {FileKind: []model.FileKind{model.KindYAML, model.KindJSON}, Platform: "openAPI"},
Expand Down Expand Up @@ -190,6 +192,7 @@ func getCombinedParser() []*parser.Parser {
Add(&dockerParser.Parser{}).
Add(&protoParser.Parser{}).
Add(&buildahParser.Parser{}).
Add(&ansibleHostsParser.Parser{}).
Build([]string{""}, []string{""})
return bd
}
Expand Down

0 comments on commit 7382541

Please sign in to comment.