newrelic_security 0.1.0

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.
Files changed (205) hide show
  1. checksums.yaml +7 -0
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  3. data/.github/ISSUE_TEMPLATE/enhancement.md +27 -0
  4. data/.github/actions/simplecov-report/LICENSE +22 -0
  5. data/.github/actions/simplecov-report/README.md +36 -0
  6. data/.github/actions/simplecov-report/__tests__/.keep +0 -0
  7. data/.github/actions/simplecov-report/__tests__/main.test.ts +3 -0
  8. data/.github/actions/simplecov-report/action.yml +25 -0
  9. data/.github/actions/simplecov-report/dist/index.js +10238 -0
  10. data/.github/actions/simplecov-report/dummy_coverage/.last_run.json +5 -0
  11. data/.github/actions/simplecov-report/jest.config.js +11 -0
  12. data/.github/actions/simplecov-report/package.json +51 -0
  13. data/.github/actions/simplecov-report/src/main.ts +54 -0
  14. data/.github/actions/simplecov-report/src/report.ts +28 -0
  15. data/.github/actions/simplecov-report/tsconfig.json +12 -0
  16. data/.github/workflows/pr_ci.yml +77 -0
  17. data/.github/workflows/release.yml +51 -0
  18. data/.github/workflows/repolinter.yml +31 -0
  19. data/.github/workflows/rubocop.yml +17 -0
  20. data/.github/workflows/scripts/rubygems-authenticate.py +13 -0
  21. data/.github/workflows/scripts/rubygems-publish.rb +33 -0
  22. data/.gitignore +72 -0
  23. data/.rubocop.yml +9 -0
  24. data/.rubocop_todo.yml +1414 -0
  25. data/.simplecov +16 -0
  26. data/CHANGELOG.md +69 -0
  27. data/CONTRIBUTING.md +22 -0
  28. data/Gemfile +6 -0
  29. data/Gemfile_test +58 -0
  30. data/LICENSE +43 -0
  31. data/README.md +133 -0
  32. data/README_agent.md +44 -0
  33. data/Rakefile +28 -0
  34. data/THIRD_PARTY_NOTICES.md +36 -0
  35. data/lib/newrelic_security/agent/agent.rb +109 -0
  36. data/lib/newrelic_security/agent/configuration/default_source.rb +8 -0
  37. data/lib/newrelic_security/agent/configuration/environment_source.rb +8 -0
  38. data/lib/newrelic_security/agent/configuration/manager.rb +178 -0
  39. data/lib/newrelic_security/agent/configuration/manual_source.rb +8 -0
  40. data/lib/newrelic_security/agent/configuration/server_source.rb +8 -0
  41. data/lib/newrelic_security/agent/configuration/yaml_source.rb +8 -0
  42. data/lib/newrelic_security/agent/control/app_info.rb +132 -0
  43. data/lib/newrelic_security/agent/control/application_url_mappings.rb +66 -0
  44. data/lib/newrelic_security/agent/control/collector.rb +117 -0
  45. data/lib/newrelic_security/agent/control/control_command.rb +117 -0
  46. data/lib/newrelic_security/agent/control/critical_message.rb +58 -0
  47. data/lib/newrelic_security/agent/control/event.rb +149 -0
  48. data/lib/newrelic_security/agent/control/event_counter.rb +28 -0
  49. data/lib/newrelic_security/agent/control/event_processor.rb +134 -0
  50. data/lib/newrelic_security/agent/control/event_stats.rb +26 -0
  51. data/lib/newrelic_security/agent/control/event_subscriber.rb +28 -0
  52. data/lib/newrelic_security/agent/control/exit_event.rb +38 -0
  53. data/lib/newrelic_security/agent/control/fuzz_request.rb +18 -0
  54. data/lib/newrelic_security/agent/control/grpc_context.rb +57 -0
  55. data/lib/newrelic_security/agent/control/health_check.rb +136 -0
  56. data/lib/newrelic_security/agent/control/http_context.rb +73 -0
  57. data/lib/newrelic_security/agent/control/iast_client.rb +151 -0
  58. data/lib/newrelic_security/agent/control/iast_data_transfer_request.rb +32 -0
  59. data/lib/newrelic_security/agent/control/reflected_xss.rb +258 -0
  60. data/lib/newrelic_security/agent/control/websocket_client.rb +131 -0
  61. data/lib/newrelic_security/agent/logging/init_logger.rb +91 -0
  62. data/lib/newrelic_security/agent/logging/logger.rb +92 -0
  63. data/lib/newrelic_security/agent/logging/null_logger.rb +21 -0
  64. data/lib/newrelic_security/agent/resources/cert.pem +50 -0
  65. data/lib/newrelic_security/agent/utils/agent_utils.rb +219 -0
  66. data/lib/newrelic_security/agent.rb +57 -0
  67. data/lib/newrelic_security/constants.rb +67 -0
  68. data/lib/newrelic_security/instrumentation-security/active_record/mysql2_adapter/chain.rb +70 -0
  69. data/lib/newrelic_security/instrumentation-security/active_record/mysql2_adapter/instrumentation.rb +187 -0
  70. data/lib/newrelic_security/instrumentation-security/active_record/mysql2_adapter/prepend.rb +54 -0
  71. data/lib/newrelic_security/instrumentation-security/active_record/postgresql_adapter/chain.rb +60 -0
  72. data/lib/newrelic_security/instrumentation-security/active_record/postgresql_adapter/instrumentation.rb +143 -0
  73. data/lib/newrelic_security/instrumentation-security/active_record/postgresql_adapter/prepend.rb +48 -0
  74. data/lib/newrelic_security/instrumentation-security/active_record/sqlite3_adapter/chain.rb +72 -0
  75. data/lib/newrelic_security/instrumentation-security/active_record/sqlite3_adapter/instrumentation.rb +187 -0
  76. data/lib/newrelic_security/instrumentation-security/active_record/sqlite3_adapter/prepend.rb +54 -0
  77. data/lib/newrelic_security/instrumentation-security/async-http/chain.rb +21 -0
  78. data/lib/newrelic_security/instrumentation-security/async-http/instrumentation.rb +46 -0
  79. data/lib/newrelic_security/instrumentation-security/async-http/prepend.rb +16 -0
  80. data/lib/newrelic_security/instrumentation-security/curb/chain.rb +26 -0
  81. data/lib/newrelic_security/instrumentation-security/curb/instrumentation.rb +52 -0
  82. data/lib/newrelic_security/instrumentation-security/curb/prepend.rb +18 -0
  83. data/lib/newrelic_security/instrumentation-security/dir/chain.rb +42 -0
  84. data/lib/newrelic_security/instrumentation-security/dir/instrumentation.rb +102 -0
  85. data/lib/newrelic_security/instrumentation-security/dir/prepend.rb +28 -0
  86. data/lib/newrelic_security/instrumentation-security/ethon/chain.rb +53 -0
  87. data/lib/newrelic_security/instrumentation-security/ethon/instrumentation.rb +122 -0
  88. data/lib/newrelic_security/instrumentation-security/ethon/prepend.rb +39 -0
  89. data/lib/newrelic_security/instrumentation-security/excon/chain.rb +23 -0
  90. data/lib/newrelic_security/instrumentation-security/excon/instrumentation.rb +44 -0
  91. data/lib/newrelic_security/instrumentation-security/excon/prepend.rb +17 -0
  92. data/lib/newrelic_security/instrumentation-security/file/chain.rb +34 -0
  93. data/lib/newrelic_security/instrumentation-security/file/instrumentation.rb +62 -0
  94. data/lib/newrelic_security/instrumentation-security/file/prepend.rb +22 -0
  95. data/lib/newrelic_security/instrumentation-security/grape/chain.rb +42 -0
  96. data/lib/newrelic_security/instrumentation-security/grape/instrumentation.rb +56 -0
  97. data/lib/newrelic_security/instrumentation-security/grape/prepend.rb +30 -0
  98. data/lib/newrelic_security/instrumentation-security/grpc/client/chain.rb +47 -0
  99. data/lib/newrelic_security/instrumentation-security/grpc/client/instrumentation.rb +37 -0
  100. data/lib/newrelic_security/instrumentation-security/grpc/client/prepend.rb +36 -0
  101. data/lib/newrelic_security/instrumentation-security/grpc/server/chain.rb +62 -0
  102. data/lib/newrelic_security/instrumentation-security/grpc/server/instrumentation.rb +65 -0
  103. data/lib/newrelic_security/instrumentation-security/grpc/server/prepend.rb +46 -0
  104. data/lib/newrelic_security/instrumentation-security/httpclient/chain.rb +30 -0
  105. data/lib/newrelic_security/instrumentation-security/httpclient/instrumentation.rb +82 -0
  106. data/lib/newrelic_security/instrumentation-security/httpclient/prepend.rb +22 -0
  107. data/lib/newrelic_security/instrumentation-security/httprb/chain.rb +21 -0
  108. data/lib/newrelic_security/instrumentation-security/httprb/instrumentation.rb +44 -0
  109. data/lib/newrelic_security/instrumentation-security/httprb/prepend.rb +16 -0
  110. data/lib/newrelic_security/instrumentation-security/httpx/chain.rb +23 -0
  111. data/lib/newrelic_security/instrumentation-security/httpx/instrumentation.rb +51 -0
  112. data/lib/newrelic_security/instrumentation-security/httpx/prepend.rb +18 -0
  113. data/lib/newrelic_security/instrumentation-security/instrumentation_loader.rb +50 -0
  114. data/lib/newrelic_security/instrumentation-security/instrumentation_utils.rb +165 -0
  115. data/lib/newrelic_security/instrumentation-security/io/chain.rb +113 -0
  116. data/lib/newrelic_security/instrumentation-security/io/instrumentation.rb +300 -0
  117. data/lib/newrelic_security/instrumentation-security/io/prepend.rb +86 -0
  118. data/lib/newrelic_security/instrumentation-security/kernel/chain.rb +65 -0
  119. data/lib/newrelic_security/instrumentation-security/kernel/instrumentation.rb +167 -0
  120. data/lib/newrelic_security/instrumentation-security/kernel/prepend.rb +50 -0
  121. data/lib/newrelic_security/instrumentation-security/mongo/chain.rb +106 -0
  122. data/lib/newrelic_security/instrumentation-security/mongo/instrumentation.rb +273 -0
  123. data/lib/newrelic_security/instrumentation-security/mongo/prepend.rb +77 -0
  124. data/lib/newrelic_security/instrumentation-security/mysql2/chain.rb +53 -0
  125. data/lib/newrelic_security/instrumentation-security/mysql2/instrumentation.rb +84 -0
  126. data/lib/newrelic_security/instrumentation-security/mysql2/prepend.rb +37 -0
  127. data/lib/newrelic_security/instrumentation-security/net_http/chain.rb +21 -0
  128. data/lib/newrelic_security/instrumentation-security/net_http/instrumentation.rb +60 -0
  129. data/lib/newrelic_security/instrumentation-security/net_http/prepend.rb +16 -0
  130. data/lib/newrelic_security/instrumentation-security/net_ldap/chain.rb +21 -0
  131. data/lib/newrelic_security/instrumentation-security/net_ldap/instrumentation.rb +42 -0
  132. data/lib/newrelic_security/instrumentation-security/net_ldap/prepend.rb +16 -0
  133. data/lib/newrelic_security/instrumentation-security/nokogiri/chain.rb +46 -0
  134. data/lib/newrelic_security/instrumentation-security/nokogiri/instrumentation.rb +36 -0
  135. data/lib/newrelic_security/instrumentation-security/nokogiri/prepend.rb +31 -0
  136. data/lib/newrelic_security/instrumentation-security/padrino/chain.rb +26 -0
  137. data/lib/newrelic_security/instrumentation-security/padrino/instrumentation.rb +42 -0
  138. data/lib/newrelic_security/instrumentation-security/padrino/prepend.rb +20 -0
  139. data/lib/newrelic_security/instrumentation-security/patron/chain.rb +23 -0
  140. data/lib/newrelic_security/instrumentation-security/patron/instrumentation.rb +50 -0
  141. data/lib/newrelic_security/instrumentation-security/patron/prepend.rb +18 -0
  142. data/lib/newrelic_security/instrumentation-security/pg/chain.rb +49 -0
  143. data/lib/newrelic_security/instrumentation-security/pg/instrumentation.rb +102 -0
  144. data/lib/newrelic_security/instrumentation-security/pg/prepend.rb +36 -0
  145. data/lib/newrelic_security/instrumentation-security/pty/chain.rb +31 -0
  146. data/lib/newrelic_security/instrumentation-security/pty/instrumentation.rb +52 -0
  147. data/lib/newrelic_security/instrumentation-security/pty/prepend.rb +22 -0
  148. data/lib/newrelic_security/instrumentation-security/rails/chain.rb +46 -0
  149. data/lib/newrelic_security/instrumentation-security/rails/instrumentation.rb +67 -0
  150. data/lib/newrelic_security/instrumentation-security/rails/prepend.rb +33 -0
  151. data/lib/newrelic_security/instrumentation-security/roda/chain.rb +22 -0
  152. data/lib/newrelic_security/instrumentation-security/roda/instrumentation.rb +41 -0
  153. data/lib/newrelic_security/instrumentation-security/roda/prepend.rb +16 -0
  154. data/lib/newrelic_security/instrumentation-security/sinatra/chain.rb +29 -0
  155. data/lib/newrelic_security/instrumentation-security/sinatra/instrumentation.rb +49 -0
  156. data/lib/newrelic_security/instrumentation-security/sinatra/prepend.rb +21 -0
  157. data/lib/newrelic_security/instrumentation-security/sqlite3/chain.rb +79 -0
  158. data/lib/newrelic_security/instrumentation-security/sqlite3/instrumentation.rb +164 -0
  159. data/lib/newrelic_security/instrumentation-security/sqlite3/prepend.rb +56 -0
  160. data/lib/newrelic_security/newrelic-security-api/api.rb +72 -0
  161. data/lib/newrelic_security/version.rb +5 -0
  162. data/lib/newrelic_security/websocket-client-simple/client.rb +128 -0
  163. data/lib/newrelic_security/websocket-client-simple/event_emitter.rb +72 -0
  164. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/error.rb +129 -0
  165. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/exception_handler.rb +32 -0
  166. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame/base.rb +62 -0
  167. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame/data.rb +49 -0
  168. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame/handler/base.rb +41 -0
  169. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame/handler/handler03.rb +224 -0
  170. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame/handler/handler04.rb +18 -0
  171. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame/handler/handler05.rb +15 -0
  172. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame/handler/handler07.rb +78 -0
  173. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame/handler/handler75.rb +78 -0
  174. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame/handler.rb +15 -0
  175. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame/incoming/client.rb +17 -0
  176. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame/incoming/server.rb +17 -0
  177. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame/incoming.rb +52 -0
  178. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame/outgoing/client.rb +17 -0
  179. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame/outgoing/server.rb +17 -0
  180. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame/outgoing.rb +35 -0
  181. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/frame.rb +11 -0
  182. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/base.rb +142 -0
  183. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/client.rb +130 -0
  184. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/handler/base.rb +49 -0
  185. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/handler/client.rb +32 -0
  186. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/handler/client01.rb +20 -0
  187. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/handler/client04.rb +63 -0
  188. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/handler/client11.rb +22 -0
  189. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/handler/client75.rb +39 -0
  190. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/handler/client76.rb +105 -0
  191. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/handler/server.rb +10 -0
  192. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/handler/server04.rb +56 -0
  193. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/handler/server75.rb +40 -0
  194. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/handler/server76.rb +75 -0
  195. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/handler.rb +21 -0
  196. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake/server.rb +179 -0
  197. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/handshake.rb +10 -0
  198. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/nice_inspect.rb +12 -0
  199. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket/version.rb +5 -0
  200. data/lib/newrelic_security/websocket-client-simple/websocket-ruby/lib/websocket.rb +50 -0
  201. data/lib/newrelic_security.rb +6 -0
  202. data/lib/tasks/all.rb +8 -0
  203. data/lib/tasks/coverage_report.rake +27 -0
  204. data/newrelic_security.gemspec +51 -0
  205. metadata +342 -0
@@ -0,0 +1,77 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module Mongo
4
+ module Collection
5
+ module Prepend
6
+ include NewRelic::Security::Instrumentation::Mongo::Collection
7
+
8
+ def find(filter = nil, options = {})
9
+ retval = nil
10
+ event = find_on_enter(filter, options) { retval = super }
11
+ find_on_exit(event) { return retval }
12
+ end
13
+
14
+ def insert_one(document, opts = {})
15
+ retval = nil
16
+ event = insert_one_on_enter(document, opts) { retval = super }
17
+ insert_one_on_exit(event) { return retval }
18
+ end
19
+
20
+ def insert_many(documents, options = {})
21
+ retval = nil
22
+ event = insert_many_on_enter(documents, options) { retval = super }
23
+ insert_many_on_exit(event) { return retval }
24
+ end
25
+ end
26
+
27
+ module View
28
+ module Prepend
29
+ include NewRelic::Security::Instrumentation::Mongo::Collection::View
30
+
31
+ def update_one(spec, opts = {})
32
+ retval = nil
33
+ event = update_one_on_enter(spec, opts) { retval = super }
34
+ update_one_on_exit(event) { return retval }
35
+ end
36
+
37
+ def update_many(spec, opts = {})
38
+ retval = nil
39
+ event = update_many_on_enter(spec, opts) { retval = super }
40
+ update_many_on_exit(event) { return retval }
41
+ end
42
+
43
+ def delete_one(opts = {})
44
+ retval = nil
45
+ event = delete_one_on_enter(opts) { retval = super }
46
+ delete_one_on_exit(event) { return retval }
47
+ end
48
+
49
+ def find_one_and_delete(opts = {})
50
+ retval = nil
51
+ event = find_one_and_delete_on_enter(opts) { retval = super }
52
+ find_one_and_delete_on_exit(event) { return retval }
53
+ end
54
+
55
+ def delete_many(opts = {})
56
+ retval = nil
57
+ event = delete_many_on_enter(opts) { retval = super }
58
+ delete_many_on_exit(event) { return retval }
59
+ end
60
+
61
+ def replace_one(replacement, opts = {})
62
+ retval = nil
63
+ event = replace_one_on_enter(replacement, opts) { retval = super }
64
+ replace_one_on_exit(event) { return retval }
65
+ end
66
+
67
+ def find_one_and_update(document, opts = {})
68
+ retval = nil
69
+ event = find_one_and_update_on_enter(document, opts) { retval = super }
70
+ find_one_and_update_on_exit(event) { return retval }
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,53 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module Mysql2
4
+
5
+ module Client
6
+ module Chain
7
+ def self.instrument!
8
+ ::Mysql2::Client.class_eval do
9
+ include NewRelic::Security::Instrumentation::Mysql2::Client
10
+
11
+ alias_method :query_without_security, :query
12
+
13
+ def query(sql, options = {})
14
+ retval = nil
15
+ event = query_on_enter(sql, options) { retval = query_without_security(sql, options) }
16
+ query_on_exit(event) { return retval }
17
+ end
18
+
19
+ alias_method :prepare_without_security, :prepare
20
+
21
+ def prepare(sql)
22
+ retval = nil
23
+ event = prepare_on_enter(sql) { retval = prepare_without_security(sql) }
24
+ prepare_on_exit(event, retval, sql) { return retval }
25
+ end
26
+
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ module Statement
33
+ module Chain
34
+
35
+ def self.instrument!
36
+ ::Mysql2::Statement.class_eval do
37
+ include NewRelic::Security::Instrumentation::Mysql2::Statement
38
+
39
+ alias_method :execute_without_security, :execute
40
+
41
+ def execute(*args, **kwargs)
42
+ retval = nil
43
+ event = execute_on_enter(*args, **kwargs) { retval = execute_without_security(*args, **kwargs) }
44
+ execute_on_exit(event) { return retval }
45
+ end
46
+
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,84 @@
1
+ require_relative 'prepend'
2
+ require_relative 'chain'
3
+
4
+ module NewRelic::Security
5
+ module Instrumentation
6
+ module Mysql2::Client
7
+
8
+ def query_on_enter(sql, options)
9
+ event = nil
10
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
11
+ hash = {}
12
+ hash[:sql] = sql
13
+ hash[:parameters] = []
14
+ event = NewRelic::Security::Agent::Control::Collector.collect(SQL_DB_COMMAND, [hash], MYSQL) unless NewRelic::Security::Instrumentation::InstrumentationUtils.sql_filter_events?(hash[:sql])
15
+ rescue => exception
16
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
17
+ ensure
18
+ yield
19
+ return event
20
+ end
21
+
22
+ def query_on_exit(event)
23
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
24
+ NewRelic::Security::Agent::Utils.create_exit_event(event)
25
+ rescue => exception
26
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
27
+ ensure
28
+ yield
29
+ end
30
+
31
+ def prepare_on_enter(sql)
32
+ event = nil
33
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
34
+ rescue => exception
35
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
36
+ ensure
37
+ yield
38
+ return event
39
+ end
40
+
41
+ def prepare_on_exit(event, retval, sql)
42
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
43
+ NewRelic::Security::Agent::Control::HTTPContext.get_context.cache[retval.object_id] = sql if NewRelic::Security::Agent::Control::HTTPContext.get_context
44
+ rescue => exception
45
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
46
+ ensure
47
+ yield
48
+ end
49
+
50
+ end
51
+
52
+ module Mysql2::Statement
53
+
54
+ def execute_on_enter(*args, **kwargs)
55
+ event = nil
56
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
57
+ hash = {}
58
+ hash[:sql] = NewRelic::Security::Agent::Control::HTTPContext.get_context.cache[self.object_id] if NewRelic::Security::Agent::Control::HTTPContext.get_context
59
+ hash[:parameters] = args.map(&:to_s)
60
+ event = NewRelic::Security::Agent::Control::Collector.collect(SQL_DB_COMMAND, [hash], MYSQL) unless NewRelic::Security::Instrumentation::InstrumentationUtils.sql_filter_events?(hash[:sql])
61
+ NewRelic::Security::Agent::Control::HTTPContext.get_context.cache.delete(self.object_id) if NewRelic::Security::Agent::Control::HTTPContext.get_context
62
+ rescue => exception
63
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
64
+ ensure
65
+ yield
66
+ return event
67
+ end
68
+
69
+ def execute_on_exit(event)
70
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
71
+ NewRelic::Security::Agent::Utils.create_exit_event(event)
72
+ rescue => exception
73
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
74
+ ensure
75
+ yield
76
+ end
77
+
78
+ end
79
+
80
+ end
81
+ end
82
+
83
+ NewRelic::Security::Instrumentation::InstrumentationLoader.install_instrumentation(:mysql2, ::Mysql2::Client, ::NewRelic::Security::Instrumentation::Mysql2::Client)
84
+ NewRelic::Security::Instrumentation::InstrumentationLoader.install_instrumentation(:mysql2, ::Mysql2::Statement, ::NewRelic::Security::Instrumentation::Mysql2::Statement)
@@ -0,0 +1,37 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module Mysql2
4
+ module Client
5
+ module Prepend
6
+ include NewRelic::Security::Instrumentation::Mysql2::Client
7
+
8
+ def query(sql, options = {})
9
+ retval = nil
10
+ event = query_on_enter(sql, options) { retval = super }
11
+ query_on_exit(event) { return retval }
12
+ end
13
+
14
+ def prepare(sql)
15
+ retval = nil
16
+ event = prepare_on_enter(sql) { retval = super }
17
+ prepare_on_exit(event, retval, sql) { return retval }
18
+ end
19
+
20
+ end
21
+ end
22
+
23
+ module Statement
24
+ module Prepend
25
+ include NewRelic::Security::Instrumentation::Mysql2::Statement
26
+
27
+ def execute(*args, **kwargs)
28
+ retval = nil
29
+ event = execute_on_enter(*args, **kwargs) { retval = super }
30
+ execute_on_exit(event) { return retval }
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,21 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module NetHTTP
4
+ module Chain
5
+ def self.instrument!
6
+ ::Net::HTTP.class_eval do
7
+ include NewRelic::Security::Instrumentation::NetHTTP
8
+
9
+ alias_method :transport_request_without_security, :transport_request
10
+
11
+ def transport_request(req, &block)
12
+ retval = nil
13
+ event = transport_request_on_enter(req) { retval = transport_request_without_security(req, &block) }
14
+ transport_request_on_exit(event) { return retval }
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,60 @@
1
+ require_relative 'prepend'
2
+ require_relative 'chain'
3
+
4
+ module NewRelic::Security
5
+ module Instrumentation
6
+ module NetHTTP
7
+
8
+ HTTP = 'http'
9
+ HTTP_COLON_SLASH_SLAH = 'http://'
10
+ HTTPS_COLON_SLASH_SLAH = 'https://'
11
+
12
+
13
+ def transport_request_on_enter(req)
14
+ event = nil
15
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
16
+ ob = {}
17
+ ob[:Method] = req.method
18
+ if req.uri != nil && URI === req.uri
19
+ uri = req.uri
20
+ ob[:scheme] = uri.scheme
21
+ ob[:host] = uri.host
22
+ ob[:port] = uri.port
23
+ ob[:URI] = uri.to_s
24
+ ob[:path] = uri.path
25
+ ob[:query] = uri.query
26
+ else
27
+ ob[:scheme] = self.use_ssl? ? HTTPS : HTTP
28
+ ob[:host] = self.address
29
+ ob[:port] = self.port
30
+ ob[:path] = req.path
31
+ ob[:query] = nil
32
+ ob[:URI] = "#{self.use_ssl? ? HTTPS_COLON_SLASH_SLAH : HTTP_COLON_SLASH_SLAH }#{self.address}:#{self.port}#{req.path}"
33
+ end
34
+ ob[:Body] = req.body
35
+ ob[:Headers] = req.to_hash.transform_values! { |v| v.join}
36
+ ob.each { |_, value| value.dup.force_encoding(ISO_8859_1).encode(UTF_8) if value.is_a?(String) }
37
+ event = NewRelic::Security::Agent::Control::Collector.collect(HTTP_REQUEST, [ob])
38
+ NewRelic::Security::Instrumentation::InstrumentationUtils.add_tracing_data(req, event) if event
39
+ ob = nil
40
+ event
41
+ rescue => exception
42
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
43
+ ensure
44
+ yield
45
+ return event
46
+ end
47
+
48
+ def transport_request_on_exit(event)
49
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
50
+ NewRelic::Security::Agent::Utils.create_exit_event(event)
51
+ rescue => exception
52
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
53
+ ensure
54
+ yield
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ NewRelic::Security::Instrumentation::InstrumentationLoader.install_instrumentation(:net_http, ::Net::HTTP, ::NewRelic::Security::Instrumentation::NetHTTP)
@@ -0,0 +1,16 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module NetHTTP
4
+ module Prepend
5
+ include NewRelic::Security::Instrumentation::NetHTTP
6
+
7
+ def transport_request(req, &block)
8
+ retval = nil
9
+ event = transport_request_on_enter(req) { retval = super }
10
+ transport_request_on_exit(event) { return retval }
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module NetLDAP
4
+ module Chain
5
+ def self.instrument!
6
+ ::Net::LDAP.class_eval do
7
+ include NewRelic::Security::Instrumentation::NetLDAP
8
+
9
+ alias_method :search_without_security, :search
10
+
11
+ def search(args = {}, &block)
12
+ retval = nil
13
+ event = search_on_enter(args) { retval = search_without_security(args, &block) }
14
+ search_on_exit(event) { return retval }
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,42 @@
1
+ require_relative 'prepend'
2
+ require_relative 'chain'
3
+
4
+ module NewRelic::Security
5
+ module Instrumentation
6
+ module NetLDAP
7
+
8
+ def search_on_enter(args)
9
+ event = nil
10
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
11
+ if args.key?(:base) && !args[:base].empty?
12
+ hash = {}
13
+ hash[:name] = args[:base] if args.key?(:base)
14
+ hash[:filter] = args[:filter] if args.key?(:filter)
15
+ event = NewRelic::Security::Agent::Control::Collector.collect(LDAP, [hash])
16
+ else
17
+ #some times this method is also used during instance creation
18
+ # to know the capabilities of Ldap server. In these
19
+ # situations they don't provide the query parameter, so we filter
20
+ # this event
21
+ NewRelic::Security::Agent.logger.info "Filtered #{self.class}.#{__method__} because of insufficient args. args : #{args}\n"
22
+ end
23
+ rescue => exception
24
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
25
+ ensure
26
+ yield
27
+ return event
28
+ end
29
+
30
+ def search_on_exit(event)
31
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
32
+ NewRelic::Security::Agent::Utils.create_exit_event(event)
33
+ rescue => exception
34
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
35
+ ensure
36
+ yield
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ NewRelic::Security::Instrumentation::InstrumentationLoader.install_instrumentation(:net_ldap, ::Net::LDAP, ::NewRelic::Security::Instrumentation::NetLDAP)
@@ -0,0 +1,16 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module NetLDAP
4
+ module Prepend
5
+ include NewRelic::Security::Instrumentation::NetLDAP
6
+
7
+ def search(args = {}, &block)
8
+ retval = nil
9
+ event = search_on_enter(args) { retval = super }
10
+ search_on_exit(event) { return retval }
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,46 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module Nokogiri
4
+ module XML
5
+ module Node
6
+ module Chain
7
+ def self.instrument!
8
+ ::Nokogiri::XML::Node.class_eval do
9
+ include NewRelic::Security::Instrumentation::Nokogiri::XML
10
+
11
+ alias_method :xpath_without_security, :xpath
12
+
13
+ def xpath(*var)
14
+ retval = nil
15
+ event = xpath_on_enter(*var) { retval = xpath_without_security(*var) }
16
+ xpath_on_exit(event) { return retval }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ module Nokogiri
25
+ module XML
26
+ module NodeSet
27
+ module Chain
28
+ def self.instrument!
29
+ ::Nokogiri::XML::NodeSet.class_eval do
30
+ include NewRelic::Security::Instrumentation::Nokogiri::XML
31
+
32
+ alias_method :xpath_without_security, :xpath
33
+
34
+ def xpath(*var)
35
+ retval = nil
36
+ event = xpath_on_enter(*var) { retval = xpath_without_security(*var) }
37
+ xpath_on_exit(event) { return retval }
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,36 @@
1
+ require_relative 'prepend'
2
+ require_relative 'chain'
3
+
4
+ module NewRelic::Security
5
+ module Instrumentation
6
+ module Nokogiri::XML
7
+
8
+ def xpath_on_enter(*var)
9
+ event = nil
10
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
11
+ paths, _, _, binds = extract_params(var)
12
+ hash = { :paths => paths, :variables => binds }
13
+ event = NewRelic::Security::Agent::Control::Collector.collect(XPATH, [hash])
14
+ rescue => exception
15
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
16
+ ensure
17
+ yield
18
+ return event
19
+ end
20
+
21
+ def xpath_on_exit(event)
22
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
23
+ NewRelic::Security::Agent::Utils.create_exit_event(event)
24
+ rescue => exception
25
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
26
+ ensure
27
+ yield
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ NewRelic::Security::Instrumentation::InstrumentationLoader.install_instrumentation(:nokogiri, ::Nokogiri::XML::Node, ::NewRelic::Security::Instrumentation::Nokogiri::XML::Node)
34
+ NewRelic::Security::Instrumentation::InstrumentationLoader.install_instrumentation(:nokogiri, ::Nokogiri::XML::NodeSet, ::NewRelic::Security::Instrumentation::Nokogiri::XML::NodeSet)
35
+
36
+ # TODO: check if this hook can replace both the hooks, Nokogiri::XML::Searchable#xpath
@@ -0,0 +1,31 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module Nokogiri
4
+ module XML
5
+ module Node
6
+ module Prepend
7
+ include NewRelic::Security::Instrumentation::Nokogiri::XML
8
+
9
+ def xpath(*var)
10
+ retval = nil
11
+ event = xpath_on_enter(*var) { retval = super }
12
+ xpath_on_exit(event) { return retval }
13
+ end
14
+ end
15
+ end
16
+
17
+ module NodeSet
18
+ module Prepend
19
+ include NewRelic::Security::Instrumentation::Nokogiri::XML
20
+
21
+ def xpath(*var)
22
+ retval = nil
23
+ event = xpath_on_enter(*var) { retval = super }
24
+ xpath_on_exit(event) { return retval }
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module Padrino
4
+ module PathRouter
5
+ module Router
6
+ module Chain
7
+ def self.instrument!
8
+ ::Padrino::PathRouter::Router.class_eval do
9
+ include NewRelic::Security::Instrumentation::Padrino::PathRouter::Router
10
+
11
+ alias_method :call_without_security, :call
12
+
13
+ def call(env, &block)
14
+ retval = nil
15
+ event = call_on_enter(env) { retval = call_without_security(env, &block) }
16
+ call_on_exit(event, retval) { return retval }
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,42 @@
1
+ require_relative 'prepend'
2
+ require_relative 'chain'
3
+
4
+ module NewRelic::Security
5
+ module Instrumentation
6
+ module Padrino::PathRouter::Router
7
+
8
+ def call_on_enter(env)
9
+ event = nil
10
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
11
+ NewRelic::Security::Agent.config.update_port = NewRelic::Security::Agent::Utils.app_port(env) unless NewRelic::Security::Agent.config[:listen_port]
12
+ NewRelic::Security::Agent::Utils.get_app_routes(:padrino, self) if NewRelic::Security::Agent.agent.route_map.empty?
13
+ extracted_env = env.instance_variable_get(:@env)
14
+ NewRelic::Security::Agent::Control::HTTPContext.set_context(extracted_env)
15
+ ctxt = NewRelic::Security::Agent::Control::HTTPContext.get_context
16
+ ctxt.route = "#{extracted_env[REQUEST_METHOD].to_s}@#{extracted_env[PATH_INFO].to_s}" if ctxt
17
+ NewRelic::Security::Agent::Utils.parse_fuzz_header(NewRelic::Security::Agent::Control::HTTPContext.get_context)
18
+ rescue => exception
19
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
20
+ ensure
21
+ yield
22
+ return event
23
+ end
24
+
25
+ def call_on_exit(event, retval)
26
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
27
+ # NewRelic::Security::Agent.logger.debug "\n\nHTTP Context : #{::NewRelic::Agent::Tracer.current_transaction.instance_variable_get(:@security_context_data).inspect}\n\n"
28
+ NewRelic::Security::Agent::Control::ReflectedXSS.check_xss(NewRelic::Security::Agent::Control::HTTPContext.get_context, retval) if NewRelic::Security::Agent.config[:'security.detection.rxss.enabled']
29
+ NewRelic::Security::Agent::Utils.delete_created_files(NewRelic::Security::Agent::Control::HTTPContext.get_context)
30
+ NewRelic::Security::Agent::Control::HTTPContext.reset_context
31
+ NewRelic::Security::Agent.logger.debug "Exit event : #{event}"
32
+ rescue => exception
33
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
34
+ ensure
35
+ yield
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+
42
+ NewRelic::Security::Instrumentation::InstrumentationLoader.install_instrumentation(:padrino, ::Padrino::PathRouter::Router, ::NewRelic::Security::Instrumentation::Padrino::PathRouter::Router)
@@ -0,0 +1,20 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module Padrino
4
+ module PathRouter
5
+ module Router
6
+ module Prepend
7
+ include NewRelic::Security::Instrumentation::Padrino::PathRouter::Router
8
+
9
+ def call(env, &block)
10
+ retval = nil
11
+ event = call_on_enter(env) { retval = super }
12
+ call_on_exit(event, retval) { return retval }
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module Patron
4
+ module Session
5
+ module Chain
6
+ def self.instrument!
7
+ ::Patron::Session.class_eval do
8
+ include NewRelic::Security::Instrumentation::Patron::Session
9
+
10
+ alias_method :request_without_security, :request
11
+
12
+ def request(action, url, headers, options = {})
13
+ retval = nil
14
+ event = request_on_enter(action, url, headers, options) { retval = request_without_security(action, url, headers, options) }
15
+ request_on_exit(event) { return retval }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end