Plugins — raider 0.2.0a0 documentation

# Plugins

Plugins in Raider are pieces of code that are used to get inputs from, and put them in the HTTP request, and/or to extract some values from the response. This is used to facilitate the information exchange between Flows. Below there’s a list of predefined Plugins. The users are also encouraged to write their own plugins.

## Variable

Use this when the value of the plugin should be extracted from the user data. At the moment only `username` and `password` are working. Future versions will allow adding and accessing arbitrary data from the users.

Example:

    (setv username (Variable "username"))

class Variable(name)

  Plugin to extract the value of a variable.

  For now only the username and password variables are supported. Use this when supplying credentials to the web application.

  extract_variable(data=None)

    Extracts the variable value.

    Given a dictionary with the predefined variables, return the value of the with the same name as the “name” attribute from this Plugin.

    Parameters

      data (`Optional`[`Dict`[`str`, `str`]]) – A dictionary with the predefined variables.

    Return type

      `Optional`[`str`]

    Returns

      A string with the value of the variable found. None if no such variable has been defined.

## Prompt

Prompt plugin should be used when the information is not known in advance, for example when receiving the SMS code.

Example:

    (setv mfa_code (Prompt "Input code here:"))

class Prompt(name)

  Plugin to ask the user for an input.

  Use this plugin when the value cannot be known in advance, for example when asking for multi-factor authentication code that is going to be sent over SMS.

  get_user_prompt()

    Gets the value from user input.

    Creates a prompt asking the user for input and stores the value in the Plugin.

    Return type

      `str`

## Command

Use Command plugin if you want to extract information using a shell command.

Example:

    (setv mfa_code (Command
                    :name "otp"
                    :command "pass otp personal/app1"))

class Command(name, command)

  Runs a shell command and extract the output.

  run_command()

    Runs a command and returns its value.

    Given a dictionary with the predefined variables, return the value of the with the same name as the “name” attribute from this Plugin.

    Parameters

      data – A dictionary with the predefined variables.

    Return type

      `Optional`[`str`]

    Returns

      A string with the value of the variable found. None if no such variable has been defined.

## Cookie

Use Cookie plugin to extract and set new cookies:

Example:

    (setv session_cookie (Cookie "PHPSESSID"))

class Cookie(name, value=None, function=None, flags=2)

  Plugin to deal with HTTP cookies.

  Use this Plugin when dealing with the cookies in the HTTP request.

  __str__()

    Returns a string representation of the cookie.

    Return type

      `str`

  extract_cookie(response)

    Returns the cookie with the specified name from the response.

    Return type

      `Optional`[`str`]

  classmethod from_plugin(name, plugin)

    Creates a Cookie from a Plugin.

    Given another `plugin`, and a name, create a `cookie`.

    Parameters

      - name (`str`) – The cookie name to use.

      - plugin (`Plugin`) – The plugin which will contain the value we need.

    Return type

      `Cookie`

    Returns

      A Cookie object with the name and the plugin’s value.

## Header

Use Header plugin to extract and set new headers. It also allows easier setup for basic and bearer authentication using the provided classmethods.

Example:

    (setv x-header (Header "x-header"))
    (setv y-header (Header "y-header" "y-value"))

    (setv z-header (Header.basicauth "username" "password"))

    (setv access_token
          (Regex
            :name "access_token"
            :regex "\"accessToken\":\"([^\"]+)\""))

    (setv z-header (Header.bearerauth access_token))

class Header(name, value=None, function=None, flags=2)

  Plugin to deal with HTTP headers.

  Use this Plugin when dealing with the headers in the HTTP request.

  __str__()

    Returns a string representation of the Plugin.

    Return type

      `str`

  classmethod basicauth(username, password)

    Creates a basic authentication header.

    Given the username and the password for the basic authentication, returns the Header object with the proper value.

    Parameters

      - username (`str`) – A string with the basic authentication username.

      - password (`str`) – A string with the basic authentication password.

    Return type

      `Header`

    Returns

      A Header object with the encoded basic authentication string.

  classmethod bearerauth(access_token)

    Creates a bearer authentication header.

    Given the access_token as a Plugin, extracts its value and returns a Header object with the correct value to be passed as the Bearer Authorization string in the Header.

    Parameters

      access_token (`Plugin`) – A Plugin containing the value of the token to use.

    Return type

      `Header`

    Returns

      A Header object with the proper bearer authentication string.

  extract_header(response)

    Returns the header with the specified name from the response.

    Return type

      `Optional`[`str`]

  classmethod from_plugin(name, plugin)

    Creates a Header from a Plugin.

    Given another `plugin`, and a name, create a `header`.

    Parameters

      - name (`str`) – The header name to use.

      - plugin (`Plugin`) – The plugin which will contain the value we need.

    Return type

      `Header`

    Returns

      A Header object with the name and the plugin’s value.

## Regex

Use Regex plugin if the data you want extracted can be easily identified with a regular expression. The string matched in between `(` and `)` will be stored as the plugin’s value.

Example:

    (setv access_token
          (Regex
            :name "access_token"
            :regex "\"accessToken\":\"([^\"]+)\""))

class Regex(name, regex, extract=0)

  Plugin to extract something using regular expressions.

  This plugin will match the regex provided, and extract the value inside the matched group, which by default is the first one. A group is the string that matched inside the brackets.

  For example if the regular expression is:

  “accessToken”:”([^”]+)”

  and the text to match it against contains:

  “accessToken”:”0123456789abcdef”

  then only the string “0123456789abcdef” will be extracted and saved in the “value” attribute.

  regex

    A string containing the regular expression to be matched.

  extract

    An integer with the group number that needs to be extracted.

  __str__()

    Returns a string representation of the Plugin.

    Return type

      `str`

  extract_regex(response)

    Extracts defined regular expression from a text.

    Given a text to be searched for matches, return the string inside the group defined in “extract” or the first group if it’s undefined.

    Parameters

      text – A string containing the text to be searched for matches.

    Return type

      `Optional`[`str`]

    Returns

      A string with the match from the extracted group. Returns None if there are no matches.

## Html

Use the Html plugin when the data you want can be easily extracted by parsing HTML tags. Create a new plugin by giving it a name, the tag where the information is located, some attributes to identify whether the tag is the right one, and the name of the tag attribute you want to extract. The attributes are created as a dictionary, and its values can be regular expressions.

Example:

    (setv csrf_token
          (Html
            :name "csrf_token"
            :tag "input"
            :attributes
            {:name "csrf_token"
             :value "^[0-9a-f]{40}$"
             :type "hidden"}
            :extract "value"))

class Html(name, tag, attributes, extract)

  Plugin to extract something from an HTML tag.

  This Plugin will find the HTML “tag” containing the specified “attributes” and store the “extract” attribute of the matched tag in its “value” attribute.

  tag

    A string defining the HTML tag to look for.

  attributes

    A dictionary with attributes matching the desired HTML tag. The keys in the dictionary are strings matching the tag’s attributes, and the values are treated as regular expressions, to help match tags that don’t have a static value.

  extract

    A string defining the HTML tag’s attribute that needs to be extracted and stored inside “value”.

  __str__()

    Returns a string representation of the Plugin.

    Return type

      `str`

  extract_html_tag(response)

    Extract data from an HTML tag.

    Given the HTML text, parses it, iterates through the tags, and find the one matching the attributes. Then it stores the matched “value” and returns it.

    Parameters

      text – A string containing the HTML text to be processed.

    Return type

      `Optional`[`str`]

    Returns

      A string with the match as defined in the Plugin. Returns None if there are no matches.

## Json

class Json(name, extract)

  Plugin to extract a field from JSON.

  The “extract” attribute is used to specify which field to store in the “value”. Using the dot `.` character you can go deeper inside the JSON object. To look inside an array, use square brackets [].

  Keys with special characters should be written inside double quotes `"`. Keep in mind that when written inside `hyfiles`, it’ll already be between double quotes, so you’ll have to escape them with the backslash character `\`.

  Examples

  `env.production[0].field` `production.keys[1].x5c[0][1][0]."with space"[3]`

  extract

    A string defining the location of the field that needs to be extracted. For now this is still quite primitive, and cannot access data from JSON arrays.

  __str__()

    Returns a string representation of the Plugin.

    Return type

      `str`

  extract_json_field(response)

    Extracts the JSON field from the text.

    Given the JSON body as a string, extract the field and store it in the Plugin’s “value” attribute.

    Parameters

      text – A string with the JSON body.

    Return type

      `Optional`[`str`]

    Returns

      A string with the result of extraction. If no such field is found None will be returned.

## Plugin API

class Plugin(name, function, flags=0, value=None)

  Parent class for all plugins.

  Each Plugin class inherits from here. “get_value” function should be called when extracting the value from the plugin, which will then be stored in the “value” attribute.

  name

    A string used as an identifier for the Plugin.

  function

    A function which will be called to extract the “value” of the Plugin when used as an input in a Flow. The function should set self.value and also return it.

  value

    A string containing the Plugin’s output value to be used as input in the HTTP request.

  flags

    An integer containing the flags that define the Plugin’s behaviour. For now only NEEDS_USERDATA and NEEDS_RESPONSE is supported. If NEEDS_USERDATA is set, the plugin will get its value from the user’s data, which will be sent to the function defined here. If NEEDS_RESPONSE is set, the Plugin will extract its value from the HTTP response instead.

## Writing custom plugins

In case the existing plugins are not enough, the user can write their own to add the new functionality. Those new plugins should be written in the project’s configuration directory in a “.hy” file. To do this, a new class has to be defined, which will inherit from Raider’s Plugin class:

Let’s assume we want a new plugin that will use unix password store to extract the OTP from our website.

    (defclass PasswordStore [Plugin]
    ;; Define class PasswordStore which inherits from Plugin

      (defn __init__ [self path]
      ;; Initiatialize the object given the path

        (.__init__ (super)
                   :name path
                   :function (. self run_command)))
      ;; Call the super() class, i.e. Plugin, and give it the
      ;; path as the name identifier, and the function
      ;; self.run_command() as a function to get the value.
      ;;
      ;; We don't need the response nor the user data to use
      ;; this plugin, so no flags will be set.

      (defn run_command [self]
        (import os)
        ;; We need os.popen() to run the command

        (setv self.value
              ((. ((. (os.popen
                        (+ "pass otp " self.path))
                      read))
                  strip)))
        ;; set self.value to the output from "pass otp",
        ;; with the newline stripped.

        (return self.value)))

And we can create a new variable that will use this class:

    (setv mfa_code (PasswordStore "personal/reddit"))

Now whenever we use the `mfa_code` in our requests, its value will be extracted from the password store.