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,187 @@
1
+ require_relative 'prepend'
2
+ require_relative 'chain'
3
+
4
+ module NewRelic::Security
5
+ module Instrumentation
6
+ module ActiveRecord::ConnectionAdapters::SQLite3Adapter
7
+
8
+ def execute_on_enter(sql, name)
9
+ event = nil
10
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
11
+ hash = {}
12
+ hash[:sql] = sql #sql query
13
+ hash[:parameters] = []
14
+ event = NewRelic::Security::Agent::Control::Collector.collect(SQL_DB_COMMAND, [hash], SQLITE) 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 execute_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 exec_query_on_enter(*var, **key_vars)
32
+ event = nil
33
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
34
+ type_casted_binds = []
35
+ binds = var[2] #third arg
36
+ if !binds.nil? && !binds.empty? #if bind params present
37
+ binds.each { |x|
38
+ if x.is_a? Integer or x.is_a? String
39
+ type_casted_binds << x
40
+ elsif x.is_a? Array and x[0].is_a? ::ActiveRecord::ConnectionAdapters::Column
41
+ type_casted_binds << x[1].to_s
42
+ else
43
+ type_casted_binds << x.value_before_type_cast.to_s
44
+ end
45
+ }
46
+ # binds_copy = binds.clone #it is a shallow copy
47
+ # type_casted_binds = type_casted_binds(binds_copy.to_s)
48
+ end
49
+ hash = {}
50
+ hash[:sql] = var[0] #sql query
51
+ hash[:parameters] = type_casted_binds #bind params
52
+ event = NewRelic::Security::Agent::Control::Collector.collect(SQL_DB_COMMAND, [hash], SQLITE) unless NewRelic::Security::Instrumentation::InstrumentationUtils.sql_filter_events?(hash[:sql])
53
+ rescue => exception
54
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
55
+ ensure
56
+ yield
57
+ return event
58
+ end
59
+
60
+ def exec_query_on_exit(event)
61
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
62
+ NewRelic::Security::Agent::Utils.create_exit_event(event)
63
+ rescue => exception
64
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
65
+ ensure
66
+ yield
67
+ end
68
+
69
+ def internal_exec_query_on_enter(*var, **key_vars)
70
+ event = nil
71
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
72
+ type_casted_binds = []
73
+ binds = var[2] #third arg
74
+ if !binds.nil? && !binds.empty? #if bind params present
75
+ binds.each { |x|
76
+ if x.is_a? Integer or x.is_a? String
77
+ type_casted_binds << x
78
+ elsif x.is_a? Array and x[0].is_a? ::ActiveRecord::ConnectionAdapters::Column
79
+ type_casted_binds << x[1].to_s
80
+ else
81
+ type_casted_binds << x.value_before_type_cast.to_s
82
+ end
83
+ }
84
+ # binds_copy = binds.clone #it is a shallow copy
85
+ # type_casted_binds = type_casted_binds(binds_copy.to_s)
86
+ end
87
+ hash = {}
88
+ hash[:sql] = var[0] #sql query
89
+ hash[:parameters] = type_casted_binds #bind params
90
+ event = NewRelic::Security::Agent::Control::Collector.collect(SQL_DB_COMMAND, [hash], SQLITE) unless NewRelic::Security::Instrumentation::InstrumentationUtils.sql_filter_events?(hash[:sql])
91
+ rescue => exception
92
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
93
+ ensure
94
+ yield
95
+ return event
96
+ end
97
+
98
+ def internal_exec_query_on_exit(event)
99
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
100
+ NewRelic::Security::Agent::Utils.create_exit_event(event)
101
+ rescue => exception
102
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
103
+ ensure
104
+ yield
105
+ end
106
+
107
+ def exec_update_on_enter(*var, **key_vars)
108
+ event = nil
109
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
110
+ type_casted_binds = []
111
+ binds = var[2] #third arg
112
+ if !binds.nil? && !binds.empty? #if bind params present
113
+ binds.each { |x|
114
+ if x.is_a? Integer or x.is_a? String
115
+ type_casted_binds << x
116
+ elsif x.is_a? Array and x[0].is_a? ::ActiveRecord::ConnectionAdapters::Column
117
+ type_casted_binds << x[1].to_s
118
+ else
119
+ type_casted_binds << x.value_before_type_cast.to_s
120
+ end
121
+ }
122
+ # binds_copy = binds.clone #it is a shallow copy
123
+ # type_casted_binds = type_casted_binds(binds_copy.to_s)
124
+ end
125
+ hash = {}
126
+ hash[:sql] = var[0] #sql query
127
+ hash[:parameters] = type_casted_binds #bind params
128
+ event = NewRelic::Security::Agent::Control::Collector.collect(SQL_DB_COMMAND, [hash], SQLITE) unless NewRelic::Security::Instrumentation::InstrumentationUtils.sql_filter_events?(hash[:sql])
129
+ rescue => exception
130
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
131
+ ensure
132
+ yield
133
+ return event
134
+ end
135
+
136
+ def exec_update_on_exit(event)
137
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
138
+ NewRelic::Security::Agent::Utils.create_exit_event(event)
139
+ rescue => exception
140
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
141
+ ensure
142
+ yield
143
+ end
144
+
145
+ def exec_delete_on_enter(*var, **key_vars)
146
+ event = nil
147
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
148
+ type_casted_binds = []
149
+ binds = var[2] #third arg
150
+ if !binds.nil? && !binds.empty? #if bind params present
151
+ binds.each { |x|
152
+ if x.is_a? Integer or x.is_a? String
153
+ type_casted_binds << x
154
+ elsif x.is_a? Array and x[0].is_a? ::ActiveRecord::ConnectionAdapters::Column
155
+ type_casted_binds << x[1].to_s
156
+ else
157
+ type_casted_binds << x.value_before_type_cast.to_s
158
+ end
159
+ }
160
+ # binds_copy = binds.clone #it is a shallow copy
161
+ # type_casted_binds = type_casted_binds(binds_copy.to_s)
162
+ end
163
+ hash = {}
164
+ hash[:sql] = var[0] #sql query
165
+ hash[:parameters] = type_casted_binds #bind params
166
+ event = NewRelic::Security::Agent::Control::Collector.collect(SQL_DB_COMMAND, [hash], SQLITE) unless NewRelic::Security::Instrumentation::InstrumentationUtils.sql_filter_events?(hash[:sql])
167
+ rescue => exception
168
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
169
+ ensure
170
+ yield
171
+ return event
172
+ end
173
+
174
+ def exec_delete_on_exit(event)
175
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
176
+ NewRelic::Security::Agent::Utils.create_exit_event(event)
177
+ rescue => exception
178
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
179
+ ensure
180
+ yield
181
+ end
182
+
183
+ end
184
+ end
185
+ end
186
+
187
+ NewRelic::Security::Instrumentation::InstrumentationLoader.install_instrumentation(:sqlite3_adapter, ::ActiveRecord::ConnectionAdapters::SQLite3Adapter, ::NewRelic::Security::Instrumentation::ActiveRecord::ConnectionAdapters::SQLite3Adapter)
@@ -0,0 +1,54 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module SQLite3Adapter
6
+ module Prepend
7
+ include NewRelic::Security::Instrumentation::ActiveRecord::ConnectionAdapters::SQLite3Adapter
8
+
9
+ if RUBY_ENGINE == 'jruby'
10
+ def execute(sql, name = nil)
11
+ retval = nil
12
+ event = execute_on_enter(sql, name) { retval = super }
13
+ execute_on_exit(event) { return retval }
14
+ end
15
+
16
+ def exec_update(*var)
17
+ retval = nil
18
+ event = exec_update_on_enter(*var) { retval = super }
19
+ exec_update_on_exit(event) { return retval }
20
+ end
21
+
22
+ def exec_delete(*var)
23
+ retval = nil
24
+ event = exec_delete_on_enter(*var) { retval = super }
25
+ exec_delete_on_exit(event) { return retval }
26
+ end
27
+ end
28
+
29
+ if ::Rails.version < '5'
30
+ def exec_query(*var)
31
+ retval = nil
32
+ event = exec_query_on_enter(*var) { retval = super }
33
+ exec_query_on_exit(event) { return retval }
34
+ end
35
+ else
36
+ def exec_query(*var, **key_vars)
37
+ retval = nil
38
+ event = exec_query_on_enter(*var, **key_vars) { retval = super }
39
+ exec_query_on_exit(event) { return retval }
40
+ end
41
+
42
+ def internal_exec_query(*var, **key_vars)
43
+ retval = nil
44
+ event = internal_exec_query_on_enter(*var, **key_vars) { retval = super }
45
+ internal_exec_query_on_exit(event) { return retval }
46
+ end
47
+ end
48
+
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,21 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module AsyncHttp
4
+ module Chain
5
+ def self.instrument!
6
+ ::Async::HTTP::Internet.class_eval do
7
+ include NewRelic::Security::Instrumentation::AsyncHttp
8
+
9
+ alias_method :call_without_security, :call
10
+
11
+ def call(method, url, headers = nil, body = nil)
12
+ retval = nil
13
+ event = call_on_enter(method, url, headers, body) { retval = call_without_security(method, url, headers, body) }
14
+ call_on_exit(event) { return retval }
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,46 @@
1
+ require_relative 'prepend'
2
+ require_relative 'chain'
3
+ require 'uri'
4
+
5
+ module NewRelic::Security
6
+ module Instrumentation
7
+ module AsyncHttp
8
+
9
+ def call_on_enter(method, url, headers, body)
10
+ event = nil
11
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
12
+ ob = {}
13
+ ob[:Method] = method
14
+ uri = ::URI.parse url
15
+ ob[:scheme] = uri.scheme
16
+ ob[:host] = uri.host
17
+ ob[:port] = uri.port
18
+ ob[:URI] = uri.to_s
19
+ ob[:path] = uri.path
20
+ ob[:query] = uri.query
21
+ ob[:Body] = body.respond_to?(:join) ? body.join.to_s : body.to_s
22
+ ob[:Headers] = headers.to_h
23
+ ob.each { |_, value| value.dup.force_encoding(ISO_8859_1).encode(UTF_8) if value.is_a?(String) }
24
+ event = NewRelic::Security::Agent::Control::Collector.collect(HTTP_REQUEST, [ob])
25
+ NewRelic::Security::Instrumentation::InstrumentationUtils.append_tracing_data(headers, event) if event
26
+ event
27
+ rescue => exception
28
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
29
+ ensure
30
+ yield
31
+ return event
32
+ end
33
+
34
+ def call_on_exit(event)
35
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
36
+ NewRelic::Security::Agent::Utils.create_exit_event(event)
37
+ rescue => exception
38
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
39
+ ensure
40
+ yield
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ NewRelic::Security::Instrumentation::InstrumentationLoader.install_instrumentation(:async_http, ::Async::HTTP::Internet, ::NewRelic::Security::Instrumentation::AsyncHttp)
@@ -0,0 +1,16 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module AsyncHttp
4
+ module Prepend
5
+ include NewRelic::Security::Instrumentation::AsyncHttp
6
+
7
+ def call(method, url, headers = nil, body = nil)
8
+ retval = nil
9
+ event = call_on_enter(method, url, headers, body) { retval = super }
10
+ call_on_exit(event) { return retval }
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,26 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module Curl
4
+ module Multi
5
+ module Chain
6
+
7
+ def self.instrument!
8
+ ::Curl::Multi.class_eval do
9
+ include NewRelic::Security::Instrumentation::Curl::Multi
10
+
11
+ alias_method :perform_without_security, :perform
12
+
13
+ def perform(*args, &block)
14
+ retval = nil
15
+ event = perform_on_enter(*args) { retval = perform_without_security(*args, &block) }
16
+ perform_on_exit(event) { return retval }
17
+ end
18
+
19
+ end
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,52 @@
1
+ require_relative 'prepend'
2
+ require_relative 'chain'
3
+
4
+ module NewRelic::Security
5
+ module Instrumentation
6
+ module Curl::Multi
7
+
8
+ def perform_on_enter(*args)
9
+ event = nil
10
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
11
+ ic_args = []
12
+ self.requests.each {
13
+ |key, req|
14
+ uri = NewRelic::Security::Instrumentation::InstrumentationUtils.parse_uri(req.url)
15
+ ob = {}
16
+ if uri
17
+ ob[:Method] = nil
18
+ ob[:scheme] = uri.scheme
19
+ ob[:host] = uri.host
20
+ ob[:port] = uri.port
21
+ ob[:URI] = uri.to_s
22
+ ob[:path] = uri.path
23
+ ob[:query] = uri.query
24
+ ob[:Body] = req.post_body
25
+ ob[:Headers] = req.headers
26
+ ob.each { |_, value| value.dup.force_encoding(ISO_8859_1).encode(UTF_8) if value.is_a?(String) }
27
+ ic_args.push(ob)
28
+ end
29
+ }
30
+ event = NewRelic::Security::Agent::Control::Collector.collect(HTTP_REQUEST, ic_args)
31
+ self.requests.each { |key, req| NewRelic::Security::Instrumentation::InstrumentationUtils.add_tracing_data(req.headers, event) } if event
32
+ 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
+ return event
38
+ end
39
+
40
+ def perform_on_exit(event)
41
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
42
+ NewRelic::Security::Agent::Utils.create_exit_event(event)
43
+ rescue => exception
44
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
45
+ ensure
46
+ yield
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ NewRelic::Security::Instrumentation::InstrumentationLoader.install_instrumentation(:curb, ::Curl::Multi, ::NewRelic::Security::Instrumentation::Curl::Multi)
@@ -0,0 +1,18 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module Curl
4
+ module Multi
5
+ module Prepend
6
+ include NewRelic::Security::Instrumentation::Curl::Multi
7
+
8
+ def perform(*args, &block)
9
+ retval = nil
10
+ event = perform_on_enter(*args) { retval = super }
11
+ perform_on_exit(event) { return retval }
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,42 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module Dir
4
+ module Chain
5
+
6
+ def self.instrument!
7
+ ::Dir.class_eval do
8
+ class << self
9
+ include ::NewRelic::Security::Instrumentation::Dir
10
+
11
+ alias_method :mkdir_without_security, :mkdir
12
+
13
+ def mkdir(*var)
14
+ retval = nil
15
+ event = mkdir_on_enter(*var) { retval = mkdir_without_security(*var) }
16
+ mkdir_on_exit(event, retval) { return retval }
17
+ end
18
+
19
+ alias_method :rmdir_without_security, :rmdir
20
+
21
+ def rmdir(name)
22
+ retval = nil
23
+ event = rmdir_on_enter(name) { retval = rmdir_without_security(name) }
24
+ rmdir_on_exit(event, retval) { return retval }
25
+ end
26
+
27
+ alias_method :unlink_without_security, :unlink
28
+
29
+ def unlink(name)
30
+ retval = nil
31
+ event = unlink_on_enter(name) { retval = unlink_without_security(name) }
32
+ unlink_on_exit(event, retval) { return retval }
33
+ end
34
+
35
+ end
36
+ end
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,102 @@
1
+ require_relative 'prepend'
2
+ require_relative 'chain'
3
+
4
+ module NewRelic::Security
5
+ module Instrumentation
6
+ module Dir
7
+
8
+ def mkdir_on_enter(*var)
9
+ event = nil
10
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
11
+ fname = var[0]
12
+ abs_path = ::File.expand_path(fname)
13
+ if NewRelic::Security::Instrumentation::InstrumentationUtils.notify_app_integrity_open?(fname, abs_path, WRITE)
14
+ event = NewRelic::Security::Agent::Control::Collector.collect(FILE_INTEGRITY, [fname], WRITE)
15
+ else
16
+ if NewRelic::Security::Instrumentation::InstrumentationUtils.read_filter?(fname, abs_path)
17
+ NewRelic::Security::Agent.logger.debug "Filtered because File name exist in filtered list #{self.class}.#{__method__} Args:: #{fname}"
18
+ else
19
+ event = NewRelic::Security::Agent::Control::Collector.collect(FILE_OPERATION, [fname], WRITE)
20
+ end
21
+ end
22
+ rescue => exception
23
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
24
+ ensure
25
+ yield
26
+ return event
27
+ end
28
+
29
+ def mkdir_on_exit(event, retval)
30
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
31
+ NewRelic::Security::Agent::Utils.create_exit_event(event) if retval.is_a?(Integer)
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
+ def rmdir_on_enter(name)
39
+ event = nil
40
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
41
+ fname = name
42
+ abs_path = ::File.expand_path(fname)
43
+ if NewRelic::Security::Instrumentation::InstrumentationUtils.notify_app_integrity_delete?([fname])
44
+ event = NewRelic::Security::Agent::Control::Collector.collect(FILE_INTEGRITY, [fname], DELETE)
45
+ else
46
+ if NewRelic::Security::Instrumentation::InstrumentationUtils.read_filter?(fname, abs_path)
47
+ NewRelic::Security::Agent.logger.debug "Filtered because File name exist in filtered list #{self.class}.#{__method__} Args:: #{fname}"
48
+ else
49
+ event = NewRelic::Security::Agent::Control::Collector.collect(FILE_OPERATION, [fname], DELETE)
50
+ end
51
+ end
52
+ rescue => exception
53
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
54
+ ensure
55
+ yield
56
+ return event
57
+ end
58
+
59
+ def rmdir_on_exit(event, retval)
60
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
61
+ NewRelic::Security::Agent::Utils.create_exit_event(event) if retval.is_a?(Integer)
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
+ end
67
+
68
+ def unlink_on_enter(*var)
69
+ event = nil
70
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
71
+ fname = var[0]
72
+ abs_path = ::File.expand_path(fname)
73
+ if NewRelic::Security::Instrumentation::InstrumentationUtils.notify_app_integrity_delete?([fname])
74
+ event = NewRelic::Security::Agent::Control::Collector.collect(FILE_INTEGRITY, [fname], DELETE)
75
+ else
76
+ if NewRelic::Security::Instrumentation::InstrumentationUtils.read_filter?(fname, abs_path)
77
+ NewRelic::Security::Agent.logger.debug "Filtered because File name exist in filtered list #{self.class}.#{__method__} Args:: #{fname}"
78
+ else
79
+ event = NewRelic::Security::Agent::Control::Collector.collect(FILE_OPERATION, [fname], DELETE)
80
+ end
81
+ end
82
+ rescue => exception
83
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
84
+ ensure
85
+ yield
86
+ return event
87
+ end
88
+
89
+ def unlink_on_exit(event, retval)
90
+ NewRelic::Security::Agent.logger.debug "OnExit : #{self.class}.#{__method__}"
91
+ NewRelic::Security::Agent::Utils.create_exit_event(event) if retval.is_a?(Integer)
92
+ rescue => exception
93
+ NewRelic::Security::Agent.logger.error "Exception in hook in #{self.class}.#{__method__}, #{exception.inspect}, #{exception.backtrace}"
94
+ ensure
95
+ yield
96
+ end
97
+
98
+ end
99
+ end
100
+ end
101
+
102
+ NewRelic::Security::Instrumentation::InstrumentationLoader.install_instrumentation(:dir, ::Dir.singleton_class, ::NewRelic::Security::Instrumentation::Dir)
@@ -0,0 +1,28 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module Dir
4
+ module Prepend
5
+ include ::NewRelic::Security::Instrumentation::Dir
6
+
7
+ def mkdir(*var)
8
+ retval = nil
9
+ event = mkdir_on_enter(*var) { retval = super }
10
+ mkdir_on_exit(event, retval) { return retval }
11
+ end
12
+
13
+ def rmdir(name)
14
+ retval = nil
15
+ event = rmdir_on_enter(name) { retval = super }
16
+ rmdir_on_exit(event, retval) { return retval }
17
+ end
18
+
19
+ def unlink(name)
20
+ retval = nil
21
+ event = unlink_on_enter(name) { retval = super }
22
+ unlink_on_exit(event, retval) { return retval }
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,53 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module Ethon
4
+ module Easy
5
+ module Chain
6
+ def self.instrument!
7
+ ::Ethon::Easy.class_eval do
8
+ include NewRelic::Security::Instrumentation::Ethon::Easy
9
+
10
+ alias_method :fabricate_without_security, :fabricate
11
+
12
+ def fabricate(url, action_name, options)
13
+ fabricate_on_enter(url, action_name, options) { return fabricate_without_security(url, action_name, options) }
14
+ end
15
+
16
+ alias_method(:headers_equals_without_security, :headers=)
17
+
18
+ def headers=(headers)
19
+ headers_equals_on_enter(headers) { return headers_equals_without_security(headers) }
20
+ end
21
+
22
+ alias_method :perform_without_security, :perform
23
+
24
+ def perform(*args)
25
+ retval = nil
26
+ event = perform_on_enter(*args) { retval = perform_without_security(*args) }
27
+ perform_on_exit(event) { return retval }
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ module Multi
35
+ module Chain
36
+ def self.instrument!
37
+ ::Ethon::Multi.class_eval do
38
+ include NewRelic::Security::Instrumentation::Ethon::Multi
39
+
40
+ alias_method :perform_without_security, :perform
41
+
42
+ def perform(*args)
43
+ retval = nil
44
+ event = perform_on_enter(*args) { retval = perform_without_security(*args) }
45
+ perform_on_exit(event) { return retval }
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end