Class: Threatstack::Jobs::EventSubmitter

Inherits:
Object
  • Object
show all
Includes:
Singleton, Constants
Defined in:
lib/jobs/event_submitter.rb

Overview

Singleton class that creates a job to submit events asynchronously

Constant Summary collapse

SUBMITTER_NAME =
'EventSubmitter'

Constants included from Constants

Constants::AGENT_ID, Constants::AGENT_INSTANCE_ID, Constants::AGENT_NAME, Constants::AGENT_VERSION, Constants::APPSEC_BASE_URL, Constants::APPSEC_EVENTS_URL, Constants::ATTACK, Constants::AWS_METADATA_URL, Constants::BLOCK_PATH_TRAVERSAL, Constants::BLOCK_SQLI, Constants::BLOCK_XSS, Constants::CGI_VARIABLES, Constants::DEPENDENCIES, Constants::DETECTED_NOT_BLOCKED, Constants::DETECT_ATTACKS_ONLY, Constants::DETECT_PATH_TRAVERSAL, Constants::DISABLED, Constants::DROP_FIELDS, Constants::ENVIRONMENT, Constants::EVENTS_PER_REQ, Constants::FILTER_BY_PATH, Constants::INSTRUMENTATION, Constants::IPV4, Constants::IPV6, Constants::JOB_INTERVAL, Constants::LOG_COLORS, Constants::LOG_LEVEL, Constants::MANUAL_INIT, Constants::MAX_QUEUED_EVENTS, Constants::PATH_TRAVERSAL, Constants::REDACTED, Constants::REQUEST_BLOCKED, Constants::ROOT_DIR, Constants::RUBY, Constants::SQLI, Constants::TRUTHY, Constants::XSS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Constants

app_root_dir, env, is_truthy

Constructor Details

#initializeEventSubmitter

Returns a new instance of EventSubmitter.



24
25
26
27
28
# File 'lib/jobs/event_submitter.rb', line 24

def initialize
  @pid = nil
  @mutex = Mutex.new
  @accumulator = Threatstack::Events::EventAccumulator.instance
end

Instance Attribute Details

#jobObject (readonly)

Returns the value of attribute job.



22
23
24
# File 'lib/jobs/event_submitter.rb', line 22

def job
  @job
end

Instance Method Details

#queue_event(event) ⇒ Object



83
84
85
86
# File 'lib/jobs/event_submitter.rb', line 83

def queue_event(event)
  start
  @accumulator.add_event event
end

#startObject

start recurrent job



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/jobs/event_submitter.rb', line 31

def start
  pid = Process.pid
  if @pid != pid
    @mutex.synchronize do
      if @pid != pid
        @logger = Threatstack::Utils::TSLogger.create SUBMITTER_NAME
        @logger.debug 'Launching an EventSubmitter instance'
        # clear events in case the accumulator was forked and already had queued events
        @accumulator.clear_events
        # submit every JOB_INTERVAL seconds
        @job = RecurrentJob.new(@logger, JOB_INTERVAL, 5) { submit }
        @pid = pid
      end
    end
  end
end

#submitObject



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/jobs/event_submitter.rb', line 48

def submit
  # fetch events from the accumulator
  events = @accumulator.remove_events EVENTS_PER_REQ
  if events.empty?
    @logger.debug 'No events to report'
    return
  end
  @logger.debug "Found a total of #{events.length} events"

  # convert payload to JSON
  json_payload = "[#{events.collect(&:to_json_string).join(', ')}]"
  # submit http request
  uri = URI.parse(APPSEC_BASE_URL + APPSEC_EVENTS_URL)
  headers = {
    'Content-Type' => 'application/json',
    'bluefyre-agent-id' => AGENT_ID,
    'bluefyre-agent-instance-id' => AGENT_INSTANCE_ID,
    'bluefyre-agent-version' => AGENT_VERSION,
    'bluefyre-agent-type' => RUBY
  }
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  http.max_retries=0 # don't attempt to retry if the request fails
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  req = Net::HTTP::Post.new(uri.request_uri, headers)
  req.body = json_payload
  @logger.debug "Sending #{events.length} events with payload: #{json_payload}"
  begin
    resp = http.request(req)
    @logger.debug "Sent #{events.length} events, HTTP code: #{resp.code}"
  rescue StandardError => e
    @logger.error "StandardError: #{e.inspect}"
  end
end