puppet-lint-security-plugins 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +90 -0
- data/lib/puppet-lint-security-plugins.rb +2 -0
- data/lib/puppet-lint/plugins/check_class_or_define_parameter_in_exec.rb +36 -0
- data/lib/puppet-lint/plugins/check_security_apache_bad_cipher.rb +28 -0
- data/lib/puppet-lint/plugins/check_security_apache_no_ssl_vhost.rb +27 -0
- data/lib/puppet-lint/plugins/check_security_apt_no_key.rb +26 -0
- data/lib/puppet-lint/plugins/check_security_eval_in_erb.rb +21 -0
- data/lib/puppet-lint/plugins/check_security_file_with_setgid_permission.rb +25 -0
- data/lib/puppet-lint/plugins/check_security_file_with_setuid_permission.rb +25 -0
- data/lib/puppet-lint/plugins/check_security_file_with_world_permissions.rb +25 -0
- data/lib/puppet-lint/plugins/check_security_firewall_any_any_allow.rb +26 -0
- data/lib/puppet-lint/plugins/check_security_firewall_any_any_deny.rb +27 -0
- data/lib/puppet-lint/plugins/check_security_firewall_dns_used.rb +30 -0
- data/lib/puppet-lint/plugins/check_security_firewall_puppetmaster_any_deny.rb +33 -0
- data/lib/puppet-lint/plugins/check_security_package_pinned_version.rb +25 -0
- data/lib/puppet-lint/plugins/check_security_password_in_code.rb +31 -0
- data/lib/puppet-lint/plugins/check_security_password_variable_in_exec.rb +22 -0
- data/lib/puppet-lint/plugins/check_security_regex_unspecific.rb +23 -0
- data/lib/puppet-lint/plugins/check_security_service_mysql_disabled.rb +22 -0
- data/lib/puppet-lint/plugins/check_security_service_puppetmaster_disabled.rb +24 -0
- data/lib/puppet-lint/plugins/check_security_ssh_root_allowed.rb +26 -0
- data/lib/puppet-lint/plugins/check_security_sudo_with_world_nopasswd.rb +23 -0
- data/lib/puppet-lint/plugins/check_security_tidy_all_files.rb +20 -0
- data/lib/puppet-lint/plugins/check_security_tidy_matches_greedy.rb +27 -0
- data/lib/puppet-lint/plugins/check_security_tidy_recurse.rb +21 -0
- data/lib/puppet-lint/plugins/check_security_user_with_id_0_created.rb +28 -0
- data/lib/puppet-lint/security.rb +280 -0
- data/spec/puppet-lint/plugins/check_class_or_define_parameter_in_exec_spec.rb +85 -0
- data/spec/puppet-lint/plugins/check_security_apache_bad_cipher_spec.rb +49 -0
- data/spec/puppet-lint/plugins/check_security_apache_no_ssl_vhost_spec.rb +40 -0
- data/spec/puppet-lint/plugins/check_security_apt_absent_no_key_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_security_apt_no_key_spec.rb +38 -0
- data/spec/puppet-lint/plugins/check_security_dir_guid_permissions_spec.rb +49 -0
- data/spec/puppet-lint/plugins/check_security_dir_world_permissions_spec.rb +39 -0
- data/spec/puppet-lint/plugins/check_security_eval_in_erb_spec.rb +35 -0
- data/spec/puppet-lint/plugins/check_security_file_suid_permissions_spec.rb +48 -0
- data/spec/puppet-lint/plugins/check_security_file_with_setgid_permission_spec.rb +59 -0
- data/spec/puppet-lint/plugins/check_security_file_with_setuid_permission_spec.rb +59 -0
- data/spec/puppet-lint/plugins/check_security_file_with_world_permissions_spec.rb +62 -0
- data/spec/puppet-lint/plugins/check_security_file_world_and_guid_permissions_spec.rb +43 -0
- data/spec/puppet-lint/plugins/check_security_firewall_any_any_allow_spec.rb +36 -0
- data/spec/puppet-lint/plugins/check_security_firewall_any_any_deny_spec.rb +124 -0
- data/spec/puppet-lint/plugins/check_security_firewall_dns_used_spec.rb +77 -0
- data/spec/puppet-lint/plugins/check_security_firewall_puppetmaster_any_deny_spec.rb +60 -0
- data/spec/puppet-lint/plugins/check_security_package_pinned_version_spec.rb +43 -0
- data/spec/puppet-lint/plugins/check_security_password_in_code_spec.rb +55 -0
- data/spec/puppet-lint/plugins/check_security_password_variable_in_exec_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_security_regex_unspecific_spec.rb +40 -0
- data/spec/puppet-lint/plugins/check_security_service_mysql_disabled_spec.rb +54 -0
- data/spec/puppet-lint/plugins/check_security_service_puppetmaster_disabled_spec.rb +40 -0
- data/spec/puppet-lint/plugins/check_security_ssh_root_allowed_spec.rb +60 -0
- data/spec/puppet-lint/plugins/check_security_ssh_server_root_allowed_spec.rb +60 -0
- data/spec/puppet-lint/plugins/check_security_sudo_with_world_nopasswd_spec.rb +40 -0
- data/spec/puppet-lint/plugins/check_security_tidy_all_files_spec.rb +36 -0
- data/spec/puppet-lint/plugins/check_security_tidy_matches_greedy_spec.rb +37 -0
- data/spec/puppet-lint/plugins/check_security_tidy_recurse_spec.rb +37 -0
- data/spec/puppet-lint/plugins/check_security_user_with_id_0_created_spec.rb +47 -0
- data/spec/spec_helper.rb +5 -0
- metadata +232 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'security_file_with_setuid_permission' do
|
4
|
+
let(:msg) { 'File or directory definition with setuid to root detected (security!)'}
|
5
|
+
|
6
|
+
context 'with fix disabled' do
|
7
|
+
context 'code having file with setuid permissions' do
|
8
|
+
let(:code) { "
|
9
|
+
|
10
|
+
file { '/bin/bash':
|
11
|
+
mode => '1755',
|
12
|
+
owner => 'root',
|
13
|
+
group => 'root',
|
14
|
+
}
|
15
|
+
|
16
|
+
" }
|
17
|
+
|
18
|
+
it 'should detect a single problem' do
|
19
|
+
expect(problems).to have(1).problem
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should create a error' do
|
23
|
+
expect(problems).to contain_error(msg).on_line(4).in_column(11)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'code having no file with setuid permissions' do
|
28
|
+
let(:code) { "
|
29
|
+
|
30
|
+
file { '/bin/bash':
|
31
|
+
mode => '0755',
|
32
|
+
owner => 'root',
|
33
|
+
group => 'root',
|
34
|
+
}
|
35
|
+
|
36
|
+
file {
|
37
|
+
'/etc/icinga/commands.cfg':
|
38
|
+
content => template('icinga/etc_icinga_commands.cfg'),
|
39
|
+
notify => Exec['icinga'],
|
40
|
+
owner => 'root',
|
41
|
+
group => 'root',
|
42
|
+
mode => '0644',
|
43
|
+
require => Package['icinga'];
|
44
|
+
'/usr/local/bin/icinga2ticket.rb':
|
45
|
+
content => template('icinga/usr_local_bin_icinga2ticket.rb'),
|
46
|
+
notify => Exec['icinga'],
|
47
|
+
owner => 'nagios',
|
48
|
+
group => 'nagios',
|
49
|
+
mode => '0750';
|
50
|
+
}
|
51
|
+
" }
|
52
|
+
|
53
|
+
it 'should not detect any problems' do
|
54
|
+
expect(problems).to have(0).problems
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'security_file_with_world_permissions' do
|
4
|
+
let(:msg) { 'File or directory definition with world permissions detected (security!)' }
|
5
|
+
|
6
|
+
context 'with fix disabled' do
|
7
|
+
context 'code having file with world permissions' do
|
8
|
+
let(:code) { "
|
9
|
+
|
10
|
+
file { '/etc/passwd':
|
11
|
+
ensure => present,
|
12
|
+
mode => '0666',
|
13
|
+
owner => 'root',
|
14
|
+
group => 'root',
|
15
|
+
source => 'puppet:///modules/passwd/etc_passwd',
|
16
|
+
}
|
17
|
+
|
18
|
+
" }
|
19
|
+
|
20
|
+
it 'should detect a single problem' do
|
21
|
+
expect(problems).to have(1).problem
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should create a error' do
|
25
|
+
expect(problems).to contain_error(msg).on_line(5).in_column(11)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'code having file with no world permissions' do
|
30
|
+
let(:code) { "
|
31
|
+
file { '/etc/passwd':
|
32
|
+
ensure => present,
|
33
|
+
mode => '0644',
|
34
|
+
owner => 'root',
|
35
|
+
group => 'root',
|
36
|
+
source => 'puppet:///modules/passwd/etc_passwd',
|
37
|
+
}
|
38
|
+
|
39
|
+
file {
|
40
|
+
'/etc/icinga/commands.cfg':
|
41
|
+
content => template('icinga/etc_icinga_commands.cfg'),
|
42
|
+
notify => Exec['icinga'],
|
43
|
+
owner => 'root',
|
44
|
+
group => 'root',
|
45
|
+
mode => '0644',
|
46
|
+
require => Package['icinga'];
|
47
|
+
'/usr/local/bin/icinga2ticket.rb':
|
48
|
+
content => template('icinga/usr_local_bin_icinga2ticket.rb'),
|
49
|
+
notify => Exec['icinga'],
|
50
|
+
owner => 'nagios',
|
51
|
+
group => 'nagios',
|
52
|
+
mode => '0750';
|
53
|
+
}
|
54
|
+
" }
|
55
|
+
|
56
|
+
it 'should not detect any problems' do
|
57
|
+
expect(problems).to have(0).problems
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'security_file_with_world_permissions' do
|
4
|
+
let(:msg) { 'File or directory definition with world permissions detected (security!)' }
|
5
|
+
|
6
|
+
context 'with fix disabled' do
|
7
|
+
context 'code having file with world permissions' do
|
8
|
+
let(:code) { "
|
9
|
+
|
10
|
+
file { \"/nfs/${targetpath}/foobar\":
|
11
|
+
group => 'roots',
|
12
|
+
mode => 2777,
|
13
|
+
require => Autofs::Mount[$targetpath];
|
14
|
+
}
|
15
|
+
|
16
|
+
" }
|
17
|
+
|
18
|
+
it 'should detect a single problem' do
|
19
|
+
expect(problems).to have(1).problem
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should create a error' do
|
23
|
+
expect(problems).to contain_error(msg).on_line(5).in_column(20)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'code having file with no world permissions' do
|
28
|
+
let(:code) { "
|
29
|
+
|
30
|
+
file { \"/nfs/${targetpath}/foobar\":
|
31
|
+
group => 'roots',
|
32
|
+
mode => 0755,
|
33
|
+
require => Autofs::Mount[$targetpath];
|
34
|
+
}
|
35
|
+
" }
|
36
|
+
|
37
|
+
it 'should not detect any problems' do
|
38
|
+
expect(problems).to have(0).problems
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'security_firewall_any_any_allow' do
|
4
|
+
let(:msg) { 'Firewall any/any allow rule detected (security!)' }
|
5
|
+
|
6
|
+
context 'with fix disabled' do
|
7
|
+
context 'code having any/any allow rule in firewall' do
|
8
|
+
let(:code) { "firewall { 'allow_any':
|
9
|
+
port => 'any',
|
10
|
+
source => 'any',
|
11
|
+
proto => tcp,
|
12
|
+
action => 'accept',
|
13
|
+
}" }
|
14
|
+
|
15
|
+
it 'should detect a single problem' do
|
16
|
+
expect(problems).to have(1).problem
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should create a error' do
|
20
|
+
expect(problems).to contain_error(msg).on_line(2).in_column(16)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'code having no any/any allow rule in firewall' do
|
25
|
+
let(:code) { "firewall { 'allow_ssh':
|
26
|
+
port => [22],
|
27
|
+
proto => tcp,
|
28
|
+
action => 'accept',
|
29
|
+
}" }
|
30
|
+
|
31
|
+
it 'should not detect any problems' do
|
32
|
+
expect(problems).to have(0).problems
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'security_firewall_any_any_deny' do
|
4
|
+
let(:msg) { 'Firewall any:all drop rule detected (security!)' }
|
5
|
+
|
6
|
+
context 'with fix disabled' do
|
7
|
+
context 'code having any:all drop rule in firewall with proto and ipv4 source given' do
|
8
|
+
let(:code) { "
|
9
|
+
firewall { '000_deny_any':
|
10
|
+
proto => 'all',
|
11
|
+
source => '0.0.0.0/0',
|
12
|
+
action => 'drop',
|
13
|
+
}
|
14
|
+
" }
|
15
|
+
|
16
|
+
it 'should detect a single problem' do
|
17
|
+
expect(problems).to have(1).problem
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should create a warning' do
|
21
|
+
expect(problems).to contain_warning(msg).on_line(2).in_column(29)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'code having any:all drop rule in firewall with proto and ipv6 source given' do
|
26
|
+
let(:code) { "
|
27
|
+
firewall { '000_deny_any':
|
28
|
+
proto => 'all',
|
29
|
+
source => '::',
|
30
|
+
action => 'drop',
|
31
|
+
}
|
32
|
+
" }
|
33
|
+
|
34
|
+
it 'should detect a single problem' do
|
35
|
+
expect(problems).to have(1).problem
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should create a warning' do
|
39
|
+
expect(problems).to contain_warning(msg).on_line(2).in_column(29)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'code having drop rule in firewall without proto and source given' do
|
44
|
+
let(:code) { "
|
45
|
+
firewall { '000_deny_any':
|
46
|
+
action => 'drop',
|
47
|
+
}
|
48
|
+
" }
|
49
|
+
|
50
|
+
it 'should detect a single problem' do
|
51
|
+
expect(problems).to have(1).problem
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should create a warning' do
|
55
|
+
expect(problems).to contain_warning(msg).on_line(2).in_column(29)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'code having drop rule in firewall without proto and source "::"' do
|
60
|
+
let(:code) { "
|
61
|
+
firewall { '000_deny_any':
|
62
|
+
source => '::',
|
63
|
+
action => 'drop',
|
64
|
+
}
|
65
|
+
" }
|
66
|
+
|
67
|
+
it 'should detect a single problem' do
|
68
|
+
expect(problems).to have(1).problem
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should create a warning' do
|
72
|
+
expect(problems).to contain_warning(msg).on_line(2).in_column(29)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'code having drop rule in firewall without proto and source "0.0.0.0/0"' do
|
77
|
+
let(:code) { "
|
78
|
+
firewall { '000_deny_any':
|
79
|
+
source => '0.0.0.0/0',
|
80
|
+
action => 'drop',
|
81
|
+
}
|
82
|
+
" }
|
83
|
+
|
84
|
+
it 'should detect a single problem' do
|
85
|
+
expect(problems).to have(1).problem
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should create a warning' do
|
89
|
+
expect(problems).to contain_warning(msg).on_line(2).in_column(29)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'code having drop rule in firewall without source and prot "all"' do
|
94
|
+
let(:code) { "
|
95
|
+
firewall { '000_deny_any':
|
96
|
+
proto => 'all',
|
97
|
+
action => 'drop',
|
98
|
+
}
|
99
|
+
" }
|
100
|
+
|
101
|
+
it 'should detect a single problem' do
|
102
|
+
expect(problems).to have(1).problem
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should create a warning' do
|
106
|
+
expect(problems).to contain_warning(msg).on_line(2).in_column(29)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'code having no any/any deny in firewall' do
|
111
|
+
let(:code) { "
|
112
|
+
firewall { 'deny_ssh':
|
113
|
+
port => [22],
|
114
|
+
proto => tcp,
|
115
|
+
action => 'drop',
|
116
|
+
}
|
117
|
+
" }
|
118
|
+
|
119
|
+
it 'should not detect any problems' do
|
120
|
+
expect(problems).to have(0).problems
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'security_firewall_dns_used' do
|
4
|
+
let(:msg) { 'DNS in firewall rule used (security!)' }
|
5
|
+
|
6
|
+
context 'with fix disabled' do
|
7
|
+
context 'code having DNS hostname in firewall' do
|
8
|
+
let(:code) { "
|
9
|
+
|
10
|
+
firewall { 'allow_ssh_from_dns_host':
|
11
|
+
port => 'ssh',
|
12
|
+
source => 'server.example.tld',
|
13
|
+
proto => tcp,
|
14
|
+
action => 'accept',
|
15
|
+
}
|
16
|
+
|
17
|
+
" }
|
18
|
+
|
19
|
+
it 'should detect a single problem' do
|
20
|
+
expect(problems).to have(1).problem
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should create a error' do
|
24
|
+
expect(problems).to contain_error(msg).on_line(5).in_column(16)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'code having no DNS hostname in firewall' do
|
29
|
+
let(:code) { "
|
30
|
+
|
31
|
+
firewall { 'allow_ssh_from_host':
|
32
|
+
port => 'ssh',
|
33
|
+
source => '192.168.10.22',
|
34
|
+
proto => tcp,
|
35
|
+
action => 'accept',
|
36
|
+
}
|
37
|
+
|
38
|
+
firewall { '100 syslog server relp':
|
39
|
+
proto => 'tcp',
|
40
|
+
dport => [\"20514\"],
|
41
|
+
source => \"10.0.0.0/16\",
|
42
|
+
action => \"accept\",
|
43
|
+
}
|
44
|
+
|
45
|
+
firewall {
|
46
|
+
'100 rpc 111/tcp':
|
47
|
+
dport => '111',
|
48
|
+
proto => 'tcp',
|
49
|
+
source => $filer,
|
50
|
+
action => 'accept';
|
51
|
+
'101 statd/tcp':
|
52
|
+
dport => $nfs_statd_port,
|
53
|
+
proto => 'tcp',
|
54
|
+
source => $filer,
|
55
|
+
action => 'accept';
|
56
|
+
'100 rpc 111/udp':
|
57
|
+
dport => '111',
|
58
|
+
proto => 'udp',
|
59
|
+
source => $filer,
|
60
|
+
action => 'accept';
|
61
|
+
'101 statd/udp':
|
62
|
+
dport => $nfs_statd_port,
|
63
|
+
proto => 'udp',
|
64
|
+
source => $filer,
|
65
|
+
action => 'accept';
|
66
|
+
|
67
|
+
}
|
68
|
+
|
69
|
+
" }
|
70
|
+
|
71
|
+
it 'should not detect any problems' do
|
72
|
+
expect(problems).to have(0).problems
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'security_firewall_puppetmaster_any_deny' do
|
4
|
+
let(:msg) { 'Firewall drops puppetmaster port (security!)' }
|
5
|
+
|
6
|
+
context 'with fix disabled' do
|
7
|
+
context 'code having rule droping puppetmaster port as array in firewall' do
|
8
|
+
let(:code) { "
|
9
|
+
firewall { '000_deny_puppetmaster':
|
10
|
+
port => [8140],
|
11
|
+
proto => tcp,
|
12
|
+
action => 'drop',
|
13
|
+
}
|
14
|
+
" }
|
15
|
+
|
16
|
+
it 'should detect a single problem' do
|
17
|
+
expect(problems).to have(1).problem
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should create a warning' do
|
21
|
+
expect(problems).to contain_warning(msg).on_line(2).in_column(38)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'code having rule droping puppetmaster port in firewall' do
|
26
|
+
let(:code) { "
|
27
|
+
firewall { '000_deny_puppetmaster':
|
28
|
+
port => 8140,
|
29
|
+
proto => tcp,
|
30
|
+
source => '::',
|
31
|
+
action => 'drop',
|
32
|
+
}
|
33
|
+
" }
|
34
|
+
|
35
|
+
it 'should detect a single problem' do
|
36
|
+
expect(problems).to have(1).problem
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should create a warning' do
|
40
|
+
expect(problems).to contain_warning(msg).on_line(2).in_column(38)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
context 'code having no rule droping puppetmaster port in firewall' do
|
46
|
+
let(:code) { "
|
47
|
+
firewall { '000_allow_puppetmaster':
|
48
|
+
port => [8140],
|
49
|
+
source => 'any',
|
50
|
+
proto => tcp,
|
51
|
+
action => 'accept',
|
52
|
+
}
|
53
|
+
" }
|
54
|
+
|
55
|
+
it 'should not detect any problems' do
|
56
|
+
expect(problems).to have(0).problems
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|