puppet-sec-lint 0.5.14 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +40 -8
- data/docs/admin-by-default.md +5 -1
- data/docs/cyrillic-homograph-attack.md +5 -1
- data/docs/empty-password.md +5 -1
- data/docs/hard-coded-credentials.md +6 -1
- data/docs/http-without-tls.md +5 -1
- data/docs/images/puppet-sec-lint_configuration_bool.png +0 -0
- data/docs/images/puppet-sec-lint_configuration_list.png +0 -0
- data/docs/images/puppet-sec-lint_configuration_regex.png +0 -0
- data/docs/images/puppet-sec-lint_rule.png +0 -0
- data/docs/invalid-ip-addr-binding.md +5 -1
- data/docs/suspicious-comments.md +31 -0
- data/docs/weak-crypto-algorithm.md +6 -1
- data/exe/puppet-sec-lint +3 -0
- data/lib/facades/configuration_page_facade.rb +1 -2
- data/lib/puppet-sec-lint/version.rb +1 -1
- data/lib/rules/no_http_rule.rb +1 -1
- data/lib/settings.ini +2 -2
- data/puppet-sec-lint.gemspec +1 -1
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ed39e8fd69a0dd1d3091aaee274f88cc192e973ef2b2cd21076a86aa21f6712
|
4
|
+
data.tar.gz: 9483297393e0eaebe4551b037d87260552c0e26b2b76d77dd9db14485c0a197c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c759dca11c5156be203bafff3ccb26dfcc02a10936a5157b061dabdb42de8689ddc69e79865a999e792c704712cbd95757f383ee1afac33e75b326ad1dbeb9dd
|
7
|
+
data.tar.gz: 49d80107d0ab6d01c73fa24b6482cd7a483f7bf0ec049e860b12b67a27aa69293df98b00bf24cd36def138d3bce3884c4d2b87421b2162f7bec90251d957bf11
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -50,20 +50,52 @@ puppet-sec-lint -c
|
|
50
50
|
|
51
51
|
## Development
|
52
52
|
|
53
|
-
### Development of new rules
|
54
|
-
|
55
53
|
The linter was built on top of a modular architecture, which means that new customizable rules can be added fairly easy facing the discovery of new scenarios and vulnerabilities.
|
56
54
|
|
57
|
-
|
58
|
-
|
55
|
+
### Cloning and running
|
56
|
+
|
57
|
+
To add new functionality to the tool, start by cloning the repository into a folder.
|
58
|
+
To run the software locally, run the executable **exe/puppet-sec-lint** from a command line.
|
59
|
+
|
60
|
+
### Adding new rules
|
61
|
+
|
62
|
+
To add a new rule, the easiest way is to duplicate the file of an existing rule inside the **lib/rules** folder. Taking the *Admin By Default* rule as an example, here is everything that can be changed and customized.
|
63
|
+
|
64
|
+
![puppet-sec-lint rule](docs/images/puppet-sec-lint_rule.png)
|
65
|
+
|
66
|
+
#### Naming
|
67
|
+
|
68
|
+
The class should have an unique and meaningful name, both at the class name itself and the property @Name (that's what's displayed in the Configurations page). It should also be derived from the **Rule** class.
|
69
|
+
|
70
|
+
#### Token analysis
|
71
|
+
|
72
|
+
Each rule works by running the **AnalyzeTokens** method, receiving a list of tokens (that represent the entire code of the file being analyzed) and after analyzing everything, it should return a list of results (each result is a vulnerability found represented by the **Sin** class). Adding new types of vulnerabilities can be done by adding new elements to the **SinType** class.
|
73
|
+
|
74
|
+
#### Configurations
|
75
|
+
|
76
|
+
To add configurable elements to the class, simply create new instances of the child classes of the **Configuration** class, as exemplified in the above rule. The constructor takes as arguments the title and description (to be shown in the configurations page) and the initial default value (before the user modifies the application settings).
|
77
|
+
|
78
|
+
All configurations should then be added to the @configurations array.
|
79
|
+
|
80
|
+
The current types of configurations available (children of the **Configuration** class) are:
|
81
|
+
|
82
|
+
* Boolean
|
83
|
+
|
84
|
+
![puppet-sec-lint configuration_bool](docs/images/puppet-sec-lint_configuration_bool.png)
|
85
|
+
* List of elements
|
86
|
+
|
87
|
+
![puppet-sec-lint configuration_list](docs/images/puppet-sec-lint_configuration_list.png)
|
88
|
+
* Regular Expression
|
89
|
+
|
90
|
+
![puppet-sec-lint configuration_regex](docs/images/puppet-sec-lint_configuration_regex.png)
|
59
91
|
|
60
|
-
|
61
|
-
-->
|
92
|
+
#### Add rule to rule engine
|
62
93
|
|
63
|
-
|
94
|
+
The final step is to ensure that the Rule Engine can detect and run the rule everytime an analysis is performed. As such, in the **lib/rule_engine.rb** file, import the newly created rule and add it to the @rules array.
|
64
95
|
|
65
|
-
|
96
|
+
---
|
66
97
|
|
98
|
+
After following these steps, the rule should then be automatically run everytime an analysis is performed. Also, the configurations now show up automatically in the configurations page, giving the user the possibility to customize its values.
|
67
99
|
|
68
100
|
## Contributing
|
69
101
|
|
data/docs/admin-by-default.md
CHANGED
@@ -24,4 +24,8 @@ Any account with the power to do everything in the system is a very dangerous si
|
|
24
24
|
|
25
25
|
## How to avoid it?
|
26
26
|
|
27
|
-
Accounts should always be setup up with the [Principle of least privilege](https://us-cert.cisa.gov/bsi/articles/knowledge/principles/least-privilege) in mind, meaning that all accounts should only get the permissions strictly necessary to perform their required tasks during the minimum amount of time possible. This severely limits the exposure to accidental errors and also to malicious attackers.
|
27
|
+
Accounts should always be setup up with the [Principle of least privilege](https://us-cert.cisa.gov/bsi/articles/knowledge/principles/least-privilege) in mind, meaning that all accounts should only get the permissions strictly necessary to perform their required tasks during the minimum amount of time possible. This severely limits the exposure to accidental errors and also to malicious attackers.
|
28
|
+
|
29
|
+
## More related information
|
30
|
+
|
31
|
+
* [CWE-250: Execution with Unnecessary Privileges](https://cwe.mitre.org/data/definitions/250.html)
|
@@ -37,4 +37,8 @@ This malicious domain on a Puppet manifest can point to a fake package repositor
|
|
37
37
|
After the tool detects the presence of Cyrillic characters on a URL, the best course of action is to replace all Cyrillic characters with their Latin counterparts, as these characters are very rarely used in legitimate domains.
|
38
38
|
Then, check if the domain is well written (subtle misspellings with similar letters are very common in these kinds of attacks).
|
39
39
|
|
40
|
-
To better ensure that the domain is actually the correct one, the URL can also be copied from a trusted source.
|
40
|
+
To better ensure that the domain is actually the correct one, the URL can also be copied from a trusted source.
|
41
|
+
|
42
|
+
## More related information
|
43
|
+
|
44
|
+
* [CWE-1007: Insufficient Visual Distinction of Homoglyphs Presented to User](https://cwe.mitre.org/data/definitions/1007.html)
|
data/docs/empty-password.md
CHANGED
@@ -24,4 +24,8 @@ An attacker looking to gain access to an account my try a couple of different ge
|
|
24
24
|
|
25
25
|
## How to avoid it?
|
26
26
|
|
27
|
-
Secure software systems should have a decent password policy that prevents, among other types, empty passwords. This means that it's very likely for the Puppet manifest to fail as the password would be rejected. But even if the target software accepts empty passwords, a long and hard to guess password is always a much safer option against malicious attacks.
|
27
|
+
Secure software systems should have a decent password policy that prevents, among other types, empty passwords. This means that it's very likely for the Puppet manifest to fail as the password would be rejected. But even if the target software accepts empty passwords, a long and hard to guess password is always a much safer option against malicious attacks.
|
28
|
+
|
29
|
+
## More related information
|
30
|
+
|
31
|
+
* [CWE-258: Empty Password in Configuration File](https://cwe.mitre.org/data/definitions/258.html)
|
@@ -77,4 +77,9 @@ file { '/etc/mysql/server-key.pem':
|
|
77
77
|
ensure => file,
|
78
78
|
content => hiera("privatekey"),
|
79
79
|
}
|
80
|
-
```
|
80
|
+
```
|
81
|
+
|
82
|
+
## More related information
|
83
|
+
|
84
|
+
* [CWE-259: Use of Hard-coded Password](https://cwe.mitre.org/data/definitions/259.html)
|
85
|
+
* [CWE-798: Use of Hard-coded Credentials](https://cwe.mitre.org/data/definitions/798.html)
|
data/docs/http-without-tls.md
CHANGED
@@ -39,4 +39,8 @@ The attacker can then use this information to attack his victim, by logging in a
|
|
39
39
|
|
40
40
|
## How to avoid it?
|
41
41
|
|
42
|
-
All connections to internet addresses or made available to the public by a service configured with a Puppet manifest must use some kind of secure protocol, to ensure the confidentiality, authenticity and integrity of all data exchanged. Making an HTTPS connection is the easiest way to do this and it's also the recommended way of addressing this security vulnerability. In some cases, if the transferred information is verified afterwards by an hashing algorithm, like packages transferred from a repository, then this solution can be considered optional.
|
42
|
+
All connections to internet addresses or made available to the public by a service configured with a Puppet manifest must use some kind of secure protocol, to ensure the confidentiality, authenticity and integrity of all data exchanged. Making an HTTPS connection is the easiest way to do this and it's also the recommended way of addressing this security vulnerability. In some cases, if the transferred information is verified afterwards by an hashing algorithm, like packages transferred from a repository, then this solution can be considered optional.
|
43
|
+
|
44
|
+
## More related information
|
45
|
+
|
46
|
+
* [CWE-319: Cleartext Transmission of Sensitive Information](https://cwe.mitre.org/data/definitions/319.html)
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -28,4 +28,8 @@ A server or service that's open to all kinds of connections it's more exposed to
|
|
28
28
|
|
29
29
|
## How to avoid it?
|
30
30
|
|
31
|
-
Properly configuring binding addresses means that the server should only accept connections from trusted networks known to use the service. This ensures a greater level of control and also protection, as an attacker would know have an extra obstacle in trying to gain access first to one of those networks.
|
31
|
+
Properly configuring binding addresses means that the server should only accept connections from trusted networks known to use the service. This ensures a greater level of control and also protection, as an attacker would know have an extra obstacle in trying to gain access first to one of those networks.
|
32
|
+
|
33
|
+
## More related information
|
34
|
+
|
35
|
+
* [CWE-284: Improper Access Control](https://cwe.mitre.org/data/definitions/284.html)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
---
|
2
|
+
title: Suspicious Comments
|
3
|
+
permalink: /suspicious-comments/
|
4
|
+
layout: default
|
5
|
+
---
|
6
|
+
|
7
|
+
# Suspicious Comments
|
8
|
+
|
9
|
+
## What are they?
|
10
|
+
|
11
|
+
Suspicious comments are all comments left in a release of a Puppet Manifest that might suggest the existence of bugs, missing security functionalities or other weaknesses.
|
12
|
+
|
13
|
+
|
14
|
+
### Example
|
15
|
+
```puppet
|
16
|
+
# TODO: switch password from weak hash to sha256
|
17
|
+
$key = md5("${client_name} ${client_ip} ${client_seed}")
|
18
|
+
```
|
19
|
+
This comment immediately tells that developers are aware of the weakness of using a compromised hashing algorithm, but still hadn't made the necessary fix.
|
20
|
+
|
21
|
+
## How can it be exploited?
|
22
|
+
|
23
|
+
In the previous example, the presence of the comment immediately draws the attention of a malicious hacker who might have gained access to the code repository. By stating the portion of code that is considered insecure, it tells to an attacker exactly where to look for unpatched vulnerabilities. In this case, he could start working on ways to break the weak hashing algorithm.
|
24
|
+
|
25
|
+
## How to avoid it?
|
26
|
+
|
27
|
+
All comments indicating to be implemented features or non-resolved security issues should be erased, as they pose a very serious threat by gaining the attackers attention. Instead, proper and secure defect management solutions should be used. As a plus, the code stays clean and easy to read.
|
28
|
+
|
29
|
+
## More related information
|
30
|
+
|
31
|
+
* [CWE-546: Suspicious Comment](https://cwe.mitre.org/data/definitions/546.html)
|
@@ -28,4 +28,9 @@ An attacker who was able to gain access to a server and steal the hashes from al
|
|
28
28
|
|
29
29
|
## How to avoid it?
|
30
30
|
|
31
|
-
If the Puppet manifest is being used to generate hashes for passwords or important data, using a more secure algorithm like SHA256 is very advisable as it avoids exposure to the risks mentioned above, ensuring that the algorithm actually performs what's intended to.
|
31
|
+
If the Puppet manifest is being used to generate hashes for passwords or important data, using a more secure algorithm like SHA256 is very advisable as it avoids exposure to the risks mentioned above, ensuring that the algorithm actually performs what's intended to.
|
32
|
+
|
33
|
+
## More related information
|
34
|
+
|
35
|
+
* [CWE-326: Inadequate Encryption Strength](https://cwe.mitre.org/data/definitions/326.html)
|
36
|
+
* [CWE-327: Use of a Broken or Risky Cryptographic Algorithm](https://cwe.mitre.org/data/definitions/327.html)
|
data/exe/puppet-sec-lint
CHANGED
@@ -70,6 +70,8 @@ puts "Release v#{PuppetSecLint::VERSION} #{PuppetSecLint::AUTHOR} #{P
|
|
70
70
|
|
71
71
|
puts "\n"
|
72
72
|
|
73
|
+
STDOUT.flush
|
74
|
+
|
73
75
|
if not ARGV[0].nil?
|
74
76
|
if File.file?(ARGV[0].to_s) && File.extname(ARGV[0].to_s) == '.pp'
|
75
77
|
analyze_file(ARGV[0].to_s)
|
@@ -102,6 +104,7 @@ if ARGV[0].nil? || options[:configurations]
|
|
102
104
|
else
|
103
105
|
puts "\nLinter configurations page available at #{conf_page_url}\n\n"
|
104
106
|
puts "-----------------------------------------------------------------------"
|
107
|
+
STDOUT.flush
|
105
108
|
end
|
106
109
|
|
107
110
|
linter_server.join
|
@@ -75,8 +75,7 @@ class ConfigurationPageFacade
|
|
75
75
|
configuration.value = new_conf[configuration.id].split(/\r?\n/).delete_if(&:empty?)
|
76
76
|
|
77
77
|
when DisplayField[:RegexBox]
|
78
|
-
configuration.value = Regexp.new new_conf[configuration.id]
|
79
|
-
|
78
|
+
configuration.value = if new_conf[configuration.id].empty? then new_conf[configuration.id] else Regexp.new new_conf[configuration.id] end
|
80
79
|
else
|
81
80
|
configuration.value = new_conf[configuration.id]
|
82
81
|
end
|
data/lib/rules/no_http_rule.rb
CHANGED
@@ -22,7 +22,7 @@ class NoHTTPRule < Rule
|
|
22
22
|
|
23
23
|
ptokens = self.filter_resources(tokens, @resources_conf.value)
|
24
24
|
ctokens = self.filter_variables(ptokens, @keywords_conf.value) #TODO: It's working upside down
|
25
|
-
if @whitelist_conf.value
|
25
|
+
if not @whitelist_conf.value.to_s.empty?
|
26
26
|
wtokens = self.filter_whitelist(ctokens, @whitelist_conf.value)
|
27
27
|
else
|
28
28
|
wtokens = ptokens
|
data/lib/settings.ini
CHANGED
@@ -7,10 +7,10 @@ HardCodedCredentialsRule-regular_expression_of_words_not_present_in_credentials
|
|
7
7
|
|
8
8
|
[NoHTTPRule]
|
9
9
|
NoHTTPRule-enable_configuration = true
|
10
|
-
NoHTTPRule-list_of_resources_that_can_use_http = apt::source,::apt::source,wget::fetch,yumrepo,yum::,aptly::mirror,util::system_package,yum::managed_yumrepo
|
10
|
+
NoHTTPRule-list_of_resources_that_can_use_http = apt::source,::apt::source,wget::fetch,yumrepo,yum::,aptly::mirror,util::system_package,yum::managed_yumrepo,apt::repository
|
11
11
|
NoHTTPRule-list_of_keywords_for_urls = backport,key,download,uri,mirror
|
12
12
|
NoHTTPRule-regular_expression_of_a_normal_http_address = (?-mix:^http:\/\/.+)
|
13
|
-
NoHTTPRule-http_address_whitelist =
|
13
|
+
NoHTTPRule-http_address_whitelist =
|
14
14
|
|
15
15
|
[AdminByDefaultRule]
|
16
16
|
AdminByDefaultRule-enable_configuration = true
|
data/puppet-sec-lint.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.description = "Linter built to detect potential security vulnerabilities in Puppet manifests code. It also offers integration with Visual Studio Code https://marketplace.visualstudio.com/items?itemName=tiago1998.puppet-sec-lint-vscode"
|
13
13
|
spec.homepage = "https://github.com/TiagoR98/puppet-sec-lint"
|
14
14
|
spec.license = "MIT"
|
15
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 2.
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
|
16
16
|
|
17
17
|
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
18
18
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppet-sec-lint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tiago Ribeiro
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: puppet-lint
|
@@ -173,11 +173,16 @@ files:
|
|
173
173
|
- docs/empty-password.md
|
174
174
|
- docs/hard-coded-credentials.md
|
175
175
|
- docs/http-without-tls.md
|
176
|
+
- docs/images/puppet-sec-lint_configuration_bool.png
|
177
|
+
- docs/images/puppet-sec-lint_configuration_list.png
|
178
|
+
- docs/images/puppet-sec-lint_configuration_regex.png
|
176
179
|
- docs/images/puppet-sec-lint_configurations.png
|
177
180
|
- docs/images/puppet-sec-lint_console.png
|
181
|
+
- docs/images/puppet-sec-lint_rule.png
|
178
182
|
- docs/images/puppet-sec-lint_vscode.png
|
179
183
|
- docs/index.md
|
180
184
|
- docs/invalid-ip-addr-binding.md
|
185
|
+
- docs/suspicious-comments.md
|
181
186
|
- docs/weak-crypto-algorithm.md
|
182
187
|
- exe/puppet-sec-lint
|
183
188
|
- lib/configurations/boolean_configuration.rb
|
@@ -223,7 +228,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
223
228
|
requirements:
|
224
229
|
- - ">="
|
225
230
|
- !ruby/object:Gem::Version
|
226
|
-
version: 2.
|
231
|
+
version: 2.7.0
|
227
232
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
228
233
|
requirements:
|
229
234
|
- - ">="
|