Module: Threatstack::Instrumentation::Frameworks::TSRails::TSActionController

Includes:
Constants
Defined in:
lib/instrumentation/frameworks/rails.rb

Constant Summary collapse

@@logger =
Threatstack::Utils::TSLogger.create 'RailsINST'

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 Method Summary collapse

Methods included from Constants

app_root_dir, env, is_truthy

Instance Method Details

#process_action(*args, &block) ⇒ Object



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
# File 'lib/instrumentation/frameworks/rails.rb', line 53

def process_action(*args, &block)
  # we need the headers hack below because Rails adds a lot of internal headers
  headers = request.headers.each_with_object({}) do |(k, v), obj|
    obj[k] = v if CGI_VARIABLES.include?(k.to_s) || k =~ /^HTTP_/
  end
  @@logger.debug("Incoming request: #{{ :headers => headers, :path => request.path_parameters,
                                        :query => Threatstack::Instrumentation.drop_sensitive_fields(request.query_parameters),
                                        :body => Threatstack::Instrumentation.drop_sensitive_fields(request.request_parameters) }}")
  backtrace = caller.join("\n")

  # check path/query/body parameters
  path_res = Threatstack::Instrumentation.check_parameters(request.path_parameters, 'path', request, headers, backtrace)
  query_res = Threatstack::Instrumentation.check_parameters(request.query_parameters, 'query', request, headers, backtrace)
  body_res = Threatstack::Instrumentation.check_parameters(request.request_parameters, 'body', request, headers, backtrace)

  @@logger.debug "RequestStats -- Path: #{path_res}, Query: #{query_res}, Body: #{body_res}"
  sqli_found = (path_res[:sqli] || query_res[:sqli] || body_res[:sqli])
  xss_found = (path_res[:xss] || query_res[:xss] || body_res[:xss])
  pathtraversal_found = (path_res[:path_traversal] || query_res[:path_traversal] || body_res[:path_traversal])
  # raise an exception if any attack payloads were detected and blocking is enabled
  if (BLOCK_SQLI && sqli_found) || (BLOCK_XSS && xss_found) || (BLOCK_PATH_TRAVERSAL && pathtraversal_found)
    raise Threatstack::Exceptions::RequestBlockedError, REQUEST_BLOCKED
  end

  # continue processing the request normally if no issues were found
  super(*args, &block)
end

#render(*args, &block) ⇒ Object



81
82
83
84
85
86
87
88
89
# File 'lib/instrumentation/frameworks/rails.rb', line 81

def render(*args, &block)
  caller_loc = caller_locations(1, 10) ? caller_locations(1, 10).first : nil
  file_path = caller_loc ? caller_loc.absolute_path : nil
  line_num = caller_loc ? caller_loc.lineno : nil
  # report back all parameters
  Threatstack::Instrumentation.create_instrumentation_event('rails', 'render', file_path, line_num, args)
  # continue processing the request
  super(*args, &block)
end