puppet-lint-check_unsafe_interpolations 0.0.3 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06bfbbbb77295091db599b90f1f6052b98b96e5b3d0d5ab3dc77526527739d56
|
4
|
+
data.tar.gz: e5861ad1c3ce71eef31c619fe6ec00f4edbd58df53741ec9c6e302516276d1bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3fff01f49a697082783b3ea9b6eab8fe92c26e10ddbe8c981eaac0dce1d733166903201f8f7ee438401453fd0096e2c571d5dabd9a5da12163d6a08cec5c306c
|
7
|
+
data.tar.gz: 0fe2a37dda1149d9396371c0eff81048845253cbb94b7badfd91c25c0496b5e10a3240a653b5fe494cba74a16002569b7df6292f936b7f34c8b1bebb240d0ecc
|
@@ -22,10 +22,10 @@ PuppetLint.new_check(:check_unsafe_interpolations) do
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
# Iterate over the tokens in a title and raise a warning if an interpolated variable is found
|
25
|
+
# Iterate over the tokens in a title and raise a warning if an unsafe interpolated variable is found
|
26
26
|
def check_unsafe_title(title)
|
27
27
|
title.each do |token|
|
28
|
-
notify_warning(token.next_code_token) if
|
28
|
+
notify_warning(token.next_code_token) if unsafe_interpolated?(token)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -33,7 +33,7 @@ PuppetLint.new_check(:check_unsafe_interpolations) do
|
|
33
33
|
def check_unsafe_interpolations(command_resources)
|
34
34
|
command_resources[:tokens].each do |token|
|
35
35
|
# Skip iteration if token isn't a command of type :NAME
|
36
|
-
next unless COMMANDS.include?(token.value) && token.type == :NAME
|
36
|
+
next unless COMMANDS.include?(token.value) && (token.type == :NAME || token.type == :UNLESS)
|
37
37
|
# Don't check the command if it is parameterised
|
38
38
|
next if parameterised?(token)
|
39
39
|
|
@@ -60,7 +60,7 @@ PuppetLint.new_check(:check_unsafe_interpolations) do
|
|
60
60
|
# Iterate through tokens in command
|
61
61
|
while current_token.type != :NEWLINE
|
62
62
|
# Check if token is a varibale and if it is parameterised
|
63
|
-
rule_violations.append(current_token.next_code_token) if
|
63
|
+
rule_violations.append(current_token.next_code_token) if unsafe_interpolated?(current_token)
|
64
64
|
current_token = current_token.next_token
|
65
65
|
end
|
66
66
|
|
@@ -78,7 +78,7 @@ PuppetLint.new_check(:check_unsafe_interpolations) do
|
|
78
78
|
end
|
79
79
|
|
80
80
|
# This function is a replacement for puppet_lint's title_tokens function which assumes titles have single quotes
|
81
|
-
# This function adds a check for titles in double quotes where there could be interpolated variables
|
81
|
+
# This function adds a check for titles in double quotes where there could be unsafe interpolated variables
|
82
82
|
def get_exec_titles
|
83
83
|
result = []
|
84
84
|
tokens.each_index do |token_idx|
|
@@ -100,8 +100,8 @@ PuppetLint.new_check(:check_unsafe_interpolations) do
|
|
100
100
|
# Check if title is double quotes string
|
101
101
|
elsif tokens[token_idx].next_code_token.next_code_token.type == :DQPRE
|
102
102
|
# Find the start and end of the title
|
103
|
-
title_start_idx = tokens.
|
104
|
-
title_end_idx =
|
103
|
+
title_start_idx = tokens.find_index(tokens[token_idx].next_code_token.next_code_token)
|
104
|
+
title_end_idx = title_start_idx + index_offset_for(':', tokens[title_start_idx..tokens.length])
|
105
105
|
|
106
106
|
result << tokens[title_start_idx..title_end_idx]
|
107
107
|
# Title is in single quotes
|
@@ -114,7 +114,60 @@ PuppetLint.new_check(:check_unsafe_interpolations) do
|
|
114
114
|
result
|
115
115
|
end
|
116
116
|
|
117
|
-
def
|
118
|
-
|
117
|
+
def find_closing_brack(token)
|
118
|
+
while (token = token.next_code_token)
|
119
|
+
case token.type
|
120
|
+
when :RBRACK
|
121
|
+
return token
|
122
|
+
when :LBRACK
|
123
|
+
token = find_closing_brack(token)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
raise 'not reached'
|
127
|
+
end
|
128
|
+
|
129
|
+
def find_closing_paren(token)
|
130
|
+
while (token = token.next_code_token)
|
131
|
+
case token.type
|
132
|
+
when :RPAREN
|
133
|
+
return token
|
134
|
+
when :LPAREN
|
135
|
+
token = find_closing_paren(token)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
raise 'not reached'
|
139
|
+
end
|
140
|
+
|
141
|
+
def unsafe_interpolated?(token)
|
142
|
+
# XXX: Since stdlib 9.0.0 'shell_escape' is deprecated in favor or 'stdlib::shell_escape'
|
143
|
+
# When the shell_escape function is removed from stdlib, we want to remove it bellow.
|
144
|
+
return false unless INTERPOLATED_STRINGS.include?(token.type)
|
145
|
+
|
146
|
+
token = token.next_code_token
|
147
|
+
|
148
|
+
if token.type == :FUNCTION_NAME && ['shell_escape', 'stdlib::shell_escape'].include?(token.value)
|
149
|
+
token = token.next_code_token
|
150
|
+
token = find_closing_paren(token).next_code_token if token.type == :LPAREN
|
151
|
+
return ![:DQPOST, :DQMID].include?(token.type)
|
152
|
+
elsif token.type == :VARIABLE
|
153
|
+
token = token.next_code_token
|
154
|
+
token = find_closing_brack(token).next_code_token if token.type == :LBRACK
|
155
|
+
if token.type == :DOT && [:NAME, :FUNCTION_NAME].include?(token.next_code_token.type) && ['shell_escape', 'stdlib::shell_escape'].include?(token.next_code_token.value)
|
156
|
+
token = token.next_code_token.next_code_token
|
157
|
+
token = find_closing_paren(token).next_code_token if token.type == :LPAREN
|
158
|
+
return ![:DQPOST, :DQMID].include?(token.type)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
true
|
163
|
+
end
|
164
|
+
|
165
|
+
# Finds the index offset of the next instance of `value` in `tokens_slice` from the original index
|
166
|
+
def index_offset_for(value, tokens_slice)
|
167
|
+
i = 0
|
168
|
+
while i < tokens_slice.length
|
169
|
+
return i if value.include?(tokens_slice[i].value)
|
170
|
+
i += 1
|
171
|
+
end
|
119
172
|
end
|
120
173
|
end
|
@@ -33,6 +33,8 @@ describe 'check_unsafe_interpolations' do
|
|
33
33
|
|
34
34
|
exec { 'bar':
|
35
35
|
command => "echo ${foo} ${bar}",
|
36
|
+
onlyif => "${baz}",
|
37
|
+
unless => "${bazz}",
|
36
38
|
}
|
37
39
|
|
38
40
|
}
|
@@ -40,12 +42,14 @@ describe 'check_unsafe_interpolations' do
|
|
40
42
|
end
|
41
43
|
|
42
44
|
it 'detects multiple unsafe exec command arguments' do
|
43
|
-
expect(problems).to have(
|
45
|
+
expect(problems).to have(4).problems
|
44
46
|
end
|
45
47
|
|
46
48
|
it 'creates two warnings' do
|
47
49
|
expect(problems).to contain_warning(msg)
|
48
|
-
expect(problems).to contain_warning(
|
50
|
+
expect(problems).to contain_warning("unsafe interpolation of variable 'bar' in exec command")
|
51
|
+
expect(problems).to contain_warning("unsafe interpolation of variable 'baz' in exec command")
|
52
|
+
expect(problems).to contain_warning("unsafe interpolation of variable 'bazz' in exec command")
|
49
53
|
end
|
50
54
|
end
|
51
55
|
|
@@ -87,6 +91,44 @@ describe 'check_unsafe_interpolations' do
|
|
87
91
|
end
|
88
92
|
end
|
89
93
|
|
94
|
+
context 'exec with shell escaped string in command' do
|
95
|
+
let(:code) do
|
96
|
+
<<-PUPPET
|
97
|
+
class foo {
|
98
|
+
|
99
|
+
exec { 'bar':
|
100
|
+
command => "echo ${foo.stdlib::shell_escape} ${bar.stdlib::shell_escape()}",
|
101
|
+
onlyif => "${bar[1].stdlib::shell_escape}",
|
102
|
+
unless => "[ -x ${stdlib::shell_escape(reticulate($baz))} ]",
|
103
|
+
}
|
104
|
+
}
|
105
|
+
PUPPET
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'detects zero problems' do
|
109
|
+
expect(problems).to have(0).problems
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'exec with post-processed shell escaped string in command' do
|
114
|
+
let(:code) do
|
115
|
+
<<-PUPPET
|
116
|
+
class foo {
|
117
|
+
|
118
|
+
exec { 'bar':
|
119
|
+
command => "echo ${reticulate(foo.stdlib::shell_escape)} ${bar.stdlib::shell_escape().reticulate}",
|
120
|
+
onlyif => "${bar[1].stdlib::shell_escape.reticulate()}",
|
121
|
+
unless => "[ -x ${reticulate(stdlib::shell_escape($baz))} ]",
|
122
|
+
}
|
123
|
+
}
|
124
|
+
PUPPET
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'detects zero problems' do
|
128
|
+
expect(problems).to have(4).problems
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
90
132
|
context 'exec that has an array of args in command' do
|
91
133
|
let(:code) do
|
92
134
|
<<-PUPPET
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,35 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppet-lint-check_unsafe_interpolations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: puppet-lint
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '4'
|
19
|
+
version: '4.0'
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
|
-
- - "
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '1.0'
|
30
|
-
- - "<"
|
24
|
+
- - "~>"
|
31
25
|
- !ruby/object:Gem::Version
|
32
|
-
version: '4'
|
26
|
+
version: '4.0'
|
33
27
|
description: " A puppet-lint plugin to check for unsafe interpolations.\n"
|
34
28
|
email:
|
35
29
|
executables: []
|
@@ -54,7 +48,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
54
48
|
requirements:
|
55
49
|
- - ">="
|
56
50
|
- !ruby/object:Gem::Version
|
57
|
-
version: '2.
|
51
|
+
version: '2.5'
|
58
52
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
53
|
requirements:
|
60
54
|
- - ">="
|