Module: Aikido::Zen::Sinks::HTTP::Extensions

Defined in:
lib/aikido/zen/sinks/http.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.build_outbound(req) ⇒ Aikido::Zen::OutboundConnection

Maps an HTTP Request to an Aikido OutboundConnection.

Parameters:

  • req (HTTP::Request)

Returns:



19
20
21
22
23
24
# File 'lib/aikido/zen/sinks/http.rb', line 19

def self.build_outbound(req)
  Aikido::Zen::OutboundConnection.new(
    host: req.socket_host,
    port: req.socket_port
  )
end

.wrap_request(req) ⇒ Aikido::Zen::Scanners::SSRFScanner::Request

Wraps the HTTP request with an API we can depend on.

Parameters:

  • req (HTTP::Request)

Returns:



30
31
32
33
34
35
36
# File 'lib/aikido/zen/sinks/http.rb', line 30

def self.wrap_request(req)
  Aikido::Zen::Scanners::SSRFScanner::Request.new(
    verb: req.verb,
    uri: URI(req.uri.to_s),
    headers: req.headers.to_h
  )
end

.wrap_response(resp) ⇒ Object



38
39
40
41
42
43
# File 'lib/aikido/zen/sinks/http.rb', line 38

def self.wrap_response(resp)
  Aikido::Zen::Scanners::SSRFScanner::Response.new(
    status: resp.status,
    headers: resp.headers.to_h
  )
end

Instance Method Details

#perform(req) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/aikido/zen/sinks/http.rb', line 45

def perform(req, *)
  wrapped_request = Extensions.wrap_request(req)

  # Store the request information so the DNS sinks can pick it up.
  if (context = Aikido::Zen.current_context)
    prev_request = context["ssrf.request"]
    context["ssrf.request"] = wrapped_request
  end

  SINK.scan(
    request: wrapped_request,
    connection: Extensions.build_outbound(req),
    operation: "request"
  )

  response = super

  Aikido::Zen::Scanners::SSRFScanner.track_redirects(
    request: wrapped_request,
    response: Extensions.wrap_response(response)
  )

  response
ensure
  context["ssrf.request"] = prev_request if context
end