puppet-sec-lint 0.1.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +4 -2
  3. data/.idea/puppet-sec-lint.iml +7 -4
  4. data/Gemfile +3 -1
  5. data/Gemfile.lock +7 -1
  6. data/README.md +35 -18
  7. data/_config.yml +1 -0
  8. data/docs/404.html +24 -0
  9. data/docs/Gemfile +30 -0
  10. data/docs/Gemfile.lock +275 -0
  11. data/docs/_config.yml +41 -0
  12. data/docs/_posts/2021-05-03-welcome-to-jekyll.markdown +25 -0
  13. data/docs/_site/404.html +71 -0
  14. data/docs/_site/feed.xml +13 -0
  15. data/docs/_site/index.html +1 -0
  16. data/docs/_site/jekyll/update/2021/05/03/welcome-to-jekyll.html +77 -0
  17. data/docs/hard-coded-credentials.md +17 -0
  18. data/docs/index.md +6 -0
  19. data/exe/puppet-sec-lint +69 -15
  20. data/lib/configurations/configuration.rb +2 -1
  21. data/lib/configurations/regex_configuration.rb +9 -0
  22. data/lib/facades/configuration_file_facade.rb +3 -1
  23. data/lib/facades/configuration_page_facade.rb +6 -0
  24. data/lib/lol.pp +6 -6
  25. data/lib/puppet-sec-lint/version.rb +3 -1
  26. data/lib/rule_engine.rb +15 -3
  27. data/lib/rules/admin_by_default_rule.rb +33 -0
  28. data/lib/rules/cyrillic_homograph_attack.rb +27 -0
  29. data/lib/rules/empty_password_rule.rb +35 -0
  30. data/lib/rules/hard_coded_credentials_rule.rb +22 -31
  31. data/lib/rules/invalid_ip_addr_binding_rule.rb +37 -0
  32. data/lib/rules/no_http_rule.rb +26 -9
  33. data/lib/rules/rule.rb +72 -0
  34. data/lib/rules/suspicious_comment_rule.rb +28 -0
  35. data/lib/rules/use_weak_crypto_algorithms_rule.rb +28 -0
  36. data/lib/servers/language_server.rb +100 -0
  37. data/lib/servers/linter_server.rb +50 -0
  38. data/lib/{sin.rb → sin/sin.rb} +6 -1
  39. data/lib/sin/sin_type.rb +44 -0
  40. data/lib/test.txt +15 -0
  41. data/lib/test2.rb +16 -0
  42. data/lib/test3.rb +32 -0
  43. data/lib/test_new.rb +19 -0
  44. data/lol2.pp +83 -0
  45. metadata +30 -5
  46. data/lib/language_server.rb +0 -78
  47. data/lib/sin_type.rb +0 -12
@@ -0,0 +1,50 @@
1
+ require "rack"
2
+ require "thin"
3
+ require 'json'
4
+ require 'uri'
5
+ require_relative '../rule_engine'
6
+ require_relative '../visitors/configuration_visitor'
7
+ require_relative '../facades/configuration_page_facade'
8
+ require_relative '../facades/configuration_file_facade'
9
+
10
+ class LinterServer
11
+ ConfigurationVisitor.GenerateIDs
12
+ ConfigurationFileFacade.LoadConfigurations
13
+
14
+ def call(env)
15
+ req = Rack::Request.new(env)
16
+
17
+ case req.path
18
+ when "/configuration"
19
+ if req.post?
20
+ process_form(req)
21
+ elsif req.get?
22
+ configurations_page
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ def configurations_page
29
+ configuration_page = ConfigurationPageFacade.AssemblePage
30
+
31
+ return [200, { 'Content-Type' => 'text/html' }, [configuration_page]]
32
+ end
33
+
34
+ def process_form(req)
35
+ new_conf = URI.decode_www_form(req.body.read)
36
+ new_conf_hash = Hash[new_conf.map {|key, value| [key, value]}]
37
+
38
+ begin
39
+ ConfigurationPageFacade.ApplyConfigurations(new_conf_hash)
40
+ ConfigurationFileFacade.SaveConfigurations
41
+ rescue StandardError => error
42
+ return [400, { 'Content-Type' => 'text/plain' }, ["Error: #{error.message}"]]
43
+ end
44
+
45
+ return [200, { 'Content-Type' => 'text/plain' }, ["Changes saved successfully"]]
46
+ end
47
+
48
+ end
49
+
50
+ Rack::Handler::Thin.run(LinterServer.new, :Port => 9292)
@@ -10,6 +10,11 @@ class Sin
10
10
  end
11
11
 
12
12
  def ToString
13
- return "<Sin:#{@type[:name]}, Line:#{@begin_line}, Char:#{@begin_char}, Message:#{@type[:message]}, Recommendation:#{@type[:recommendation]}>"
13
+ return "<Sin:#{@type[:name]}, Line:#{@begin_line}, Char:#{@begin_char}, Message:#{@type[:message]}, Recommendation:#{@type[:solution]}>"
14
14
  end
15
+
16
+ def ==(other_object)
17
+ @type == other_object.type && @begin_line == other_object.begin_line && @begin_char == other_object.begin_char && @end_line == other_object.end_line && @end_char == other_object.end_char
18
+ end
19
+
15
20
  end
@@ -0,0 +1,44 @@
1
+ module SinType
2
+ base_url="https://tiagor98.github.io/puppet-sec-lint"
3
+
4
+ HardCodedCred = {
5
+ name: "Hard Coded Credentials",
6
+ message: "Do not hard code secrets. This may help an attacker to attack the system.",
7
+ solution: "#{base_url}/hard-coded-credentials"
8
+ }
9
+ HttpWithoutTLS = {
10
+ name: "HTTP without TLS",
11
+ message: "Do not use HTTP without TLS. This may cause a man in the middle attack.",
12
+ solution: "#{base_url}/http-without-tls"
13
+ }
14
+ AdminByDefault = {
15
+ name: "Admin by default",
16
+ message: "This violates the secure by design principle.",
17
+ solution: "#{base_url}/admin-by-default"
18
+ }
19
+ EmptyPassword = {
20
+ name: "Empty password",
21
+ message: "Do not keep password field empty. This may help an attacker to attack.",
22
+ solution: "#{base_url}/empty-password"
23
+ }
24
+ InvalidIPAddrBinding = {
25
+ name: "Invalid IP Address Binding",
26
+ message: "This config allows connections from every possible network.",
27
+ solution: "#{base_url}/invalid-ip-addr-binding"
28
+ }
29
+ SuspiciousComments = {
30
+ name: "Suspicious Comments",
31
+ message: "This comment can expose sensitive information to attackers.",
32
+ solution: "#{base_url}/suspicious-comments"
33
+ }
34
+ WeakCryptoAlgorithm = {
35
+ name: "Weak Crypto Algorithm",
36
+ message: "Do not use this algorithm, as it may have security weaknesses.",
37
+ solution: "#{base_url}/weak-crypto-algorithm"
38
+ }
39
+ CyrillicHomographAttack = {
40
+ name: "Cyrillic Homograph attack",
41
+ message: "This link has a cyrillic char. These are not rendered by browsers and are sometimes used for phishing attacks.",
42
+ solution: "#{base_url}/cyrillic-homograph-attack"
43
+ }
44
+ end
data/lib/test.txt ADDED
@@ -0,0 +1,15 @@
1
+ jiuhiuhiuh
2
+ ouhiuhiuh
3
+ iuhiuh
4
+ iuhiuhkokok
5
+ kokokokokokokowdijwoidjqwoidjqwodijqdoiqjwdodij
6
+ qwdqwd
7
+ qwdqwddq
8
+ wd
9
+ qwdqwdoijoijoijoij
10
+ oijoijoijoij
11
+ kkkkkkkk
12
+ huiuhiuhiuh
13
+
14
+ kkjjjm
15
+ okpokpok,l,l,l
data/lib/test2.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'rjr/nodes/ws'
2
+
3
+ # listen for methods via amqp, websockets, http, and via local calls
4
+
5
+ ws_node = RJR::Nodes::WS.new :node_id => 'server', :host => '127.0.0.1', :port => 5007
6
+
7
+
8
+ # define a rpc method called 'hello' which takes
9
+ # one argument and returns it in upper case
10
+ ws_node.dispatcher.handle("initialize") { |processId,clientInfo,locale,rootPath,rootUri,capabilities,trace,workspaceFolders|
11
+ arg.upcase
12
+ }
13
+
14
+ # start the server and block
15
+ ws_node.listen
16
+ ws_node.join
data/lib/test3.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'socket' # Get sockets from stdlib
2
+ require 'json'
3
+
4
+ server = TCPServer.open(5007) # Socket to listen on port 2000
5
+
6
+ loop {
7
+ Thread.fork(server.accept) do |client|
8
+ while line=client.gets
9
+ length=Integer(line.scan(/\d/).join(''))
10
+ line=client.read(length+2)
11
+ request = JSON.parse(line)
12
+ puts line
13
+
14
+ response = {
15
+ jsonrpc: request['jsonrpc'],
16
+ result: {
17
+ capabilities: {
18
+ textDocumentSync:1
19
+ }
20
+ },
21
+ id: request['id']
22
+ }
23
+
24
+ response = JSON.generate(response)
25
+
26
+ client.flush
27
+ client.puts("Content-Length: "+response.length.to_s+"\r\n\r\n")
28
+ client.puts(response)
29
+ end
30
+ client.close
31
+ end
32
+ }
data/lib/test_new.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'jimson'
2
+
3
+ class MyHandler
4
+ extend Jimson::Handler
5
+
6
+ def initi(a,b)
7
+ a + b
8
+ end
9
+
10
+ def initialize
11
+ super
12
+ end
13
+
14
+ end
15
+
16
+ server = Jimson::Server.new(MyHandler.new)
17
+ server.port = 5007
18
+ server.host = '127.0.0.1'
19
+ server.start # serve with webrick on http://0.0.0.0:8999/
data/lol2.pp ADDED
@@ -0,0 +1,83 @@
1
+ #class path_attribute {
2
+ # file { 'ssh_config_file':
3
+ # path => '/etc/ssh/sshd_config',
4
+ # content => 'Bad path attribute, bad.',
5
+ # }
6
+ #}
7
+
8
+ # the following code addresses the bujjjg: https://bukkkgs.launchpad.net/keystone/+bug/1472285 .
9
+
10
+ class consul_template::service (
11
+ $pass = lols(3),
12
+ $aijoijooiumihhn_password = 'pe-puppet'
13
+ $admin = 'ceisssesrelometer',
14
+ $aijoijooiumihhn_passuihiuhword = '(adiyu(guygmin',
15
+ ) {
16
+ exec { 'network-restart':
17
+ command => 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDM release-runner key',
18
+ path => '/usr/bin:/usr/sbin:/bin:/sbin',
19
+ refreshonly => true,
20
+ vmware_md5 => 'LOL',
21
+ autho => 'MDi09i09i5',
22
+ cmd => 'virsh secret-define --file ${secret_xml} && virsh secret-set-value --secret ${rbd_secret_uuid} --base64 $(ceph auth get-key client.${user})',
23
+ $auth_uri => 'http://127.0.0.1:5000',
24
+ 'bind_address' => '0.0.0.0',
25
+ passwkkkkord => 'joijoij',
26
+ }
27
+ case $::osfamily {
28
+ 'RedHat': {
29
+ exec { 'upload-img':
30
+ command => "/usr/bin/glance -N ${os_auth_url} -T ${os_tenant_name} -I ${os_username} -K ${os_password} add name=${img_name} is_public=${public} container_format=${container_format} disk_format=${disk_format} distro=${os_name} < /opt/vm/cirros-x86_64-disk.img",
31
+ unless => "/usr/bin/glance -N ${os_auth_url} -T ${os_tenant_name} -I ${os_username} -K ${os_password} index && (/usr/bin/glance -N ${os_auth_url} -T ${os_tenant_name} -I ${os_username} -K ${os_password} index | grep ${img_name})",
32
+
33
+ }
34
+ }
35
+ 'Debian': {
36
+ exec { 'upload-img':
37
+ command => "/usr/bin/glance -N ${os_auth_url} -T ${os_tenant_name} -I ${os_username} -K ${os_password} add name=${img_name} is_public=${public} container_format=${container_format} disk_format=${disk_format} distro=${os_name} < /usr/share/cirros-testvm/cirros-x86_64-disk.img",
38
+ unless => "/usr/bin/glance -N ${os_auth_url} -T ${os_tenant_name} -I ${os_username} -K ${os_password} index && (/usr/bin/glance -N ${os_auth_url} -T ${os_tenant_name} -I ${os_username} -K ${os_password} index | grep ${img_name})",
39
+ kehhhuhy => "E8CC67053ED3B199",
40
+ key_content => '-----BEGIN PGP PUBLIC KEY BLOCK-----
41
+ Version: GnuPG v1.4.11 (GNU/Linux)
42
+
43
+ mQENBE/oXVkBCACcjAcV7lRGskECEHovgZ6a2robpBroQBW+tJds7B+qn/DslOAN
44
+ 1hm0UuGQsi8pNzHDE29FMO3yOhmkenDd1V/T6tHNXqhHvf55nL6anlzwMmq3syIS
45
+ uqVjeMMXbZ4d+Rh0K/rI4TyRbUiI2DDLP+6wYeh1pTPwrleHm5FXBMDbU/OZ5vKZ
46
+ 67j99GaARYxHp8W/be8KRSoV9wU1WXr4+GA6K7ENe2A8PT+jH79Sr4kF4uKC3VxD
47
+ BF5Z0yaLqr+1V2pHU3AfmybOCmoPYviOqpwj3FQ2PhtObLs+hq7zCviDTX2IxHBb
48
+ Q3mGsD8wS9uyZcHN77maAzZlL5G794DEr1NLABEBAAG0NU9wZW5TdGFja0BDaXNj
49
+ byBBUFQgcmVwbyA8b3BlbnN0YWNrLWJ1aWxkZEBjaXNjby5jb20+iQE4BBMBAgAi
50
+ BQJP6F1ZAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRDozGcFPtOxmXcK
51
+ B/9WvQrBwxmIMV2M+VMBhQqtipvJeDX2Uv34Ytpsg2jldl0TS8XheGlUNZ5djxDy
52
+ u3X0hKwRLeOppV09GVO3wGizNCV1EJjqQbCMkq6VSJjD1B/6Tg+3M/XmNaKHK3Op
53
+ zSi+35OQ6xXc38DUOrigaCZUU40nGQeYUMRYzI+d3pPlNd0+nLndrE4rNNFB91dM
54
+ BTeoyQMWd6tpTwz5MAi+I11tCIQAPCSG1qR52R3bog/0PlJzilxjkdShl1Cj0RmX
55
+ 7bHIMD66uC1FKCpbRaiPR8XmTPLv29ZTk1ABBzoynZyFDfliRwQi6TS20TuEj+ZH
56
+ xq/T6MM6+rpdBVz62ek6/KBcuQENBE/oXVkBCACgzyyGvvHLx7g/Rpys1WdevYMH
57
+ THBS24RMaDHqg7H7xe0fFzmiblWjV8V4Yy+heLLV5nTYBQLS43MFvFbnFvB3ygDI
58
+ IdVjLVDXcPfcp+Np2PE8cJuDEE4seGU26UoJ2pPK/IHbnmGWYwXJBbik9YepD61c
59
+ NJ5XMzMYI5z9/YNupeJoy8/8uxdxI/B66PL9QN8wKBk5js2OX8TtEjmEZSrZrIuM
60
+ rVVXRU/1m732lhIyVVws4StRkpG+D15Dp98yDGjbCRREzZPeKHpvO/Uhn23hVyHe
61
+ PIc+bu1mXMQ+N/3UjXtfUg27hmmgBDAjxUeSb1moFpeqLys2AAY+yXiHDv57ABEB
62
+ AAGJAR8EGAECAAkFAk/oXVkCGwwACgkQ6MxnBT7TsZng+AgAnFogD90f3ByTVlNp
63
+ Sb+HHd/cPqZ83RB9XUxRRnkIQmOozUjw8nq8I8eTT4t0Sa8G9q1fl14tXIJ9szzz
64
+ BUIYyda/RYZszL9rHhucSfFIkpnp7ddfE9NDlnZUvavnnyRsWpIZa6hJq8hQEp92
65
+ IQBF6R7wOws0A0oUmME25Rzam9qVbywOh9ZQvzYPpFaEmmjpCRDxJLB1DYu8lnC4
66
+ h1jP1GXFUIQDbcznrR2MQDy5fNt678HcIqMwVp2CJz/2jrZlbSKfMckdpbiWNns/
67
+ xKyLYs5m34d4a0it6wsMem3YCefSYBjyLGSd/kCI/CgOdGN1ZY1HSdLmmjiDkQPQ
68
+ UcXHbA==
69
+ =v6jg
70
+ -----END PGP PUBLIC KEY BLOCK-----',
71
+
72
+ }
73
+ }
74
+ }
75
+ file { '/var/lib/gerrit/.ssh/id_rsa' :
76
+ owner => 'gerrit',
77
+ group => 'gerrit',
78
+ mode => '0600',
79
+ content => $ssh_replication_rsa_key_contents,
80
+ replace => true,
81
+ require => File['/var/lib/gerrit/.ssh']
82
+ }
83
+ }
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.1.2
4
+ version: 0.5.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-04-11 00:00:00.000000000 Z
11
+ date: 2021-05-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: This is a more complete security linter for the puppet language
14
14
  email:
@@ -35,24 +35,49 @@ files:
35
35
  - LICENSE.txt
36
36
  - README.md
37
37
  - Rakefile
38
+ - _config.yml
38
39
  - bin/console
39
40
  - bin/setup
41
+ - docs/404.html
42
+ - docs/Gemfile
43
+ - docs/Gemfile.lock
44
+ - docs/_config.yml
45
+ - docs/_posts/2021-05-03-welcome-to-jekyll.markdown
46
+ - docs/_site/404.html
47
+ - docs/_site/feed.xml
48
+ - docs/_site/index.html
49
+ - docs/_site/jekyll/update/2021/05/03/welcome-to-jekyll.html
50
+ - docs/hard-coded-credentials.md
51
+ - docs/index.md
40
52
  - exe/puppet-sec-lint
41
53
  - lib/configurations/boolean_configuration.rb
42
54
  - lib/configurations/configuration.rb
43
55
  - lib/configurations/list_configuration.rb
56
+ - lib/configurations/regex_configuration.rb
44
57
  - lib/facades/configuration_file_facade.rb
45
58
  - lib/facades/configuration_page_facade.rb
46
- - lib/language_server.rb
47
59
  - lib/lol.pp
48
60
  - lib/puppet-sec-lint/version.rb
49
61
  - lib/rule_engine.rb
62
+ - lib/rules/admin_by_default_rule.rb
63
+ - lib/rules/cyrillic_homograph_attack.rb
64
+ - lib/rules/empty_password_rule.rb
50
65
  - lib/rules/hard_coded_credentials_rule.rb
66
+ - lib/rules/invalid_ip_addr_binding_rule.rb
51
67
  - lib/rules/no_http_rule.rb
52
68
  - lib/rules/rule.rb
53
- - lib/sin.rb
54
- - lib/sin_type.rb
69
+ - lib/rules/suspicious_comment_rule.rb
70
+ - lib/rules/use_weak_crypto_algorithms_rule.rb
71
+ - lib/servers/language_server.rb
72
+ - lib/servers/linter_server.rb
73
+ - lib/sin/sin.rb
74
+ - lib/sin/sin_type.rb
75
+ - lib/test.txt
76
+ - lib/test2.rb
77
+ - lib/test3.rb
78
+ - lib/test_new.rb
55
79
  - lib/visitors/configuration_visitor.rb
80
+ - lol2.pp
56
81
  - puppet-sec-lint.gemspec
57
82
  homepage: https://github.com/TiagoR98/puppet-sec-lint
58
83
  licenses:
@@ -1,78 +0,0 @@
1
- require "rack"
2
- require "thin"
3
- require 'json'
4
- require 'uri'
5
- require_relative 'rule_engine'
6
- require_relative 'visitors/configuration_visitor'
7
- require_relative 'facades/configuration_page_facade'
8
- require_relative 'facades/configuration_file_facade'
9
-
10
- class LanguageServer
11
- ConfigurationVisitor.GenerateIDs
12
- ConfigurationFileFacade.LoadConfigurations
13
-
14
- def call(env)
15
- req = Rack::Request.new(env)
16
-
17
- case req.path
18
- when "/"
19
- if req.post?
20
- process_analysis(req)
21
- end
22
- when "/configuration"
23
- if req.post?
24
- process_form(req)
25
- elsif req.get?
26
- configurations_page
27
- end
28
- end
29
-
30
- end
31
-
32
- def process_form(req)
33
- new_conf = URI.decode_www_form(req.body.read)
34
- new_conf_hash = Hash[new_conf.map {|key, value| [key, value]}]
35
-
36
- ConfigurationPageFacade.ApplyConfigurations(new_conf_hash)
37
- ConfigurationFileFacade.SaveConfigurations
38
-
39
- return [200, { 'Content-Type' => 'text/plain' }, ["Changes saved successfully"]]
40
- end
41
-
42
- def process_analysis(req)
43
- body = JSON.parse(req.body.read)
44
-
45
- if body['documentContent']
46
- code = body['documentContent']
47
-
48
- result_json = []
49
-
50
- result = RuleEngine.analyzeDocument(code) #convert to json
51
-
52
- result.each do |sin|
53
- result_json.append(JSON.generate({
54
- 'name' => sin.type[:name],
55
- 'message' => sin.type[:message],
56
- 'recommendation' => sin.type[:recommendation],
57
- 'begin_line' => sin.begin_line,
58
- 'begin_char' => sin.begin_char,
59
- 'end_line' => sin.end_line,
60
- 'end_char' => sin.end_char
61
- }))
62
- end
63
-
64
- return [200, { 'Content-Type' => 'application/json' }, [result_json.to_json]]
65
- end
66
-
67
- [401, { 'Content-Type' => 'text/html' }, ['Invalid Request']]
68
- end
69
-
70
- def configurations_page
71
- configuration_page = ConfigurationPageFacade.AssemblePage
72
-
73
- return [200, { 'Content-Type' => 'text/html' }, [configuration_page]]
74
- end
75
-
76
- end
77
-
78
- Rack::Handler::Thin.run(LanguageServer.new, :Port => 9292)
data/lib/sin_type.rb DELETED
@@ -1,12 +0,0 @@
1
- module SinType
2
- HardCodedCred = {
3
- name: "Hard Coded Credentials",
4
- message: "Do not hard code secrets. This may help an attacker to attack the system.",
5
- recommendation: "You can use hiera to avoid this issue."
6
- }
7
- HttpWithoutTLS = {
8
- name: "HTTP without TLS",
9
- message: "Do not use HTTP without TLS. This may cause a man in the middle attack.",
10
- recommendation: "Use TLS with HTTP"
11
- }
12
- end