threatstack-agent-ruby 0.2.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.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/LICENSE +6 -0
- data/ext/libinjection/extconf.rb +4 -0
- data/ext/libinjection/libinjection.h +65 -0
- data/ext/libinjection/libinjection.i +13 -0
- data/ext/libinjection/libinjection_html5.c +850 -0
- data/ext/libinjection/libinjection_html5.h +54 -0
- data/ext/libinjection/libinjection_sqli.c +2325 -0
- data/ext/libinjection/libinjection_sqli.h +298 -0
- data/ext/libinjection/libinjection_sqli_data.h +9654 -0
- data/ext/libinjection/libinjection_wrap.c +2393 -0
- data/ext/libinjection/libinjection_xss.c +532 -0
- data/ext/libinjection/libinjection_xss.h +21 -0
- data/lib/constants.rb +110 -0
- data/lib/control.rb +61 -0
- data/lib/events/event_accumulator.rb +36 -0
- data/lib/events/models/attack_event.rb +58 -0
- data/lib/events/models/base_event.rb +41 -0
- data/lib/events/models/dependency_event.rb +93 -0
- data/lib/events/models/environment_event.rb +93 -0
- data/lib/events/models/instrumentation_event.rb +46 -0
- data/lib/exceptions/request_blocked_error.rb +11 -0
- data/lib/instrumentation/common.rb +172 -0
- data/lib/instrumentation/instrumenter.rb +144 -0
- data/lib/instrumentation/kernel.rb +45 -0
- data/lib/instrumentation/rails.rb +61 -0
- data/lib/jobs/delayed_job.rb +26 -0
- data/lib/jobs/event_submitter.rb +101 -0
- data/lib/jobs/job_queue.rb +38 -0
- data/lib/jobs/recurrent_job.rb +61 -0
- data/lib/threatstack-agent-ruby.rb +7 -0
- data/lib/utils/aws_utils.rb +46 -0
- data/lib/utils/formatter.rb +47 -0
- data/lib/utils/logger.rb +43 -0
- data/threatstack-agent-ruby.gemspec +35 -0
- metadata +221 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './recurrent_job'
|
4
|
+
|
5
|
+
module Threatstack
|
6
|
+
module Jobs
|
7
|
+
|
8
|
+
class DelayedJob
|
9
|
+
def initialize(name_or_logger, initial_delay = 0, args = nil, &block)
|
10
|
+
@job = RecurrentJob.new(name_or_logger,1, initial_delay, 1, args, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def stop
|
14
|
+
@job.stop
|
15
|
+
end
|
16
|
+
|
17
|
+
def exec_count
|
18
|
+
@job.exec_count
|
19
|
+
end
|
20
|
+
|
21
|
+
def stopped
|
22
|
+
@job.stopped
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
require 'net/https'
|
5
|
+
require 'thread'
|
6
|
+
require 'uri'
|
7
|
+
|
8
|
+
require_relative '../events/event_accumulator'
|
9
|
+
require_relative '../constants'
|
10
|
+
require_relative '../utils/logger'
|
11
|
+
require_relative './recurrent_job'
|
12
|
+
|
13
|
+
module Threatstack
|
14
|
+
module Jobs
|
15
|
+
# Singleton class that creates a job to submit events asynchronously
|
16
|
+
class EventSubmitter
|
17
|
+
include Singleton
|
18
|
+
include Threatstack::Constants
|
19
|
+
|
20
|
+
SUBMITTER_NAME = 'EventSubmitter'
|
21
|
+
|
22
|
+
attr_reader :job
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
@pid = nil
|
26
|
+
@mutex = Mutex.new
|
27
|
+
@accumulator = Threatstack::Events::EventAccumulator.instance
|
28
|
+
end
|
29
|
+
|
30
|
+
# start recurrent job
|
31
|
+
def start
|
32
|
+
pid = Process.pid
|
33
|
+
if @pid != pid
|
34
|
+
@mutex.synchronize do
|
35
|
+
if @pid != pid
|
36
|
+
@logger = Threatstack::Utils::TSLogger.create SUBMITTER_NAME
|
37
|
+
@logger.debug 'Launching an EventSubmitter instance'
|
38
|
+
# clear events in case the accumulator was forked and already had queued events
|
39
|
+
@accumulator.clear_events
|
40
|
+
# submit every JOB_INTERVAL seconds
|
41
|
+
@job = RecurrentJob.new(@logger, JOB_INTERVAL, 5) { submit }
|
42
|
+
@pid = pid
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def submit
|
49
|
+
@logger.debug 'Starting event submission'
|
50
|
+
|
51
|
+
# fetch events from the accumulator
|
52
|
+
events = fetch_events
|
53
|
+
@logger.debug "Found a total of #{events.length} events"
|
54
|
+
|
55
|
+
if events.empty?
|
56
|
+
@logger.debug 'No events to report'
|
57
|
+
return
|
58
|
+
end
|
59
|
+
|
60
|
+
# split events array into groups of EVENTS_PER_REQ
|
61
|
+
events.each_slice(EVENTS_PER_REQ) do |group|
|
62
|
+
# convert payload to JSON
|
63
|
+
json_payload = "[#{group.collect(&:to_json_string).join(', ')}]"
|
64
|
+
# submit http request
|
65
|
+
uri = URI.parse(APPSEC_BASE_URL + APPSEC_EVENTS_URL)
|
66
|
+
headers = {
|
67
|
+
'Content-Type' => 'application/json',
|
68
|
+
'bluefyre-agent-id' => AGENT_ID,
|
69
|
+
'bluefyre-agent-instance-id' => AGENT_INSTANCE_ID
|
70
|
+
}
|
71
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
72
|
+
http.use_ssl = true
|
73
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
74
|
+
req = Net::HTTP::Post.new(uri.request_uri, headers)
|
75
|
+
req.body = json_payload
|
76
|
+
@logger.debug "Sending #{group.length} events with payload: #{json_payload}"
|
77
|
+
begin
|
78
|
+
resp = http.request(req)
|
79
|
+
@logger.debug "Sent #{group.length} events, HTTP code: #{resp.code}"
|
80
|
+
rescue StandardError => e
|
81
|
+
@logger.error "StandardError: #{e.inspect}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def queue_event(event)
|
87
|
+
start
|
88
|
+
@accumulator.add_event event
|
89
|
+
end
|
90
|
+
|
91
|
+
def fetch_events
|
92
|
+
# check total number of events first
|
93
|
+
total_events = @accumulator.events.length
|
94
|
+
return [] unless total_events > 0
|
95
|
+
|
96
|
+
# retrieve events from the accumulator in a thread-safe manner
|
97
|
+
@accumulator.remove_events total_events
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Threatstack
|
4
|
+
module Jobs
|
5
|
+
|
6
|
+
class JobQueue
|
7
|
+
attr_reader :job_queue
|
8
|
+
attr_reader :job_thread
|
9
|
+
attr_reader :stopped
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@stopped = false
|
13
|
+
@job_queue = Queue.new
|
14
|
+
@job_thread = Thread.new do
|
15
|
+
# Fetch an item from the worker queue, or wait until one is available
|
16
|
+
while (job = @job_queue.pop)
|
17
|
+
Thread.stop if @stopped
|
18
|
+
job[:action].call(job[:args])
|
19
|
+
end
|
20
|
+
@stopped = true
|
21
|
+
Thread.stop
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_job(args = nil, &block)
|
26
|
+
raise 'Invalid proc provided' unless block_given?
|
27
|
+
|
28
|
+
@job_queue.push(:action => block, :args => args)
|
29
|
+
end
|
30
|
+
|
31
|
+
def stop
|
32
|
+
@stopped = true
|
33
|
+
# push nil to stop the while loop
|
34
|
+
add_job nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thread/every'
|
4
|
+
|
5
|
+
require_relative '../utils/logger'
|
6
|
+
|
7
|
+
module Threatstack
|
8
|
+
module Jobs
|
9
|
+
|
10
|
+
class RecurrentJob
|
11
|
+
attr_reader :exec_count
|
12
|
+
attr_reader :stopped
|
13
|
+
attr_reader :logger
|
14
|
+
|
15
|
+
def initialize(name_or_logger, repeat_every_sec = 10, initial_delay_sec = 0, total_times = nil, args = nil, &block)
|
16
|
+
raise 'Block not specified' unless block_given?
|
17
|
+
|
18
|
+
# create logger or use passed one if available
|
19
|
+
if name_or_logger.respond_to?(:debug) && name_or_logger.respond_to?(:info) && name_or_logger.respond_to?(:error)
|
20
|
+
@logger = name_or_logger
|
21
|
+
else
|
22
|
+
@logger = Threatstack::Utils::TSLogger.create "#{name_or_logger}Job"
|
23
|
+
end
|
24
|
+
|
25
|
+
@stopped = false
|
26
|
+
@exec_count = 0
|
27
|
+
@logger.debug "Creating recurrent job with #{initial_delay_sec} sec delay, repeat every #{repeat_every_sec} sec, #{total_times || 'infinite'} time(s)"
|
28
|
+
Thread.new do
|
29
|
+
# wait before starting
|
30
|
+
sleep initial_delay_sec
|
31
|
+
# repeat every X secs
|
32
|
+
Thread.every(repeat_every_sec) do
|
33
|
+
@logger.debug 'Starting job iteration...'
|
34
|
+
# stop if stop method called or exec limit reached
|
35
|
+
if @stopped || (!total_times.nil? && @exec_count == total_times)
|
36
|
+
@logger.debug 'Job stopped'
|
37
|
+
@stopped = true
|
38
|
+
Thread.stop
|
39
|
+
return
|
40
|
+
end
|
41
|
+
# increment
|
42
|
+
@exec_count += 1
|
43
|
+
# perform main action
|
44
|
+
begin
|
45
|
+
@logger.debug 'Calling job action'
|
46
|
+
block.call args
|
47
|
+
@logger.debug 'Job action called'
|
48
|
+
rescue StandardError => e
|
49
|
+
@logger.error "StandardError in job action: #{e.inspect}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def stop
|
56
|
+
@logger.debug 'Stopping recurrent job'
|
57
|
+
@stopped = true
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require_relative './logger'
|
6
|
+
require_relative '../constants'
|
7
|
+
|
8
|
+
module Threatstack
|
9
|
+
module Utils
|
10
|
+
class Aws
|
11
|
+
include Singleton
|
12
|
+
include Threatstack::Constants
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@logger = Threatstack::Utils::TSLogger.create 'AwsUtils'
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_aws_metadata
|
19
|
+
aws_metadata = {}
|
20
|
+
timeout = 5 # secs
|
21
|
+
|
22
|
+
begin
|
23
|
+
# prepare request
|
24
|
+
@logger.debug 'Preparing request to fetch AWS metadata'
|
25
|
+
aws_uri = URI(AWS_METADATA_URL)
|
26
|
+
http = Net::HTTP.new(aws_uri.host, aws_uri.port)
|
27
|
+
http.open_timeout = timeout
|
28
|
+
http.read_timeout = timeout
|
29
|
+
# http.keep_alive_timeout = 2
|
30
|
+
req = Net::HTTP::Get.new(aws_uri.path)
|
31
|
+
# fire request
|
32
|
+
@logger.debug 'Firing request to fetch AWS metadata'
|
33
|
+
resp = http.request(req)
|
34
|
+
@logger.debug "AWS metadata request HTTP code #{resp.code} and response: #{resp.body}"
|
35
|
+
# convert response to hash
|
36
|
+
aws_metadata = resp.body ? JSON.parse(resp.body) : aws_metadata
|
37
|
+
rescue StandardError => e
|
38
|
+
@logger.error "StandardError: #{e.inspect}"
|
39
|
+
end
|
40
|
+
|
41
|
+
# return
|
42
|
+
aws_metadata
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Threatstack
|
4
|
+
module Utils
|
5
|
+
class TSFormatter
|
6
|
+
def regular(str)
|
7
|
+
"\e[00m#{str}\e[0m"
|
8
|
+
end
|
9
|
+
|
10
|
+
def bright(str)
|
11
|
+
"\e[01m#{str}\e[0m"
|
12
|
+
end
|
13
|
+
|
14
|
+
def black(str)
|
15
|
+
"\e[30m#{str}\e[0m"
|
16
|
+
end
|
17
|
+
|
18
|
+
def red(str)
|
19
|
+
"\e[31m#{str}\e[0m"
|
20
|
+
end
|
21
|
+
|
22
|
+
def green(str)
|
23
|
+
"\e[32m#{str}\e[0m"
|
24
|
+
end
|
25
|
+
|
26
|
+
def yellow(str)
|
27
|
+
"\e[33m#{str}\e[0m"
|
28
|
+
end
|
29
|
+
|
30
|
+
def blue(str)
|
31
|
+
"\e[34m#{str}\e[0m"
|
32
|
+
end
|
33
|
+
|
34
|
+
def magenta(str)
|
35
|
+
"\e[35m#{str}\e[0m"
|
36
|
+
end
|
37
|
+
|
38
|
+
def cyan(str)
|
39
|
+
"\e[36m#{str}\e[0m"
|
40
|
+
end
|
41
|
+
|
42
|
+
def gray(str)
|
43
|
+
"\e[37m#{str}\e[0m"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/utils/logger.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
require_relative '../constants'
|
6
|
+
require_relative './formatter'
|
7
|
+
|
8
|
+
module Threatstack
|
9
|
+
module Utils
|
10
|
+
module TSLogger
|
11
|
+
def self.create(name)
|
12
|
+
formatter = TSFormatter.new
|
13
|
+
logger = Logger.new STDOUT
|
14
|
+
logger.progname = "TS#{name}"
|
15
|
+
logger.datetime_format = '%FT%T%:z'
|
16
|
+
logger.level = Threatstack::Constants::LOG_LEVEL
|
17
|
+
colors = Threatstack::Constants::LOG_COLORS
|
18
|
+
random_color = ['blue', 'gray', 'green', 'yellow', 'cyan', 'magenta'].sample
|
19
|
+
progname = colors ? formatter.send(random_color, '%16.16s' % logger.progname) : '%16.16s' % logger.progname
|
20
|
+
logger.formatter = proc do |severity, datetime, _progname, msg|
|
21
|
+
pid = Process.pid
|
22
|
+
sev_padded = '%5.5s' % severity
|
23
|
+
sev_final = sev_padded
|
24
|
+
if colors
|
25
|
+
pid = formatter.green pid
|
26
|
+
if severity == 'INFO'
|
27
|
+
sev_final = formatter.cyan sev_padded
|
28
|
+
elsif severity == 'WARN'
|
29
|
+
sev_final = formatter.yellow sev_padded
|
30
|
+
elsif severity == 'ERROR' || severity == 'FATAL'
|
31
|
+
sev_final = formatter.red sev_padded
|
32
|
+
else
|
33
|
+
sev_final = formatter.regular sev_padded
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
"[#{datetime}] #{pid} - #{sev_final} - #{progname}: #{msg}\n"
|
38
|
+
end
|
39
|
+
logger
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'threatstack-agent-ruby'
|
8
|
+
spec.version = '0.2.1'
|
9
|
+
spec.authors = ['Threat Stack Inc']
|
10
|
+
spec.email = ['support@threatstack.com']
|
11
|
+
spec.summary = 'Ruby version of the ThreatStack agent which helps identify security vulnerabilities at runtime'
|
12
|
+
spec.license = 'Threat Stack'
|
13
|
+
spec.homepage = 'https://www.threatstack.com'
|
14
|
+
spec.extra_rdoc_files = [
|
15
|
+
"LICENSE"
|
16
|
+
]
|
17
|
+
|
18
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
19
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^((test|spec|features|)/|Gemfile_release|Rakefile|README.md|.gitlab-ci.yml|.rubocop.yml|Gemfile.lock|.gitignore)}) }
|
20
|
+
end
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
spec.extensions = ['ext/libinjection/extconf.rb']
|
23
|
+
|
24
|
+
spec.add_dependency 'network_interface', '0.0.2'
|
25
|
+
spec.add_dependency 'Platform', '0.4.2'
|
26
|
+
spec.add_dependency 'thread', '0.2.2'
|
27
|
+
|
28
|
+
spec.add_development_dependency 'rubocop'
|
29
|
+
spec.add_development_dependency 'aws-sdk-s3'
|
30
|
+
spec.add_development_dependency 'builder'
|
31
|
+
spec.add_development_dependency 'rake'
|
32
|
+
spec.add_development_dependency 'rspec'
|
33
|
+
spec.add_development_dependency 'simplecov'
|
34
|
+
spec.add_development_dependency 'webmock'
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,221 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: threatstack-agent-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Threat Stack Inc
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-05-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: network_interface
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.0.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.0.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: Platform
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.4.2
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.4.2
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: thread
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.2.2
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.2.2
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: aws-sdk-s3
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: builder
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: simplecov
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: webmock
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description:
|
154
|
+
email:
|
155
|
+
- support@threatstack.com
|
156
|
+
executables: []
|
157
|
+
extensions:
|
158
|
+
- ext/libinjection/extconf.rb
|
159
|
+
extra_rdoc_files:
|
160
|
+
- LICENSE
|
161
|
+
files:
|
162
|
+
- Gemfile
|
163
|
+
- LICENSE
|
164
|
+
- ext/libinjection/extconf.rb
|
165
|
+
- ext/libinjection/libinjection.h
|
166
|
+
- ext/libinjection/libinjection.i
|
167
|
+
- ext/libinjection/libinjection_html5.c
|
168
|
+
- ext/libinjection/libinjection_html5.h
|
169
|
+
- ext/libinjection/libinjection_sqli.c
|
170
|
+
- ext/libinjection/libinjection_sqli.h
|
171
|
+
- ext/libinjection/libinjection_sqli_data.h
|
172
|
+
- ext/libinjection/libinjection_wrap.c
|
173
|
+
- ext/libinjection/libinjection_xss.c
|
174
|
+
- ext/libinjection/libinjection_xss.h
|
175
|
+
- lib/constants.rb
|
176
|
+
- lib/control.rb
|
177
|
+
- lib/events/event_accumulator.rb
|
178
|
+
- lib/events/models/attack_event.rb
|
179
|
+
- lib/events/models/base_event.rb
|
180
|
+
- lib/events/models/dependency_event.rb
|
181
|
+
- lib/events/models/environment_event.rb
|
182
|
+
- lib/events/models/instrumentation_event.rb
|
183
|
+
- lib/exceptions/request_blocked_error.rb
|
184
|
+
- lib/instrumentation/common.rb
|
185
|
+
- lib/instrumentation/instrumenter.rb
|
186
|
+
- lib/instrumentation/kernel.rb
|
187
|
+
- lib/instrumentation/rails.rb
|
188
|
+
- lib/jobs/delayed_job.rb
|
189
|
+
- lib/jobs/event_submitter.rb
|
190
|
+
- lib/jobs/job_queue.rb
|
191
|
+
- lib/jobs/recurrent_job.rb
|
192
|
+
- lib/threatstack-agent-ruby.rb
|
193
|
+
- lib/utils/aws_utils.rb
|
194
|
+
- lib/utils/formatter.rb
|
195
|
+
- lib/utils/logger.rb
|
196
|
+
- threatstack-agent-ruby.gemspec
|
197
|
+
homepage: https://www.threatstack.com
|
198
|
+
licenses:
|
199
|
+
- Threat Stack
|
200
|
+
metadata: {}
|
201
|
+
post_install_message:
|
202
|
+
rdoc_options: []
|
203
|
+
require_paths:
|
204
|
+
- lib
|
205
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
206
|
+
requirements:
|
207
|
+
- - ">="
|
208
|
+
- !ruby/object:Gem::Version
|
209
|
+
version: '0'
|
210
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
211
|
+
requirements:
|
212
|
+
- - ">="
|
213
|
+
- !ruby/object:Gem::Version
|
214
|
+
version: '0'
|
215
|
+
requirements: []
|
216
|
+
rubygems_version: 3.1.2
|
217
|
+
signing_key:
|
218
|
+
specification_version: 4
|
219
|
+
summary: Ruby version of the ThreatStack agent which helps identify security vulnerabilities
|
220
|
+
at runtime
|
221
|
+
test_files: []
|