Flows — raider 0.2.0a0 documentation

# Flows

Flows are the main concept in Raider, used to define the HTTP information exchange. Each request you want to send needs its own Flow object. Inside the `request` attribute of the object, needs to be a `Request` object containing the definition of the request. This definition can contain `Plugins` whose value will be used when sending the HTTP request.

Flow class holding the information exchanged between server and client.

class Flow(name, request, outputs=None, operations=None)

  Class dealing with the information exchange from HTTP communication.

  A Flow object in Raider defines all the information about one single HTTP information exchange. It has a `name`, contains one `request`, the `response`, the `outputs` that needs to be extracted from the response, and a list of `operations` to be run when the exchange is over.

  Flow objects are used as states in the `Authentication` class to define the authentication process as a finite state machine.

  It’s also used in the `Functions` class to run arbitrary actions when it doesn’t affect the authentication state.

  name

    A string used as a unique identifier for the defined Flow.

  request

    A `Request` object detailing the HTTP request with its elements.

  response

    A `requests.model.Response` object. It’s empty until the request is sent. When the HTTP response arrives, it’s stored here.

  outputs

    A list of `Plugin` objects detailing the pieces of information to be extracted from the response. Those will be later available for other Flow objects.

  operations

    A list of `Operation` objects to be executed after the response is received and outputs are extracted. Should contain a `NextStage` operation if another Flow is expected.

  logger

    A `logging.RootLogger` object used for debugging.

  execute(user, config)

    Sends the request and extracts the outputs.

    Given the user in context and the global Raider configuration, sends the HTTP request and extracts the defined outputs.

    Parameters

      - user (`User`) – An object containing all the user specific data relevant for this action.

      - config (`Config`) – The global Raider configuration.

    Return type

      `None`

  get_outputs()

    Extract the outputs from the HTTP response.

    Iterates through the defined outputs in the Flow object, and extracts the data from the HTTP response, saving it in the respective `Plugin` object.

    Return type

      `None`

  run_operations()

    Runs the defined `operations`.

    Iterates through the defined `operations` and executes them one by one. Iteration stops when the first `NextStage` operations is encountered.

    Return type

      `Optional`[`str`]

    Returns

      A string with the name of the next stage to run or None.

## Examples

Create the variable `initialization` with the Flow. It’ll send a request to the _base_url using the path `admin/`. If the HTTP response code is 200 go to next stage `login`.

    (setv initialization
          (Flow
            :name "initialization"
            :request (Request
                       :method "GET"
                       :path "admin/")
            :operations [(Http
                           :status 200
                           :action (NextStage "login"))]))

Define Flow `login`. It will send a POST request to `https://www.example.com/admin/login` with the username and the password in the body. Extract the cookie `PHPSESSID` and store it in the `session_id` plugin. If server responds with HTTP 200 OK, print `login successfully`, otherwise quit with the error message `login error`.

    (setv username (Variable "username"))
    (setv password (Variable "password"))
    (setv session_id (Cookie "PHPSESSID"))

    (setv login
          (Flow
            :name "login"
            :request (Request
                       :method "POST"
                       :url "https://www.example.com/admin/login"
                       :data
                       {"password" password
                        "username" username})
            :outputs [session_id]
            :operations [(Http
                           :status 200
                           :action (Print "login successfully")
                           :otherwise (Error "login error"))]))

Define another `login` Flow. Here what’s different is the `csrf_name` and `csrf_value` plugins. In this application both the name and the value of the token needs to be extracted, since they change all the time. They were defined as `Html` objects. Later they’re being used in the body of the `Request`.

If the HTTP response code is 200 means the MFA was enabled and the `multi_factor` stage needs to run next. Otherwise, try to log in again. Here the password is asked from the user by a `Prompt`.

    (setv username (Variable "username"))
    (setv password (Prompt "password"))
    (setv session_id (Cookie "PHPSESSID"))

    (setv csrf_name
          (Html
            :name "csrf_name"
            :tag "input"
            :attributes
            {:name "^[0-9A-Fa-f]{10}$"
             :value "^[0-9A-Fa-f]{64}$"
             :type "hidden"}
            :extract "name"))

    (setv csrf_value
          (Html
            :name "csrf_value"
            :tag "input"
            :attributes
            {:name "^[0-9A-Fa-f]{10}$"
             :value "^[0-9A-Fa-f]{64}$"
             :type "hidden"}
            :extract "value"))

    (setv login
          (Flow
            :name "login"
            :request (Request
                       :method "POST"
                       :path "/login.php"
                       :cookies [session_id]
                       :data
                       {"open" "login"
                        "action" "customerlogin"
                        "password" password
                        "username" username
                        "redirect" "myaccount"
                        csrf_name csrf_value})
            :outputs [csrf_name csrf_value]
            :operations [(Http
                           :status 200
                           :action (NextStage "multi_factor")
                           :otherwise (NextStage "login"))]))