newrelic_security 0.3.0 → 0.4.1

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/pr_ci.yml +4 -4
  3. data/.github/workflows/release.yml +1 -1
  4. data/.github/workflows/rubocop.yml +1 -1
  5. data/.rubocop_todo.yml +165 -199
  6. data/CHANGELOG.md +32 -0
  7. data/Gemfile_test +4 -0
  8. data/README.md +1 -0
  9. data/lib/newrelic_security/agent/agent.rb +3 -1
  10. data/lib/newrelic_security/agent/configuration/manager.rb +16 -2
  11. data/lib/newrelic_security/agent/control/application_runtime_error.rb +1 -1
  12. data/lib/newrelic_security/agent/control/collector.rb +7 -1
  13. data/lib/newrelic_security/agent/control/control_command.rb +2 -1
  14. data/lib/newrelic_security/agent/control/error_reporting.rb +8 -6
  15. data/lib/newrelic_security/agent/control/event.rb +1 -0
  16. data/lib/newrelic_security/agent/control/event_processor.rb +20 -14
  17. data/lib/newrelic_security/agent/control/event_subscriber.rb +5 -1
  18. data/lib/newrelic_security/agent/control/health_check.rb +1 -0
  19. data/lib/newrelic_security/agent/control/http_context.rb +2 -1
  20. data/lib/newrelic_security/agent/control/iast_client.rb +1 -1
  21. data/lib/newrelic_security/agent/control/reflected_xss.rb +3 -4
  22. data/lib/newrelic_security/agent/control/websocket_client.rb +53 -16
  23. data/lib/newrelic_security/agent/utils/agent_utils.rb +14 -10
  24. data/lib/newrelic_security/instrumentation-security/graphql/chain.rb +26 -0
  25. data/lib/newrelic_security/instrumentation-security/graphql/instrumentation.rb +28 -0
  26. data/lib/newrelic_security/instrumentation-security/graphql/prepend.rb +18 -0
  27. data/lib/newrelic_security/instrumentation-security/io/chain.rb +2 -2
  28. data/lib/newrelic_security/instrumentation-security/io/prepend.rb +1 -1
  29. data/lib/newrelic_security/instrumentation-security/pg/instrumentation.rb +1 -1
  30. data/lib/newrelic_security/instrumentation-security/rack/chain.rb +24 -0
  31. data/lib/newrelic_security/instrumentation-security/rack/instrumentation.rb +44 -0
  32. data/lib/newrelic_security/instrumentation-security/rack/prepend.rb +18 -0
  33. data/lib/newrelic_security/version.rb +1 -1
  34. data/lib/newrelic_security/websocket-client-simple/client.rb +5 -1
  35. metadata +11 -5
@@ -0,0 +1,18 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module GraphQL
4
+ module Query
5
+ module Executor
6
+ module Prepend
7
+ include NewRelic::Security::Instrumentation::GraphQL::Query::Executor
8
+
9
+ def execute
10
+ execute_on_enter { return super }
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -99,9 +99,9 @@ module NewRelic::Security
99
99
 
100
100
  alias_method :popen_without_security, :popen
101
101
 
102
- def popen(*var)
102
+ def popen(*var, &block)
103
103
  retval = nil
104
- event = popen_on_enter(*var) { retval = popen_without_security(*var) }
104
+ event = popen_on_enter(*var) { retval = popen_without_security(*var, &block) }
105
105
  popen_on_exit(event) { return retval }
106
106
  end
107
107
  end
@@ -75,7 +75,7 @@ module NewRelic::Security
75
75
  binwrite_on_exit(event, retval) { return retval }
76
76
  end
77
77
 
78
- def popen(*var)
78
+ def popen(*var, &block)
79
79
  retval = nil
80
80
  event = popen_on_enter(*var) { retval = super }
81
81
  popen_on_exit(event) { return retval }
@@ -75,7 +75,7 @@ module NewRelic::Security
75
75
  NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
76
76
  hash = {}
77
77
  hash[:sql] = NewRelic::Security::Agent::Control::HTTPContext.get_context.cache[args[0].to_s] if NewRelic::Security::Agent::Control::HTTPContext.get_context
78
- hash[:sql] = self.exec("select statement from pg_prepared_statements where name = '#{args[0]}'").getvalue(0,0) unless hash[:sql]
78
+ hash[:sql] = self.exec("select statement from pg_prepared_statements where name = #{escape_literal(args[0].to_s)}").getvalue(0,0) unless hash[:sql]
79
79
  hash[:parameters] = args[1].map(&:to_s)
80
80
  event = NewRelic::Security::Agent::Control::Collector.collect(SQL_DB_COMMAND, [hash], POSTGRES) unless NewRelic::Security::Instrumentation::InstrumentationUtils.sql_filter_events?(hash[:sql])
81
81
  NewRelic::Security::Agent::Control::HTTPContext.get_context.cache.delete(args[0].to_s) if NewRelic::Security::Agent::Control::HTTPContext.get_context
@@ -0,0 +1,24 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module Rack
4
+ module Builder
5
+ module Chain
6
+ def self.instrument!
7
+ ::Rack::Builder.class_eval do
8
+ include NewRelic::Security::Instrumentation::Rack::Builder
9
+
10
+ alias_method :call_without_security, :call
11
+
12
+ def call(env)
13
+ retval = nil
14
+ event = call_on_enter(env) { retval = call_without_security(env) }
15
+ call_on_exit(event, retval) { return retval }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,44 @@
1
+ require_relative 'prepend'
2
+ require_relative 'chain'
3
+
4
+ module NewRelic::Security
5
+ module Instrumentation
6
+ module Rack::Builder
7
+
8
+ def call_on_enter(env)
9
+ event = nil
10
+ NewRelic::Security::Agent.logger.debug "OnEnter : #{self.class}.#{__method__}"
11
+ return unless NewRelic::Security::Agent.config[:enabled]
12
+ NewRelic::Security::Agent.config.update_port = NewRelic::Security::Agent::Utils.app_port(env) unless NewRelic::Security::Agent.config[:listen_port]
13
+ NewRelic::Security::Agent::Utils.get_app_routes(:rack) if NewRelic::Security::Agent.agent.route_map.empty?
14
+ NewRelic::Security::Agent::Control::HTTPContext.set_context(env)
15
+ ctxt = NewRelic::Security::Agent::Control::HTTPContext.get_context
16
+ ctxt.route = "#{env[REQUEST_METHOD]}@#{env[PATH_INFO]}" 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.agent.error_reporting&.report_unhandled_or_5xx_exceptions(NewRelic::Security::Agent::Control::HTTPContext.get_current_transaction, NewRelic::Security::Agent::Control::HTTPContext.get_context, retval[0])
31
+ NewRelic::Security::Agent::Control::HTTPContext.reset_context
32
+ NewRelic::Security::Agent.logger.debug "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
+
39
+ end
40
+
41
+ end
42
+ end
43
+
44
+ NewRelic::Security::Instrumentation::InstrumentationLoader.install_instrumentation(:rack, NewRelic::Security::Agent.config[:app_class].class, ::NewRelic::Security::Instrumentation::Rack::Builder) if NewRelic::Security::Agent.config[:framework] == :rack
@@ -0,0 +1,18 @@
1
+ module NewRelic::Security
2
+ module Instrumentation
3
+ module Rack
4
+ module Builder
5
+ module Prepend
6
+ include NewRelic::Security::Instrumentation::Rack::Builder
7
+
8
+ def call(env, &block)
9
+ retval = nil
10
+ event = call_on_enter(env) { retval = super }
11
+ call_on_exit(event, retval) { return retval }
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,5 @@
1
1
  module NewRelic
2
2
  module Security
3
- VERSION = "0.3.0"
3
+ VERSION = "0.4.1"
4
4
  end
5
5
  end
@@ -72,7 +72,11 @@ module NewRelic::Security
72
72
  end
73
73
  end
74
74
  rescue IOError => e
75
- close false
75
+ if e.inspect =~ /stream closed in another thread/
76
+ close false
77
+ else
78
+ emit :error, e
79
+ end
76
80
  rescue => e
77
81
  emit :error, e
78
82
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newrelic_security
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Prateek Sen
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-20 00:00:00.000000000 Z
11
+ date: 2026-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: newrelic_rpm
@@ -208,6 +208,9 @@ files:
208
208
  - lib/newrelic_security/instrumentation-security/grape/chain.rb
209
209
  - lib/newrelic_security/instrumentation-security/grape/instrumentation.rb
210
210
  - lib/newrelic_security/instrumentation-security/grape/prepend.rb
211
+ - lib/newrelic_security/instrumentation-security/graphql/chain.rb
212
+ - lib/newrelic_security/instrumentation-security/graphql/instrumentation.rb
213
+ - lib/newrelic_security/instrumentation-security/graphql/prepend.rb
211
214
  - lib/newrelic_security/instrumentation-security/grpc/client/chain.rb
212
215
  - lib/newrelic_security/instrumentation-security/grpc/client/instrumentation.rb
213
216
  - lib/newrelic_security/instrumentation-security/grpc/client/prepend.rb
@@ -258,6 +261,9 @@ files:
258
261
  - lib/newrelic_security/instrumentation-security/pty/chain.rb
259
262
  - lib/newrelic_security/instrumentation-security/pty/instrumentation.rb
260
263
  - lib/newrelic_security/instrumentation-security/pty/prepend.rb
264
+ - lib/newrelic_security/instrumentation-security/rack/chain.rb
265
+ - lib/newrelic_security/instrumentation-security/rack/instrumentation.rb
266
+ - lib/newrelic_security/instrumentation-security/rack/prepend.rb
261
267
  - lib/newrelic_security/instrumentation-security/rails/chain.rb
262
268
  - lib/newrelic_security/instrumentation-security/rails/instrumentation.rb
263
269
  - lib/newrelic_security/instrumentation-security/rails/prepend.rb
@@ -324,7 +330,7 @@ metadata:
324
330
  documentation_uri: https://docs.newrelic.com/docs/iast/introduction/
325
331
  source_code_uri: https://github.com/newrelic/csec-ruby-agent
326
332
  homepage_uri: https://github.com/newrelic/csec-ruby-agent
327
- post_install_message:
333
+ post_install_message:
328
334
  rdoc_options: []
329
335
  require_paths:
330
336
  - lib
@@ -340,7 +346,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
340
346
  version: 1.3.1
341
347
  requirements: []
342
348
  rubygems_version: 3.4.19
343
- signing_key:
349
+ signing_key:
344
350
  specification_version: 4
345
351
  summary: Extension for newrelic_rpm with security feature
346
352
  test_files: []