tcell_agent 0.2.10 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/tcell_agent/configuration.rb +75 -10
- data/lib/tcell_agent/instrumentation.rb +3 -0
- data/lib/tcell_agent/logger.rb +2 -2
- data/lib/tcell_agent/rails/dlp.rb +82 -43
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +5 -4
- data/lib/tcell_agent/sensor_events/app_sensor.rb +44 -2
- data/lib/tcell_agent/servers/puma.rb +7 -2
- data/lib/tcell_agent/version.rb +1 -1
- data/spec/lib/tcell_agent/agent/policy_manager_spec.rb +1 -1
- data/spec/lib/tcell_agent/configuration_spec.rb +371 -0
- data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +7 -7
- data/spec/lib/tcell_agent/sensor_events/tcell_app_sensor_event_processor_spec.rb +289 -0
- metadata +6 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: d554725aca1909bfd60fe8c8eaea0a31d9f81db4
         | 
| 4 | 
            +
              data.tar.gz: 49d5a1f379e3fe812f705bf8455574d14c5af44c
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: ba72d99a1a9d4b280010f35ef9c748baa8127445afe5a24f717819a3e10655d5a179a055bf777a2f492d2114fb4a05bfad4f34f597e322085426bfc70e2720bc
         | 
| 7 | 
            +
              data.tar.gz: d9a76ef1c4ba6037d6f13bb43fbf01895d29e625da2cc3174767e1cf1edee54d9ee4bfe2bd55441fe3587ce21db40a578a1156566cd98f6f2982d8be40bf7689
         | 
| @@ -1,6 +1,7 @@ | |
| 1 1 | 
             
            # See the file "LICENSE" for the full license governing this code.
         | 
| 2 2 | 
             
            require 'fileutils'
         | 
| 3 3 | 
             
            require 'json'
         | 
| 4 | 
            +
            require 'yaml'
         | 
| 4 5 | 
             
            require 'socket'
         | 
| 5 6 | 
             
            require 'securerandom'
         | 
| 6 7 |  | 
| @@ -15,7 +16,7 @@ module TCellAgent | |
| 15 16 | 
             
              end
         | 
| 16 17 |  | 
| 17 18 | 
             
              class Configuration
         | 
| 18 | 
            -
                attr_accessor :version, :app_id, :api_key, :hmac_key, | 
| 19 | 
            +
                attr_accessor :version, :app_id, :api_key, :hmac_key,
         | 
| 19 20 | 
             
                  :tcell_api_url, :tcell_input_url,
         | 
| 20 21 | 
             
                  :logging_options,
         | 
| 21 22 | 
             
                  :fetch_policies_from_tcell, :instrument_for_events,
         | 
| @@ -25,13 +26,18 @@ module TCellAgent | |
| 25 26 | 
             
                  :uuid,
         | 
| 26 27 | 
             
                  :company,
         | 
| 27 28 | 
             
                  :event_batch_size_limit, :event_time_limit_seconds,
         | 
| 28 | 
            -
                  : | 
| 29 | 
            +
                  :log_filename,
         | 
| 29 30 | 
             
                  :base_dir,
         | 
| 30 31 | 
             
                  :cache_filename,
         | 
| 31 32 | 
             
                  :js_agent_api_base_url,
         | 
| 32 33 | 
             
                  :js_agent_url,
         | 
| 33 34 | 
             
                  :raise_exceptions,
         | 
| 34 | 
            -
                  :allow_unencrypted_appsensor_payloads
         | 
| 35 | 
            +
                  :allow_unencrypted_appsensor_payloads,
         | 
| 36 | 
            +
                  :blacklisted_params,
         | 
| 37 | 
            +
                  :whitelisted_params,
         | 
| 38 | 
            +
                  :whitelist_present,
         | 
| 39 | 
            +
                  :config_filename,
         | 
| 40 | 
            +
                  :max_data_ex_db_records_per_request
         | 
| 35 41 |  | 
| 36 42 | 
             
                attr_accessor :disable_all,
         | 
| 37 43 | 
             
                  :enabled,
         | 
| @@ -79,16 +85,23 @@ module TCellAgent | |
| 79 85 | 
             
                  @enable_instrumentation = true
         | 
| 80 86 | 
             
                  @enable_intercept_requests = true
         | 
| 81 87 |  | 
| 82 | 
            -
             | 
| 83 | 
            -
                  @ | 
| 88 | 
            +
             | 
| 89 | 
            +
                  @agent_home_dir = File.join(Dir.getwd, "tcell")
         | 
| 90 | 
            +
                  @agent_log_dir = File.join(@agent_home_dir, "logs")
         | 
| 91 | 
            +
                  @config_filename = File.join(Dir.getwd, filename)
         | 
| 84 92 |  | 
| 85 93 | 
             
                  @event_batch_size_limit = 50
         | 
| 86 94 | 
             
                  @event_time_limit_seconds = 15
         | 
| 87 95 |  | 
| 88 96 | 
             
                  @raise_exceptions = false
         | 
| 89 97 |  | 
| 98 | 
            +
                  @max_data_ex_db_records_per_request = 1000
         | 
| 99 | 
            +
             | 
| 90 100 | 
             
                  read_config_using_env
         | 
| 91 | 
            -
                  read_config_from_file( | 
| 101 | 
            +
                  read_config_from_file(@config_filename)
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                  @cache_filename = File.join(@agent_home_dir, "cache", "tcell_agent.cache")
         | 
| 104 | 
            +
                  @log_filename = File.join(@agent_log_dir, "tcell_agent.log")
         | 
| 92 105 |  | 
| 93 106 | 
             
                  # Because ENV can override this one
         | 
| 94 107 | 
             
                  env_unencrypted_firewall = 
         | 
| @@ -115,11 +128,13 @@ module TCellAgent | |
| 115 128 | 
             
                  @uuid = SecureRandom.uuid
         | 
| 116 129 |  | 
| 117 130 | 
             
                  FileUtils::mkdir_p File.dirname(@cache_filename)
         | 
| 118 | 
            -
                  if @logging_options  | 
| 131 | 
            +
                  if @logging_options && @logging_options["filename"]
         | 
| 119 132 | 
             
                    FileUtils::mkdir_p File.dirname(@logging_options["filename"])
         | 
| 120 133 | 
             
                  else
         | 
| 121 | 
            -
                    FileUtils::mkdir_p File.dirname(@ | 
| 134 | 
            +
                    FileUtils::mkdir_p File.dirname(@log_filename)
         | 
| 122 135 | 
             
                  end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                  load_app_sensor_restrictions
         | 
| 123 138 | 
             
                end
         | 
| 124 139 |  | 
| 125 140 | 
             
                def cache_filename_with_app_id
         | 
| @@ -139,6 +154,10 @@ module TCellAgent | |
| 139 154 | 
             
                  @tcell_input_url = ENV["TCELL_INPUT_URL"]
         | 
| 140 155 | 
             
                  @demomode = ENV["TCELL_DEMOMODE"] || @demomode
         | 
| 141 156 |  | 
| 157 | 
            +
                  @agent_home_dir = ENV["TCELL_AGENT_HOME"] || @agent_home_dir
         | 
| 158 | 
            +
                  @agent_log_dir = ENV["TCELL_AGENT_LOG_DIR"] || File.join(@agent_home_dir, "logs")
         | 
| 159 | 
            +
                  @config_filename = ENV["TCELL_AGENT_CONFIG"] || @config_filename
         | 
| 160 | 
            +
             | 
| 142 161 | 
             
                  if @demomode
         | 
| 143 162 | 
             
                    @event_batch_size_limit = 2
         | 
| 144 163 | 
             
                    @event_time_limit_seconds = 5
         | 
| @@ -151,7 +170,7 @@ module TCellAgent | |
| 151 170 | 
             
                  if File.file?(filename)
         | 
| 152 171 | 
             
                    #puts "tCell.io: Loading from file"
         | 
| 153 172 | 
             
                    begin
         | 
| 154 | 
            -
                      config_text = open(filename).read
         | 
| 173 | 
            +
                      config_text = File.open(filename).read
         | 
| 155 174 | 
             
                      config = JSON.parse(config_text)
         | 
| 156 175 | 
             
                      if (config["version"] == 1)
         | 
| 157 176 | 
             
                        # Required
         | 
| @@ -189,6 +208,8 @@ module TCellAgent | |
| 189 208 | 
             
                        @allow_unencrypted_appsensor_payloads = app_data.fetch('allow_unencrypted_appsensor_payloads', @allow_unencrypted_appsensor_payloads) 
         | 
| 190 209 | 
             
                        @allow_unencrypted_appsensor_payloads = app_data.fetch('allow_unencrypted_appfirewall_payloads', @allow_unencrypted_appsensor_payloads) 
         | 
| 191 210 |  | 
| 211 | 
            +
                        data_exposure = app_data.fetch('data_exposure', {})
         | 
| 212 | 
            +
                        @max_data_ex_db_records_per_request = data_exposure.fetch('max_data_ex_db_records_per_request', @max_data_ex_db_records_per_request)
         | 
| 192 213 |  | 
| 193 214 | 
             
                        @host_identifier = @host_identifier || app_data.fetch("host_identifier", @host_identifier)
         | 
| 194 215 | 
             
                        if (@host_identifier == nil)
         | 
| @@ -218,7 +239,7 @@ module TCellAgent | |
| 218 239 | 
             
                          @event_batch_size_limit = 2
         | 
| 219 240 | 
             
                          @event_time_limit_seconds = 5
         | 
| 220 241 | 
             
                        end
         | 
| 221 | 
            -
                      else | 
| 242 | 
            +
                      else
         | 
| 222 243 | 
             
                        puts " ********* ********* ********* *********"
         | 
| 223 244 | 
             
                        puts "* tCell.io                               *"
         | 
| 224 245 | 
             
                        puts "* Unsupported config file version        *"
         | 
| @@ -233,6 +254,50 @@ module TCellAgent | |
| 233 254 | 
             
                    end #begin
         | 
| 234 255 | 
             
                  end # filename exist
         | 
| 235 256 | 
             
                end #def read
         | 
| 257 | 
            +
             | 
| 258 | 
            +
                def load_app_sensor_restrictions
         | 
| 259 | 
            +
                  payloads_config_filename = ENV["TCELL_AGENT_PAYLOADS_CONFIG"] || "config/tcell_agent_payloads.config"
         | 
| 260 | 
            +
             | 
| 261 | 
            +
                  @blacklisted_params = {
         | 
| 262 | 
            +
                    "token" => true,
         | 
| 263 | 
            +
                    "client_secret" => true,
         | 
| 264 | 
            +
                    "password" => true,
         | 
| 265 | 
            +
                    "passwd" => true,
         | 
| 266 | 
            +
                    "refresh_token" => true,
         | 
| 267 | 
            +
                    "pf.pass" => true,
         | 
| 268 | 
            +
                    "user.password" => true
         | 
| 269 | 
            +
                  }
         | 
| 270 | 
            +
                  @whitelisted_params = {}
         | 
| 271 | 
            +
                  @whitelist_present = false
         | 
| 272 | 
            +
             | 
| 273 | 
            +
                  if File.file?(payloads_config_filename)
         | 
| 274 | 
            +
                    begin
         | 
| 275 | 
            +
                      payloads_config = YAML.load(File.open(payloads_config_filename).read)
         | 
| 276 | 
            +
                      if payloads_config.has_key?("blacklisted")
         | 
| 277 | 
            +
                        @blacklisted_params = {}
         | 
| 278 | 
            +
                        payloads_config["blacklisted"].each do |param_name|
         | 
| 279 | 
            +
                          @blacklisted_params[param_name.downcase] = true
         | 
| 280 | 
            +
                        end
         | 
| 281 | 
            +
                      end
         | 
| 282 | 
            +
                      if payloads_config.has_key?("whitelisted")
         | 
| 283 | 
            +
                        @whitelist_present = true
         | 
| 284 | 
            +
                        payloads_config["whitelisted"].each do |param_name|
         | 
| 285 | 
            +
                          @whitelisted_params[param_name.downcase] = true
         | 
| 286 | 
            +
                        end
         | 
| 287 | 
            +
                      end
         | 
| 288 | 
            +
             | 
| 289 | 
            +
                    rescue Exception => e
         | 
| 290 | 
            +
                      @allow_unencrypted_appsensor_payloads = false
         | 
| 291 | 
            +
             | 
| 292 | 
            +
                      puts " ********* ********* ********* **********"
         | 
| 293 | 
            +
                      puts "* tCell.io                               *"
         | 
| 294 | 
            +
                      puts "* Could not load payloads config file    *"
         | 
| 295 | 
            +
                      puts " ********* ********* ********* **********"
         | 
| 296 | 
            +
                      puts e
         | 
| 297 | 
            +
                    end
         | 
| 298 | 
            +
                  end
         | 
| 299 | 
            +
                end
         | 
| 300 | 
            +
             | 
| 236 301 | 
             
              end # class
         | 
| 237 302 |  | 
| 238 303 | 
             
              TCellAgent.configuration ||= TCellAgent::Configuration.new
         | 
| @@ -5,6 +5,7 @@ require 'tcell_agent/logger' | |
| 5 5 | 
             
            require 'tcell_agent/configuration'
         | 
| 6 6 | 
             
            require 'tcell_agent/version'
         | 
| 7 7 | 
             
            require 'date'
         | 
| 8 | 
            +
            require 'cgi'
         | 
| 8 9 |  | 
| 9 10 | 
             
            module TCellAgent
         | 
| 10 11 | 
             
              module Instrumentation
         | 
| @@ -126,6 +127,7 @@ module TCellAgent | |
| 126 127 | 
             
                              session_id_actions.action_id
         | 
| 127 128 | 
             
                              ).for_framework(TCellAgent::SensorEvents::DlpEvent::FRAMEWORK_VARIABLE_SESSION_ID)
         | 
| 128 129 | 
             
                          )
         | 
| 130 | 
            +
             | 
| 129 131 | 
             
                        end
         | 
| 130 132 | 
             
                      end
         | 
| 131 133 | 
             
                    end
         | 
| @@ -133,6 +135,7 @@ module TCellAgent | |
| 133 135 | 
             
                      replace_filters = (context_filters.select {|context_filter| context_filter.rule.body_redact == true })
         | 
| 134 136 | 
             
                      event_filters = (context_filters.select {|context_filter| (context_filter.rule.body_redact != true && context_filter.rule.body_event == true) })
         | 
| 135 137 | 
             
                      send_flag = TCellData.filterx(body, event_filters.length > 0, replace_filters.length > 0, term)
         | 
| 138 | 
            +
                      send_flag = send_flag || TCellData.filterx(body, event_filters.length > 0, replace_filters.length > 0, CGI.escapeHTML(term))
         | 
| 136 139 | 
             
                      if send_flag
         | 
| 137 140 | 
             
                        (replace_filters + event_filters).each { |filter|
         | 
| 138 141 | 
             
                          base_event = TCellAgent::SensorEvents::DlpEvent.new(
         | 
    
        data/lib/tcell_agent/logger.rb
    CHANGED
    
    | @@ -34,7 +34,7 @@ module TCellAgent | |
| 34 34 | 
             
                if logging_options && logging_options["enabled"]
         | 
| 35 35 | 
             
                  FileUtils.mkdir_p 'tcell/logs'
         | 
| 36 36 | 
             
                  level = loggingLevelFromString(logging_options["level"])
         | 
| 37 | 
            -
                  logging_file = logging_options["filename"] || TCellAgent.configuration. | 
| 37 | 
            +
                  logging_file = logging_options["filename"] || TCellAgent.configuration.log_filename
         | 
| 38 38 | 
             
                  # limit the total log file to about 9 * 5 = 45 mb
         | 
| 39 39 | 
             
                  @logger = Logger.new(logging_file, shift_age=9, shift_size=5242880)
         | 
| 40 40 | 
             
                  @logger.level = level
         | 
| @@ -47,7 +47,7 @@ module TCellAgent | |
| 47 47 | 
             
                  return @logger
         | 
| 48 48 | 
             
                end
         | 
| 49 49 |  | 
| 50 | 
            -
                logger = Logger.new(TCellAgent.configuration. | 
| 50 | 
            +
                logger = Logger.new(TCellAgent.configuration.log_filename)
         | 
| 51 51 | 
             
                logger.level = Logger::ERROR
         | 
| 52 52 | 
             
                return logger
         | 
| 53 53 | 
             
              end
         | 
| @@ -51,58 +51,97 @@ require 'thread' | |
| 51 51 | 
             
            require 'tcell_agent/configuration'
         | 
| 52 52 |  | 
| 53 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 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 89 | 
            -
             | 
| 90 | 
            -
             | 
| 91 | 
            -
             | 
| 54 | 
            +
            module TCellAgent
         | 
| 55 | 
            +
              class MyRailtie < Rails::Railtie
         | 
| 56 | 
            +
                initializer 'activeservice.autoload', :after => :set_autoload_paths do |app|
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  if defined?(ActiveRecord)
         | 
| 59 | 
            +
                    ActiveRecord::Relation.class_eval do
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                      alias_method :original_exec_queries, :exec_queries
         | 
| 62 | 
            +
                      def exec_queries
         | 
| 63 | 
            +
                        @records = original_exec_queries
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                        TCellAgent::Instrumentation.safe_block("Running DLP on query") do
         | 
| 66 | 
            +
                          if @records.size > 0
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                            if TCellAgent.configuration.enabled &&
         | 
| 69 | 
            +
                                TCellAgent.configuration.should_instrument? &&
         | 
| 70 | 
            +
                                TCellAgent.configuration.should_intercept_requests?
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                              dlp_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                              if dlp_policy
         | 
| 75 | 
            +
                                request_env = TCellAgent::Instrumentation::Rails::Middleware::ContextMiddleware::THREADS.fetch(Thread.current.object_id, nil)
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                                if request_env
         | 
| 78 | 
            +
                                  tcell_context = request_env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                                  if tcell_context
         | 
| 81 | 
            +
                                    first_record = @records.first
         | 
| 82 | 
            +
                                    database_name = first_record.class.connection_config().fetch(:database,"*").split('/').last
         | 
| 83 | 
            +
                                    model = first_record.class
         | 
| 84 | 
            +
                                    column_names = model.columns.map { |col| col.name }
         | 
| 85 | 
            +
                                    table_name = model.table_name
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                                    if dlp_policy.database_discovery_enabled
         | 
| 88 | 
            +
                                      TCellAgent.discover_database_fields(
         | 
| 89 | 
            +
                                        tcell_context.route_id,
         | 
| 90 | 
            +
                                        database_name,
         | 
| 91 | 
            +
                                        "*",
         | 
| 92 | 
            +
                                        table_name,
         | 
| 93 | 
            +
                                        column_names
         | 
| 94 | 
            +
                                      )
         | 
| 95 | 
            +
                                    end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                                    column_name_to_rules = first_record.attributes.keys.inject({}) do |memo, column_name|
         | 
| 98 | 
            +
                                      memo[column_name] = dlp_policy.get_actions_for_table(
         | 
| 99 | 
            +
                                        database_name,
         | 
| 100 | 
            +
                                        "*",
         | 
| 101 | 
            +
                                        table_name,
         | 
| 102 | 
            +
                                        column_name,
         | 
| 103 | 
            +
                                        tcell_context.route_id
         | 
| 104 | 
            +
                                      )
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                                      memo
         | 
| 107 | 
            +
                                    end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                                    if @records.size > TCellAgent.configuration.max_data_ex_db_records_per_request
         | 
| 110 | 
            +
                                      TCellAgent.logger.warn("Route (#{tcell_context.route_id}) retrieved too many records")
         | 
| 111 | 
            +
                                    end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                                    @records[0...TCellAgent.configuration.max_data_ex_db_records_per_request].each do |record|
         | 
| 114 | 
            +
                                      column_name_to_rules.each do |column_name, rules|
         | 
| 115 | 
            +
                                        if rules
         | 
| 116 | 
            +
                                          rules.each do |rule|
         | 
| 117 | 
            +
                                            tcell_context.add_response_db_filter(
         | 
| 118 | 
            +
                                              record[column_name.to_sym],
         | 
| 119 | 
            +
                                              rule,
         | 
| 120 | 
            +
                                              database_name,
         | 
| 121 | 
            +
                                              "*",
         | 
| 122 | 
            +
                                              table_name,
         | 
| 123 | 
            +
                                              column_name
         | 
| 124 | 
            +
                                            )
         | 
| 125 | 
            +
                                          end
         | 
| 126 | 
            +
                                        end
         | 
| 127 | 
            +
                                      end
         | 
| 128 | 
            +
                                    end
         | 
| 129 | 
            +
                                  end
         | 
| 130 | 
            +
                                end
         | 
| 92 131 | 
             
                              end
         | 
| 93 132 | 
             
                            end
         | 
| 94 133 | 
             
                          end
         | 
| 95 134 | 
             
                        end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                        @records
         | 
| 96 137 | 
             
                      end
         | 
| 97 | 
            -
                    end # /if dlp_policy
         | 
| 98 | 
            -
                  end # /enabled
         | 
| 99 | 
            -
                end # /after_find
         | 
| 100 | 
            -
              end # /class
         | 
| 101 | 
            -
            end
         | 
| 102 138 |  | 
| 139 | 
            +
                    end
         | 
| 103 140 | 
             
                  end
         | 
| 141 | 
            +
             | 
| 104 142 | 
             
                end
         | 
| 105 143 | 
             
              end
         | 
| 144 | 
            +
            end
         | 
| 106 145 |  | 
| 107 146 |  | 
| 108 147 |  | 
| @@ -145,18 +145,19 @@ module TCellAgent | |
| 145 145 | 
             
                          rack_response = Rack::Response.new(response)
         | 
| 146 146 |  | 
| 147 147 | 
             
                          if appsensor_policy && appsensor_policy.enabled
         | 
| 148 | 
            -
                            event = TCellAgent::SensorEvents::TCellAppSensorEventProcessor.new | 
| 148 | 
            +
                            event = TCellAgent::SensorEvents::TCellAppSensorEventProcessor.new
         | 
| 149 149 | 
             
                            event.request_headers = request.env
         | 
| 150 150 | 
             
                            event.request_content_length = (request.content_length || "0").to_i
         | 
| 151 151 | 
             
                            event.response_content_length = (rack_response.length || "0").to_i
         | 
| 152 | 
            +
                            event.request_content_type = request.content_type
         | 
| 152 153 | 
             
                            event.remote_addr = request.ip
         | 
| 153 | 
            -
                            event.uri = request.fullpath
         | 
| 154 | 
            +
                            event.uri = "#{request.base_url}#{request.fullpath}"
         | 
| 154 155 | 
             
                            event.get_params = request.GET
         | 
| 155 156 | 
             
                            event.post_params = request.POST
         | 
| 157 | 
            +
                            event.request_body = request.body.gets
         | 
| 156 158 | 
             
                            event.cookies = request.cookies
         | 
| 157 159 | 
             
                            event.request_method = request.request_method
         | 
| 158 | 
            -
             | 
| 159 | 
            -
                            request_body = request.body
         | 
| 160 | 
            +
             | 
| 160 161 | 
             
                            event.request_size = event.request_content_length
         | 
| 161 162 | 
             
                            #status, headers, active_response = response
         | 
| 162 163 | 
             
                            #if active_response.class != ActionDispatch::Response
         | 
| @@ -54,20 +54,33 @@ module TCellAgent | |
| 54 54 | 
             
                        end
         | 
| 55 55 | 
             
                    end
         | 
| 56 56 | 
             
                    class TCellAppSensorEventProcessor < TCellSensorEvent
         | 
| 57 | 
            -
                        attr_accessor :request_headers, :request_size, :remote_addr, | 
| 57 | 
            +
                        attr_accessor :request_headers, :request_size, :remote_addr,
         | 
| 58 58 | 
             
                                        :uri, :get_params, :post_params, :cookies,
         | 
| 59 59 | 
             
                                        :request_content_length, :request_content_type,
         | 
| 60 | 
            -
                                        :request_method
         | 
| 60 | 
            +
                                        :request_method, :request_body
         | 
| 61 61 | 
             
                        attr_accessor :status_code, :response_headers,
         | 
| 62 62 | 
             
                                        :response_content_length,
         | 
| 63 63 | 
             
                                        :route_id, :transaction_id, :session_id, :user_id
         | 
| 64 | 
            +
             | 
| 64 65 | 
             
                        def initialize
         | 
| 65 66 | 
             
                            @request_content_length=0
         | 
| 66 67 | 
             
                            @response_content_length = 0
         | 
| 67 68 | 
             
                            @send = false
         | 
| 69 | 
            +
                            @body_params = nil
         | 
| 68 70 | 
             
                        end
         | 
| 71 | 
            +
             | 
| 69 72 | 
             
                        def appsensor_event(dp, param, data, payload=nil)
         | 
| 70 73 | 
             
                            TCellAgent::Instrumentation.safe_block("AppSensor Sending Event") {
         | 
| 74 | 
            +
                                unless payload.nil?
         | 
| 75 | 
            +
                                    if TCellAgent.configuration.blacklisted_params.has_key?(param.downcase)
         | 
| 76 | 
            +
                                        payload = "BLACKLISTED"
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                                    elsif TCellAgent.configuration.whitelist_present &&
         | 
| 79 | 
            +
                                        !TCellAgent.configuration.whitelisted_params.has_key?(param.downcase)
         | 
| 80 | 
            +
                                        payload = "NOT_WHITELISTED"
         | 
| 81 | 
            +
                                    end
         | 
| 82 | 
            +
                                end
         | 
| 83 | 
            +
             | 
| 71 84 | 
             
                                event = TCellAgent::SensorEvents::TCellAppSensorEvent.new(
         | 
| 72 85 | 
             
                                    @uri,
         | 
| 73 86 | 
             
                                    dp,
         | 
| @@ -84,6 +97,7 @@ module TCellAgent | |
| 84 97 | 
             
                                TCellAgent.send_event(event)
         | 
| 85 98 | 
             
                            }
         | 
| 86 99 | 
             
                        end
         | 
| 100 | 
            +
             | 
| 87 101 | 
             
                        def loop_params_hash(method, param_hash, prefix, &block)
         | 
| 88 102 | 
             
                            param_hash.each do |param_name, param_value|
         | 
| 89 103 | 
             
                                if param_value && param_value.is_a?(Hash)
         | 
| @@ -95,6 +109,7 @@ module TCellAgent | |
| 95 109 | 
             
                                end
         | 
| 96 110 | 
             
                            end
         | 
| 97 111 | 
             
                        end
         | 
| 112 | 
            +
             | 
| 98 113 | 
             
                        def for_params(&block)
         | 
| 99 114 | 
             
                            if @get_params
         | 
| 100 115 | 
             
                                self.loop_params_hash('get', @get_params, nil, &block)
         | 
| @@ -102,13 +117,40 @@ module TCellAgent | |
| 102 117 | 
             
                            if @post_params
         | 
| 103 118 | 
             
                                self.loop_params_hash('post', @post_params, nil, &block)
         | 
| 104 119 | 
             
                            end
         | 
| 120 | 
            +
                            if body_params.length > 0
         | 
| 121 | 
            +
                                self.loop_params_hash('body', body_params, nil, &block)
         | 
| 122 | 
            +
                            end
         | 
| 105 123 | 
             
                        end
         | 
| 124 | 
            +
             | 
| 106 125 | 
             
                        def for_get_params(&block)
         | 
| 107 126 | 
             
                            if @get_params
         | 
| 108 127 | 
             
                                self.loop_params_hash('get', @get_params, nil, &block)
         | 
| 109 128 | 
             
                            end
         | 
| 110 129 | 
             
                        end
         | 
| 111 130 |  | 
| 131 | 
            +
                        def body_params
         | 
| 132 | 
            +
                            if @body_params
         | 
| 133 | 
            +
                                @body_params
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                            elsif @request_content_length > 2000000
         | 
| 136 | 
            +
                              @body_params = {}
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                            else
         | 
| 139 | 
            +
                                if @request_content_type =~ %r{application/json}i && @request_body
         | 
| 140 | 
            +
                                    begin
         | 
| 141 | 
            +
                                        @body_params = JSON.parse(@request_body)
         | 
| 142 | 
            +
                                    rescue
         | 
| 143 | 
            +
                                        TCellAgent.logger.debug("JSON body parameter parsing failed")
         | 
| 144 | 
            +
                                        @body_params = {}
         | 
| 145 | 
            +
                                    end
         | 
| 146 | 
            +
                                else
         | 
| 147 | 
            +
                                    @body_params = {}
         | 
| 148 | 
            +
                                end
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                                @body_params
         | 
| 151 | 
            +
                            end
         | 
| 152 | 
            +
                        end
         | 
| 153 | 
            +
             | 
| 112 154 | 
             
                        def test_response_size
         | 
| 113 155 | 
             
                            if (@response_content_length && @response_content_length > TCellAgent::Policies::AppSensorPolicy::MAX_NORMAL_RESPONSE_BYTES)
         | 
| 114 156 | 
             
                                appsensor_event(TCellAgent::Policies::AppSensorPolicy::DP_UNUSUAL_RESPONSE_SIZE, response_content_length.to_s, nil)
         | 
| @@ -35,7 +35,13 @@ if defined?(Puma.cli_config) | |
| 35 35 |  | 
| 36 36 | 
             
                  # Runs initial instrumentation only once on the master process
         | 
| 37 37 | 
             
                  puma_server_starting = Proc.new { TCellAgent.run_instrumentation("Puma Cluster Mode") }
         | 
| 38 | 
            -
             | 
| 38 | 
            +
             | 
| 39 | 
            +
                  # before_fork was added in Puma v2.13.0
         | 
| 40 | 
            +
                  if Puma.cli_config.options[:before_fork]
         | 
| 41 | 
            +
                    Puma.cli_config.options[:before_fork].push(puma_server_starting)
         | 
| 42 | 
            +
                  else
         | 
| 43 | 
            +
                    Puma.cli_config.options[:before_fork] = [puma_server_starting]
         | 
| 44 | 
            +
                  end
         | 
| 39 45 |  | 
| 40 46 | 
             
                  # Each puma worker still needs the agent started but no need to run
         | 
| 41 47 | 
             
                  # initial instrumentation again
         | 
| @@ -58,4 +64,3 @@ if defined?(Puma.cli_config) | |
| 58 64 |  | 
| 59 65 | 
             
              end
         | 
| 60 66 | 
             
            end
         | 
| 61 | 
            -
             | 
    
        data/lib/tcell_agent/version.rb
    CHANGED
    
    
| @@ -79,7 +79,7 @@ module TCellAgent | |
| 79 79 | 
             
                    end
         | 
| 80 80 |  | 
| 81 81 | 
             
                    context "with 10 processes updating the cached file" do
         | 
| 82 | 
            -
                       | 
| 82 | 
            +
                      xit "should update the cached file with all updates" do
         | 
| 83 83 | 
             
                        processes = 5.times.map do |process_number|
         | 
| 84 84 | 
             
                          ForkBreak::Process.new do |breakpoints|
         | 
| 85 85 | 
             
                            original_dump = JSON.method(:dump)
         | 
| @@ -0,0 +1,371 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module TCellAgent
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              describe Configuration do
         | 
| 6 | 
            +
                describe "#load_app_sensor_restrictions" do
         | 
| 7 | 
            +
                  before(:each) do
         | 
| 8 | 
            +
                    @config_file = double("config", read: {
         | 
| 9 | 
            +
                      version: 1,
         | 
| 10 | 
            +
                      applications: [
         | 
| 11 | 
            +
                        {
         | 
| 12 | 
            +
                          allow_unencrypted_appsensor_payloads: true
         | 
| 13 | 
            +
                        }
         | 
| 14 | 
            +
                      ]
         | 
| 15 | 
            +
                    }.to_json)
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  context "with no payloads file present" do
         | 
| 19 | 
            +
                    it "should set blacklist to default params and whitelist to empty" do
         | 
| 20 | 
            +
                      expect(File).to receive(:file?).with(
         | 
| 21 | 
            +
                        File.join(Dir.getwd, "config/tcell_agent.config")
         | 
| 22 | 
            +
                      ).and_return(true)
         | 
| 23 | 
            +
                      expect(File).to receive(:open).with(
         | 
| 24 | 
            +
                        File.join(Dir.getwd, "config/tcell_agent.config")
         | 
| 25 | 
            +
                      ).and_return(@config_file)
         | 
| 26 | 
            +
                      expect(File).to receive(:file?).with(
         | 
| 27 | 
            +
                        "config/tcell_agent_payloads.config"
         | 
| 28 | 
            +
                      ).and_return(false)
         | 
| 29 | 
            +
                      expect(File).to_not receive(:open)
         | 
| 30 | 
            +
                      configuration = TCellAgent::Configuration.new
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                      expect(configuration.allow_unencrypted_appsensor_payloads).to eq(true)
         | 
| 33 | 
            +
                      expect(configuration.blacklisted_params).to eq({
         | 
| 34 | 
            +
                        "token" => true,
         | 
| 35 | 
            +
                        "client_secret" => true,
         | 
| 36 | 
            +
                        "password" => true,
         | 
| 37 | 
            +
                        "passwd" => true,
         | 
| 38 | 
            +
                        "refresh_token" => true,
         | 
| 39 | 
            +
                        "pf.pass" => true,
         | 
| 40 | 
            +
                        "user.password" => true
         | 
| 41 | 
            +
                      })
         | 
| 42 | 
            +
                      expect(configuration.whitelisted_params).to eq({})
         | 
| 43 | 
            +
                      expect(configuration.whitelist_present).to eq(false)
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  context "with a payloads file present" do
         | 
| 48 | 
            +
                    context "with a malformed payloads file" do
         | 
| 49 | 
            +
                      it "should set blacklist to default params and whitelist to empty" do
         | 
| 50 | 
            +
                        payloads_file = double("payloads", read: "{ whitelist: { test } ")
         | 
| 51 | 
            +
                        expect(File).to receive(:file?).with(
         | 
| 52 | 
            +
                          File.join(Dir.getwd, "config/tcell_agent.config")
         | 
| 53 | 
            +
                        ).and_return(true)
         | 
| 54 | 
            +
                        expect(File).to receive(:open).with(
         | 
| 55 | 
            +
                          File.join(Dir.getwd, "config/tcell_agent.config")
         | 
| 56 | 
            +
                        ).and_return(@config_file)
         | 
| 57 | 
            +
                        expect(File).to receive(:file?).with("config/tcell_agent_payloads.config").and_return(true)
         | 
| 58 | 
            +
                        expect(File).to receive(:open).with("config/tcell_agent_payloads.config").and_return(payloads_file)
         | 
| 59 | 
            +
                        configuration = TCellAgent::Configuration.new
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                        expect(configuration.allow_unencrypted_appsensor_payloads).to eq(false)
         | 
| 62 | 
            +
                        expect(configuration.blacklisted_params).to eq({
         | 
| 63 | 
            +
                          "token" => true,
         | 
| 64 | 
            +
                          "client_secret" => true,
         | 
| 65 | 
            +
                          "password" => true,
         | 
| 66 | 
            +
                          "passwd" => true,
         | 
| 67 | 
            +
                          "refresh_token" => true,
         | 
| 68 | 
            +
                          "pf.pass" => true,
         | 
| 69 | 
            +
                          "user.password" => true
         | 
| 70 | 
            +
                        })
         | 
| 71 | 
            +
                        expect(configuration.whitelisted_params).to eq({})
         | 
| 72 | 
            +
                        expect(configuration.whitelist_present).to eq(false)
         | 
| 73 | 
            +
                      end
         | 
| 74 | 
            +
                    end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                    context "with a payloads file" do
         | 
| 77 | 
            +
                      context "with empty json" do
         | 
| 78 | 
            +
                        it "should set blacklist to default params and whitelist to empty" do
         | 
| 79 | 
            +
                          payloads_file = double("payloads", read: "{}")
         | 
| 80 | 
            +
                          expect(File).to receive(:file?).with(
         | 
| 81 | 
            +
                            File.join(Dir.getwd, "config/tcell_agent.config")
         | 
| 82 | 
            +
                          ).and_return(true)
         | 
| 83 | 
            +
                          expect(File).to receive(:open).with(
         | 
| 84 | 
            +
                            File.join(Dir.getwd, "config/tcell_agent.config")
         | 
| 85 | 
            +
                          ).and_return(@config_file)
         | 
| 86 | 
            +
                          expect(File).to receive(:file?).with("config/tcell_agent_payloads.config").and_return(true)
         | 
| 87 | 
            +
                          expect(File).to receive(:open).with("config/tcell_agent_payloads.config").and_return(payloads_file)
         | 
| 88 | 
            +
                          configuration = TCellAgent::Configuration.new
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                          expect(configuration.allow_unencrypted_appsensor_payloads).to eq(true)
         | 
| 91 | 
            +
                          expect(configuration.blacklisted_params).to eq({
         | 
| 92 | 
            +
                            "token" => true,
         | 
| 93 | 
            +
                            "client_secret" => true,
         | 
| 94 | 
            +
                            "password" => true,
         | 
| 95 | 
            +
                            "passwd" => true,
         | 
| 96 | 
            +
                            "refresh_token" => true,
         | 
| 97 | 
            +
                            "pf.pass" => true,
         | 
| 98 | 
            +
                            "user.password" => true
         | 
| 99 | 
            +
                          })
         | 
| 100 | 
            +
                          expect(configuration.whitelisted_params).to eq({})
         | 
| 101 | 
            +
                          expect(configuration.whitelist_present).to eq(false)
         | 
| 102 | 
            +
                        end
         | 
| 103 | 
            +
                      end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                      context "with blacklisted present" do
         | 
| 106 | 
            +
                        it "should set blacklist but whitelist is empty" do
         | 
| 107 | 
            +
                          payloads_file = double("payloads", read:{blacklisted:["passwd"]}.to_json)
         | 
| 108 | 
            +
                          expect(File).to receive(:file?).with(
         | 
| 109 | 
            +
                            File.join(Dir.getwd, "config/tcell_agent.config")
         | 
| 110 | 
            +
                          ).and_return(true)
         | 
| 111 | 
            +
                          expect(File).to receive(:open).with(
         | 
| 112 | 
            +
                            File.join(Dir.getwd, "config/tcell_agent.config")
         | 
| 113 | 
            +
                          ).and_return(@config_file)
         | 
| 114 | 
            +
                          expect(File).to receive(:file?).with("config/tcell_agent_payloads.config").and_return(true)
         | 
| 115 | 
            +
                          expect(File).to receive(:open).with("config/tcell_agent_payloads.config").and_return(payloads_file)
         | 
| 116 | 
            +
                          configuration = TCellAgent::Configuration.new
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                          expect(configuration.allow_unencrypted_appsensor_payloads).to eq(true)
         | 
| 119 | 
            +
                          expect(configuration.blacklisted_params).to eq({"passwd" => true})
         | 
| 120 | 
            +
                          expect(configuration.whitelisted_params).to eq({})
         | 
| 121 | 
            +
                          expect(configuration.whitelist_present).to eq(false)
         | 
| 122 | 
            +
                        end
         | 
| 123 | 
            +
                      end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                      context "with whitelist present" do
         | 
| 126 | 
            +
                        it "should set whitelist and blacklist to default params" do
         | 
| 127 | 
            +
                          payloads_file = double("payloads", read: {whitelisted: ["passwd"]}.to_json)
         | 
| 128 | 
            +
                          expect(File).to receive(:file?).with(
         | 
| 129 | 
            +
                            File.join(Dir.getwd, "config/tcell_agent.config")
         | 
| 130 | 
            +
                          ).and_return(true)
         | 
| 131 | 
            +
                          expect(File).to receive(:open).with(
         | 
| 132 | 
            +
                            File.join(Dir.getwd, "config/tcell_agent.config")
         | 
| 133 | 
            +
                          ).and_return(@config_file)
         | 
| 134 | 
            +
                          expect(File).to receive(:file?).with("config/tcell_agent_payloads.config").and_return(true)
         | 
| 135 | 
            +
                          expect(File).to receive(:open).with("config/tcell_agent_payloads.config").and_return(payloads_file)
         | 
| 136 | 
            +
                          configuration = TCellAgent::Configuration.new
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                          expect(configuration.allow_unencrypted_appsensor_payloads).to eq(true)
         | 
| 139 | 
            +
                          expect(configuration.blacklisted_params).to eq({
         | 
| 140 | 
            +
                            "token" => true,
         | 
| 141 | 
            +
                            "client_secret" => true,
         | 
| 142 | 
            +
                            "password" => true,
         | 
| 143 | 
            +
                            "passwd" => true,
         | 
| 144 | 
            +
                            "refresh_token" => true,
         | 
| 145 | 
            +
                            "pf.pass" => true,
         | 
| 146 | 
            +
                            "user.password" => true
         | 
| 147 | 
            +
                          })
         | 
| 148 | 
            +
                          expect(configuration.whitelisted_params).to eq({"passwd" => true})
         | 
| 149 | 
            +
                          expect(configuration.whitelist_present).to eq(true)
         | 
| 150 | 
            +
                        end
         | 
| 151 | 
            +
                      end
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                      context "with blacklist and whitelist present" do
         | 
| 154 | 
            +
                        it "should set whitelist and blacklist" do
         | 
| 155 | 
            +
                          payloads_file = double("payloads", read: {blacklisted: ["ssn"], whitelisted: ["passwd"]}.to_json)
         | 
| 156 | 
            +
                          expect(File).to receive(:file?).with(
         | 
| 157 | 
            +
                            File.join(Dir.getwd, "config/tcell_agent.config")
         | 
| 158 | 
            +
                          ).and_return(true)
         | 
| 159 | 
            +
                          expect(File).to receive(:open).with(
         | 
| 160 | 
            +
                            File.join(Dir.getwd, "config/tcell_agent.config")
         | 
| 161 | 
            +
                          ).and_return(@config_file)
         | 
| 162 | 
            +
                          expect(File).to receive(:file?).with("config/tcell_agent_payloads.config").and_return(true)
         | 
| 163 | 
            +
                          expect(File).to receive(:open).with("config/tcell_agent_payloads.config").and_return(payloads_file)
         | 
| 164 | 
            +
                          configuration = TCellAgent::Configuration.new
         | 
| 165 | 
            +
             | 
| 166 | 
            +
                          expect(configuration.allow_unencrypted_appsensor_payloads).to eq(true)
         | 
| 167 | 
            +
                          expect(configuration.blacklisted_params).to eq({"ssn" => true})
         | 
| 168 | 
            +
                          expect(configuration.whitelisted_params).to eq({"passwd" => true})
         | 
| 169 | 
            +
                          expect(configuration.whitelist_present).to eq(true)
         | 
| 170 | 
            +
                        end
         | 
| 171 | 
            +
                      end
         | 
| 172 | 
            +
                    end
         | 
| 173 | 
            +
                  end
         | 
| 174 | 
            +
             | 
| 175 | 
            +
                end
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                describe "#agent_home_dir" do
         | 
| 178 | 
            +
                  context "no TCELL_AGENT_HOME defined" do
         | 
| 179 | 
            +
                    it "should set cache file, config, and log file to defaults" do
         | 
| 180 | 
            +
                      configuration = Configuration.new
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                      expect(configuration.cache_filename).to eq(
         | 
| 183 | 
            +
                        File.join(Dir.getwd, "tcell/cache/tcell_agent.cache")
         | 
| 184 | 
            +
                      )
         | 
| 185 | 
            +
                      expect(configuration.log_filename).to eq(
         | 
| 186 | 
            +
                        File.join(Dir.getwd, "tcell/logs/tcell_agent.log")
         | 
| 187 | 
            +
                      )
         | 
| 188 | 
            +
                      expect(configuration.config_filename).to eq(
         | 
| 189 | 
            +
                        File.join(Dir.getwd, "config/tcell_agent.config")
         | 
| 190 | 
            +
                      )
         | 
| 191 | 
            +
                    end
         | 
| 192 | 
            +
                  end
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                  context "TCELL_AGENT_HOME defined" do
         | 
| 195 | 
            +
                    it "should set config filename to default, cache file and log file are updated" do
         | 
| 196 | 
            +
                      old_tcell_agent_home = ENV["TCELL_AGENT_HOME"]
         | 
| 197 | 
            +
             | 
| 198 | 
            +
                      ENV["TCELL_AGENT_HOME"] = "spec_tcell_home"
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                      expect(FileUtils).to receive(:mkdir_p).with("spec_tcell_home/cache")
         | 
| 201 | 
            +
                      expect(FileUtils).to receive(:mkdir_p).with("spec_tcell_home/logs")
         | 
| 202 | 
            +
             | 
| 203 | 
            +
                      configuration = Configuration.new
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                      expect(configuration.cache_filename).to eq(
         | 
| 206 | 
            +
                        "spec_tcell_home/cache/tcell_agent.cache"
         | 
| 207 | 
            +
                      )
         | 
| 208 | 
            +
                      expect(configuration.log_filename).to eq(
         | 
| 209 | 
            +
                        "spec_tcell_home/logs/tcell_agent.log"
         | 
| 210 | 
            +
                      )
         | 
| 211 | 
            +
                      expect(configuration.config_filename).to eq(
         | 
| 212 | 
            +
                        File.join(Dir.getwd, "config/tcell_agent.config")
         | 
| 213 | 
            +
                      )
         | 
| 214 | 
            +
             | 
| 215 | 
            +
                      ENV["TCELL_AGENT_HOME"] = old_tcell_agent_home
         | 
| 216 | 
            +
                    end
         | 
| 217 | 
            +
                  end
         | 
| 218 | 
            +
             | 
| 219 | 
            +
                  context "TCELL_AGENT_HOME and TCELL_AGENT_LOG_DIR defined" do
         | 
| 220 | 
            +
                    it "should set config filename to default, cache file and log file are updated" do
         | 
| 221 | 
            +
                      old_tcell_agent_home = ENV["TCELL_AGENT_HOME"]
         | 
| 222 | 
            +
                      old_tcell_agent_log_dir = ENV["TCELL_AGENT_LOG_DIR"]
         | 
| 223 | 
            +
             | 
| 224 | 
            +
                      ENV["TCELL_AGENT_HOME"] = "spec_tcell_home"
         | 
| 225 | 
            +
                      ENV["TCELL_AGENT_LOG_DIR"] = "spec_tcell_log_dir"
         | 
| 226 | 
            +
             | 
| 227 | 
            +
                      expect(FileUtils).to receive(:mkdir_p).with("spec_tcell_home/cache")
         | 
| 228 | 
            +
                      expect(FileUtils).to receive(:mkdir_p).with("spec_tcell_log_dir")
         | 
| 229 | 
            +
             | 
| 230 | 
            +
                      configuration = Configuration.new
         | 
| 231 | 
            +
             | 
| 232 | 
            +
                      expect(configuration.cache_filename).to eq(
         | 
| 233 | 
            +
                        "spec_tcell_home/cache/tcell_agent.cache"
         | 
| 234 | 
            +
                      )
         | 
| 235 | 
            +
                      expect(configuration.log_filename).to eq(
         | 
| 236 | 
            +
                        "spec_tcell_log_dir/tcell_agent.log"
         | 
| 237 | 
            +
                      )
         | 
| 238 | 
            +
                      expect(configuration.config_filename).to eq(
         | 
| 239 | 
            +
                        File.join(Dir.getwd, "config/tcell_agent.config")
         | 
| 240 | 
            +
                      )
         | 
| 241 | 
            +
             | 
| 242 | 
            +
                      ENV["TCELL_AGENT_HOME"] = old_tcell_agent_home
         | 
| 243 | 
            +
                      ENV["TCELL_AGENT_LOG_DIR"] = old_tcell_agent_log_dir
         | 
| 244 | 
            +
                    end
         | 
| 245 | 
            +
                  end
         | 
| 246 | 
            +
             | 
| 247 | 
            +
                  context "TCELL_AGENT_HOME, TCELL_AGENT_LOG_DIR, and TCELL_AGENT_CONFIG defined " do
         | 
| 248 | 
            +
                    it "should update config filename, cache file, and log file" do
         | 
| 249 | 
            +
                      old_tcell_agent_home = ENV["TCELL_AGENT_HOME"]
         | 
| 250 | 
            +
                      old_tcell_agent_log_dir = ENV["TCELL_AGENT_LOG_DIR"]
         | 
| 251 | 
            +
                      old_config_filename = ENV["TCELL_AGENT_CONFIG"]
         | 
| 252 | 
            +
             | 
| 253 | 
            +
                      ENV["TCELL_AGENT_HOME"] = "spec_tcell_home"
         | 
| 254 | 
            +
                      ENV["TCELL_AGENT_LOG_DIR"] = "spec_tcell_log_dir"
         | 
| 255 | 
            +
                      ENV["TCELL_AGENT_CONFIG"] = "spec_config/tcell_agent.config"
         | 
| 256 | 
            +
             | 
| 257 | 
            +
                      expect(FileUtils).to receive(:mkdir_p).with("spec_tcell_log_dir")
         | 
| 258 | 
            +
                      expect(FileUtils).to receive(:mkdir_p).with("spec_tcell_home/cache")
         | 
| 259 | 
            +
             | 
| 260 | 
            +
                      configuration = Configuration.new
         | 
| 261 | 
            +
             | 
| 262 | 
            +
                      expect(configuration.cache_filename).to eq(
         | 
| 263 | 
            +
                        "spec_tcell_home/cache/tcell_agent.cache"
         | 
| 264 | 
            +
                      )
         | 
| 265 | 
            +
                      expect(configuration.log_filename).to eq(
         | 
| 266 | 
            +
                        "spec_tcell_log_dir/tcell_agent.log"
         | 
| 267 | 
            +
                      )
         | 
| 268 | 
            +
                      expect(configuration.config_filename).to eq(
         | 
| 269 | 
            +
                        "spec_config/tcell_agent.config"
         | 
| 270 | 
            +
                      )
         | 
| 271 | 
            +
             | 
| 272 | 
            +
                      ENV["TCELL_AGENT_HOME"] = old_tcell_agent_home
         | 
| 273 | 
            +
                      ENV["TCELL_AGENT_LOG_DIR"] = old_tcell_agent_log_dir
         | 
| 274 | 
            +
                      ENV["TCELL_AGENT_CONFIG"] = old_config_filename
         | 
| 275 | 
            +
                    end
         | 
| 276 | 
            +
                  end
         | 
| 277 | 
            +
                end
         | 
| 278 | 
            +
             | 
| 279 | 
            +
                describe "#data_exposure" do
         | 
| 280 | 
            +
                  context "no data_exposure defined" do
         | 
| 281 | 
            +
                    it "should set max_data_ex_db_records_per_request to default" do
         | 
| 282 | 
            +
                      no_data_ex = double(
         | 
| 283 | 
            +
                        "no_data_ex",
         | 
| 284 | 
            +
                        read: {
         | 
| 285 | 
            +
                          version: 1,
         | 
| 286 | 
            +
                          applications: [
         | 
| 287 | 
            +
                            app_id: "app_id",
         | 
| 288 | 
            +
                            name: "test",
         | 
| 289 | 
            +
                            api_key: "api_key"
         | 
| 290 | 
            +
                          ]
         | 
| 291 | 
            +
                        }.to_json
         | 
| 292 | 
            +
                      )
         | 
| 293 | 
            +
                      expect(File).to receive(:file?).with(
         | 
| 294 | 
            +
                        File.join(Dir.getwd, "no_data_ex.config")
         | 
| 295 | 
            +
                      ).and_return(true)
         | 
| 296 | 
            +
                      expect(File).to receive(:open).with(
         | 
| 297 | 
            +
                        File.join(Dir.getwd, "no_data_ex.config")
         | 
| 298 | 
            +
                      ).and_return(no_data_ex)
         | 
| 299 | 
            +
                      expect(File).to receive(:file?).with(
         | 
| 300 | 
            +
                        "config/tcell_agent_payloads.config"
         | 
| 301 | 
            +
                      ).and_return(false)
         | 
| 302 | 
            +
                      configuration = Configuration.new("no_data_ex.config")
         | 
| 303 | 
            +
             | 
| 304 | 
            +
                      expect(configuration.max_data_ex_db_records_per_request).to eq(1000)
         | 
| 305 | 
            +
                    end
         | 
| 306 | 
            +
                  end
         | 
| 307 | 
            +
             | 
| 308 | 
            +
                  context "data_exposure is empty" do
         | 
| 309 | 
            +
                    it "should set max_data_ex_db_records_per_request to default" do
         | 
| 310 | 
            +
                      no_data_ex = double(
         | 
| 311 | 
            +
                        "no_data_ex",
         | 
| 312 | 
            +
                        read: {
         | 
| 313 | 
            +
                          version: 1,
         | 
| 314 | 
            +
                          applications: [
         | 
| 315 | 
            +
                            app_id: "app_id",
         | 
| 316 | 
            +
                            name: "test",
         | 
| 317 | 
            +
                            api_key: "api_key",
         | 
| 318 | 
            +
                            data_exposure: {}
         | 
| 319 | 
            +
                          ]
         | 
| 320 | 
            +
                        }.to_json
         | 
| 321 | 
            +
                      )
         | 
| 322 | 
            +
                      expect(File).to receive(:file?).with(
         | 
| 323 | 
            +
                        File.join(Dir.getwd, "no_data_ex.config")
         | 
| 324 | 
            +
                      ).and_return(true)
         | 
| 325 | 
            +
                      expect(File).to receive(:open).with(
         | 
| 326 | 
            +
                        File.join(Dir.getwd, "no_data_ex.config")
         | 
| 327 | 
            +
                      ).and_return(no_data_ex)
         | 
| 328 | 
            +
                      expect(File).to receive(:file?).with(
         | 
| 329 | 
            +
                        "config/tcell_agent_payloads.config"
         | 
| 330 | 
            +
                      ).and_return(false)
         | 
| 331 | 
            +
                      configuration = Configuration.new("no_data_ex.config")
         | 
| 332 | 
            +
             | 
| 333 | 
            +
                      expect(configuration.max_data_ex_db_records_per_request).to eq(1000)
         | 
| 334 | 
            +
                    end
         | 
| 335 | 
            +
                  end
         | 
| 336 | 
            +
             | 
| 337 | 
            +
                  context "data_exposure contains an override" do
         | 
| 338 | 
            +
                    it "should set max_data_ex_db_records_per_request to override" do
         | 
| 339 | 
            +
                      no_data_ex = double(
         | 
| 340 | 
            +
                        "no_data_ex",
         | 
| 341 | 
            +
                        read: {
         | 
| 342 | 
            +
                          version: 1,
         | 
| 343 | 
            +
                          applications: [
         | 
| 344 | 
            +
                            app_id: "app_id",
         | 
| 345 | 
            +
                            name: "test",
         | 
| 346 | 
            +
                            api_key: "api_key",
         | 
| 347 | 
            +
                            data_exposure: {
         | 
| 348 | 
            +
                              max_data_ex_db_records_per_request: 5000
         | 
| 349 | 
            +
                            }
         | 
| 350 | 
            +
                          ]
         | 
| 351 | 
            +
                        }.to_json
         | 
| 352 | 
            +
                      )
         | 
| 353 | 
            +
                      expect(File).to receive(:file?).with(
         | 
| 354 | 
            +
                        File.join(Dir.getwd, "no_data_ex.config")
         | 
| 355 | 
            +
                      ).and_return(true)
         | 
| 356 | 
            +
                      expect(File).to receive(:open).with(
         | 
| 357 | 
            +
                        File.join(Dir.getwd, "no_data_ex.config")
         | 
| 358 | 
            +
                      ).and_return(no_data_ex)
         | 
| 359 | 
            +
                      expect(File).to receive(:file?).with(
         | 
| 360 | 
            +
                        "config/tcell_agent_payloads.config"
         | 
| 361 | 
            +
                      ).and_return(false)
         | 
| 362 | 
            +
                      configuration = Configuration.new("no_data_ex.config")
         | 
| 363 | 
            +
             | 
| 364 | 
            +
                      expect(configuration.max_data_ex_db_records_per_request).to eq(5000)
         | 
| 365 | 
            +
                    end
         | 
| 366 | 
            +
                  end
         | 
| 367 | 
            +
                end
         | 
| 368 | 
            +
             | 
| 369 | 
            +
              end
         | 
| 370 | 
            +
             | 
| 371 | 
            +
            end
         | 
| @@ -64,24 +64,24 @@ module TCellAgent | |
| 64 64 | 
             
                          end
         | 
| 65 65 | 
             
                          it "alerts on get xss payload" do
         | 
| 66 66 | 
             
                            response = request.get("/foo?xyz=%3Cscript%3Ealert(1)%3C%2Fscript%3E", 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6')
         | 
| 67 | 
            -
                            expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"xyz", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"/foo?xyz=", "tid"=>"a-b-c-d-e-f"}
         | 
| 67 | 
            +
                            expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"xyz", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"http://example.org/foo?xyz=", "tid"=>"a-b-c-d-e-f"}
         | 
| 68 68 | 
             
                            expect(TCellAgent.event_queue).to include(expected_as)
         | 
| 69 69 | 
             
                          end
         | 
| 70 70 | 
             
                          it "alerts on post xss payload" do
         | 
| 71 71 | 
             
                            response = request.post("/foo", :input => "x=<script>alert(1)</script>", 'REMOTE_ADDR' => '1.2.3.4,3.4.5.6')
         | 
| 72 | 
            -
                            expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"x", "remote_addr"=>"1.2.3.4", "m"=>"POST", "loc"=>"/foo", "tid"=>"a-b-c-d-e-f"}
         | 
| 72 | 
            +
                            expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"x", "remote_addr"=>"1.2.3.4", "m"=>"POST", "loc"=>"http://example.org/foo", "tid"=>"a-b-c-d-e-f"}
         | 
| 73 73 | 
             
                            expect(TCellAgent.event_queue).to include(expected_as)
         | 
| 74 74 | 
             
                          end #/it
         | 
| 75 75 | 
             
                          it "alerts on get xss payload with route_id" do
         | 
| 76 76 | 
             
                            response = request2.get("/foo?xyz=%3Cscript%3Ealert(1)%3C%2Fscript%3E")
         | 
| 77 | 
            -
                            expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"xyz", "remote_addr"=>nil, "rou"=>"myrouteid", "m"=>"GET", "loc"=>"/foo?xyz=", "tid"=>"a-b-c-d-e-f"}
         | 
| 77 | 
            +
                            expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"xyz", "remote_addr"=>nil, "rou"=>"myrouteid", "m"=>"GET", "loc"=>"http://example.org/foo?xyz=", "tid"=>"a-b-c-d-e-f"}
         | 
| 78 78 | 
             
                            expect(TCellAgent.event_queue).to include(expected_as)
         | 
| 79 79 | 
             
                          end
         | 
| 80 80 | 
             
                          it "checks that payload is sent in xss with route_id" do
         | 
| 81 81 | 
             
                            old_uap = TCellAgent.configuration.allow_unencrypted_appsensor_payloads
         | 
| 82 82 | 
             
                            TCellAgent.configuration.allow_unencrypted_appsensor_payloads = true
         | 
| 83 83 | 
             
                            response = request2.get("/foo?xyz=%3Cscript%3Ealert(1)%3C%2Fscript%3E")
         | 
| 84 | 
            -
                            expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"xyz", "remote_addr"=>nil, "rou"=>"myrouteid", "m"=>"GET", "loc"=>"/foo?xyz=", "tid"=>"a-b-c-d-e-f", "payload"=>"<script>alert(1)</script>"}
         | 
| 84 | 
            +
                            expected_as = {"event_type"=>"as", "dp"=>"xss", "param"=>"xyz", "remote_addr"=>nil, "rou"=>"myrouteid", "m"=>"GET", "loc"=>"http://example.org/foo?xyz=", "tid"=>"a-b-c-d-e-f", "payload"=>"<script>alert(1)</script>"}
         | 
| 85 85 | 
             
                            TCellAgent.configuration.allow_unencrypted_appsensor_payloads = old_uap
         | 
| 86 86 | 
             
                            expect(TCellAgent.event_queue).to include(expected_as)
         | 
| 87 87 | 
             
                          end
         | 
| @@ -104,7 +104,7 @@ module TCellAgent | |
| 104 104 | 
             
                          it "alerts on get sqli payload" do
         | 
| 105 105 | 
             
                            # ' OR '3'='3
         | 
| 106 106 | 
             
                            response = request.get("/foo?xyz=abds&def=%27%20OR%20%273%27%3D%273", 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6')
         | 
| 107 | 
            -
                            expected_as = {"event_type"=>"as", "dp"=>"sqli", "param"=>"def", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"/foo?xyz=&def=", "tid"=>"a-b-c-d-e-f"}
         | 
| 107 | 
            +
                            expected_as = {"event_type"=>"as", "dp"=>"sqli", "param"=>"def", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"http://example.org/foo?xyz=&def=", "tid"=>"a-b-c-d-e-f"}
         | 
| 108 108 | 
             
                            expect(TCellAgent.event_queue).to include(expected_as)
         | 
| 109 109 | 
             
                          end
         | 
| 110 110 | 
             
                        end #/conext
         | 
| @@ -124,14 +124,14 @@ module TCellAgent | |
| 124 124 | 
             
                          end
         | 
| 125 125 | 
             
                          it "alerts on most obvious payload" do
         | 
| 126 126 | 
             
                            response = request.get("/foo?xyz=/etc/passwd", 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6')
         | 
| 127 | 
            -
                            expected_as = {"event_type"=>"as", "dp"=>"fpt", "param"=>"xyz", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"/foo?xyz=", "tid"=>"a-b-c-d-e-f"}
         | 
| 127 | 
            +
                            expected_as = {"event_type"=>"as", "dp"=>"fpt", "param"=>"xyz", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"http://example.org/foo?xyz=", "tid"=>"a-b-c-d-e-f"}
         | 
| 128 128 | 
             
                            expect(TCellAgent.event_queue).to include(expected_as)
         | 
| 129 129 | 
             
                          end
         | 
| 130 130 | 
             
                          it "checks that payload is sent" do
         | 
| 131 131 | 
             
                            old_uap = TCellAgent.configuration.allow_unencrypted_appsensor_payloads
         | 
| 132 132 | 
             
                            TCellAgent.configuration.allow_unencrypted_appsensor_payloads = true
         | 
| 133 133 | 
             
                            response = request.get("/foo?xyz=/etc/passwd", 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6')
         | 
| 134 | 
            -
                            expected_as = {"event_type"=>"as", "dp"=>"fpt", "param"=>"xyz", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"/foo?xyz=", "tid"=>"a-b-c-d-e-f", "payload"=>"/etc/passwd"}
         | 
| 134 | 
            +
                            expected_as = {"event_type"=>"as", "dp"=>"fpt", "param"=>"xyz", "remote_addr"=>"1.3.3.4", "m"=>"GET", "loc"=>"http://example.org/foo?xyz=", "tid"=>"a-b-c-d-e-f", "payload"=>"/etc/passwd"}
         | 
| 135 135 | 
             
                            TCellAgent.configuration.allow_unencrypted_appsensor_payloads = old_uap
         | 
| 136 136 | 
             
                            expect(TCellAgent.event_queue).to include(expected_as)
         | 
| 137 137 | 
             
                          end
         | 
| @@ -0,0 +1,289 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module TCellAgent
         | 
| 4 | 
            +
              module SensorEvents
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                describe TCellAppSensorEventProcessor do
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  describe "#appsensor_event" do
         | 
| 9 | 
            +
                    before(:each) do
         | 
| 10 | 
            +
                      @app_sensor_event_process = TCellAppSensorEventProcessor.new
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    context "whitelist not present" do
         | 
| 14 | 
            +
                      context "a term that is blacklisted" do
         | 
| 15 | 
            +
                        it "should obfuscate the payload" do
         | 
| 16 | 
            +
                          event = double("event")
         | 
| 17 | 
            +
                          configuration = double(
         | 
| 18 | 
            +
                            "configuration",
         | 
| 19 | 
            +
                            whitelist_present: false,
         | 
| 20 | 
            +
                            raise_exceptions: true,
         | 
| 21 | 
            +
                            blacklisted_params: double("bp", {"passwd" => true, "has_key?" => true})
         | 
| 22 | 
            +
                          )
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                          expect(TCellAgent).to receive(:configuration).and_return(configuration)
         | 
| 25 | 
            +
                          expect(TCellAgent::SensorEvents::TCellAppSensorEvent).to receive(:new).with(
         | 
| 26 | 
            +
                            nil,
         | 
| 27 | 
            +
                            "xss",
         | 
| 28 | 
            +
                            nil,
         | 
| 29 | 
            +
                            nil,
         | 
| 30 | 
            +
                            "PASSWD",
         | 
| 31 | 
            +
                            nil,
         | 
| 32 | 
            +
                            nil,
         | 
| 33 | 
            +
                            nil,
         | 
| 34 | 
            +
                            nil,
         | 
| 35 | 
            +
                            nil,
         | 
| 36 | 
            +
                            "BLACKLISTED"
         | 
| 37 | 
            +
                          ).and_return(event)
         | 
| 38 | 
            +
                          expect(TCellAgent).to receive(:send_event)
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                          @app_sensor_event_process.appsensor_event("xss", "PASSWD", nil, "%3Cscript%3Ealert(1)%3C%2Fscript%3E")
         | 
| 41 | 
            +
                        end
         | 
| 42 | 
            +
                      end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                      context "a term that is not blacklisted" do
         | 
| 45 | 
            +
                        it "should not obfuscate the payload" do
         | 
| 46 | 
            +
                          event = double("event")
         | 
| 47 | 
            +
                          configuration = double(
         | 
| 48 | 
            +
                            "configuration",
         | 
| 49 | 
            +
                            whitelist_present: false,
         | 
| 50 | 
            +
                            raise_exceptions: true,
         | 
| 51 | 
            +
                            blacklisted_params: double("bp", {"has_key?" => false})
         | 
| 52 | 
            +
                          )
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                          expect(TCellAgent).to receive(:configuration).and_return(configuration)
         | 
| 55 | 
            +
                          expect(TCellAgent).to receive(:configuration).and_return(configuration)
         | 
| 56 | 
            +
                          expect(TCellAgent::SensorEvents::TCellAppSensorEvent).to receive(:new).with(
         | 
| 57 | 
            +
                            nil,
         | 
| 58 | 
            +
                            "xss",
         | 
| 59 | 
            +
                            nil,
         | 
| 60 | 
            +
                            nil,
         | 
| 61 | 
            +
                            "PASSWD",
         | 
| 62 | 
            +
                            nil,
         | 
| 63 | 
            +
                            nil,
         | 
| 64 | 
            +
                            nil,
         | 
| 65 | 
            +
                            nil,
         | 
| 66 | 
            +
                            nil,
         | 
| 67 | 
            +
                            "%3Cscript%3Ealert(1)%3C%2Fscript%3E"
         | 
| 68 | 
            +
                          ).and_return(event)
         | 
| 69 | 
            +
                          expect(TCellAgent).to receive(:send_event)
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                          @app_sensor_event_process.appsensor_event("xss", "PASSWD", nil, "%3Cscript%3Ealert(1)%3C%2Fscript%3E")
         | 
| 72 | 
            +
                        end
         | 
| 73 | 
            +
                      end
         | 
| 74 | 
            +
                    end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                    context "whitelist present" do
         | 
| 77 | 
            +
                      context "a term is whitelisted" do
         | 
| 78 | 
            +
                        context "a term that is blacklisted" do
         | 
| 79 | 
            +
                          it "should obfuscate the payload" do
         | 
| 80 | 
            +
                            event = double("event")
         | 
| 81 | 
            +
                            configuration = double(
         | 
| 82 | 
            +
                              "configuration",
         | 
| 83 | 
            +
                              whitelist_present: true,
         | 
| 84 | 
            +
                              raise_exceptions: true,
         | 
| 85 | 
            +
                              blacklisted_params: double("bp", {"passwd" => true, "has_key?" => true}),
         | 
| 86 | 
            +
                              whitelisted_params: double("wp", {"passwd" => true, "has_key?" => true})
         | 
| 87 | 
            +
                            )
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                            expect(TCellAgent).to receive(:configuration).and_return(configuration)
         | 
| 90 | 
            +
                            expect(TCellAgent::SensorEvents::TCellAppSensorEvent).to receive(:new).with(
         | 
| 91 | 
            +
                              nil,
         | 
| 92 | 
            +
                              "xss",
         | 
| 93 | 
            +
                              nil,
         | 
| 94 | 
            +
                              nil,
         | 
| 95 | 
            +
                              "PASSWD",
         | 
| 96 | 
            +
                              nil,
         | 
| 97 | 
            +
                              nil,
         | 
| 98 | 
            +
                              nil,
         | 
| 99 | 
            +
                              nil,
         | 
| 100 | 
            +
                              nil,
         | 
| 101 | 
            +
                              "BLACKLISTED"
         | 
| 102 | 
            +
                            ).and_return(event)
         | 
| 103 | 
            +
                            expect(TCellAgent).to receive(:send_event)
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                            @app_sensor_event_process.appsensor_event("xss", "PASSWD", nil, "%3Cscript%3Ealert(1)%3C%2Fscript%3E")
         | 
| 106 | 
            +
                          end
         | 
| 107 | 
            +
                        end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                        context "a term that is not blacklisted" do
         | 
| 110 | 
            +
                          it "should not obfuscate the payload" do
         | 
| 111 | 
            +
                            event = double("event")
         | 
| 112 | 
            +
                            configuration = double(
         | 
| 113 | 
            +
                              "configuration",
         | 
| 114 | 
            +
                              whitelist_present: true,
         | 
| 115 | 
            +
                              raise_exceptions: true,
         | 
| 116 | 
            +
                              blacklisted_params: double("bp", {"has_key?" => false}),
         | 
| 117 | 
            +
                              whitelisted_params: double("wp", {"passwd" => true, "has_key?" => true})
         | 
| 118 | 
            +
                            )
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                            expect(TCellAgent).to receive(:configuration).and_return(configuration)
         | 
| 121 | 
            +
                            expect(TCellAgent).to receive(:configuration).and_return(configuration)
         | 
| 122 | 
            +
                            expect(TCellAgent).to receive(:configuration).and_return(configuration)
         | 
| 123 | 
            +
                            expect(TCellAgent::SensorEvents::TCellAppSensorEvent).to receive(:new).with(
         | 
| 124 | 
            +
                              nil,
         | 
| 125 | 
            +
                              "xss",
         | 
| 126 | 
            +
                              nil,
         | 
| 127 | 
            +
                              nil,
         | 
| 128 | 
            +
                              "PASSWD",
         | 
| 129 | 
            +
                              nil,
         | 
| 130 | 
            +
                              nil,
         | 
| 131 | 
            +
                              nil,
         | 
| 132 | 
            +
                              nil,
         | 
| 133 | 
            +
                              nil,
         | 
| 134 | 
            +
                              "%3Cscript%3Ealert(1)%3C%2Fscript%3E"
         | 
| 135 | 
            +
                            ).and_return(event)
         | 
| 136 | 
            +
                            expect(TCellAgent).to receive(:send_event)
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                            @app_sensor_event_process.appsensor_event("xss", "PASSWD", nil, "%3Cscript%3Ealert(1)%3C%2Fscript%3E")
         | 
| 139 | 
            +
                          end
         | 
| 140 | 
            +
                        end
         | 
| 141 | 
            +
                      end
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                      context "a term is not whitelisted" do
         | 
| 144 | 
            +
                        context "a term that is blacklisted" do
         | 
| 145 | 
            +
                          it "should obfuscate the payload" do
         | 
| 146 | 
            +
                            event = double("event")
         | 
| 147 | 
            +
                            configuration = double(
         | 
| 148 | 
            +
                              "configuration",
         | 
| 149 | 
            +
                              whitelist_present: true,
         | 
| 150 | 
            +
                              raise_exceptions: true,
         | 
| 151 | 
            +
                              blacklisted_params: double("bp", {"passwd" => true, "has_key?" => true}),
         | 
| 152 | 
            +
                              whitelisted_params: double("wp", {"has_key?" => false})
         | 
| 153 | 
            +
                            )
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                            expect(TCellAgent).to receive(:configuration).and_return(configuration)
         | 
| 156 | 
            +
                            expect(TCellAgent::SensorEvents::TCellAppSensorEvent).to receive(:new).with(
         | 
| 157 | 
            +
                              nil,
         | 
| 158 | 
            +
                              "xss",
         | 
| 159 | 
            +
                              nil,
         | 
| 160 | 
            +
                              nil,
         | 
| 161 | 
            +
                              "PASSWD",
         | 
| 162 | 
            +
                              nil,
         | 
| 163 | 
            +
                              nil,
         | 
| 164 | 
            +
                              nil,
         | 
| 165 | 
            +
                              nil,
         | 
| 166 | 
            +
                              nil,
         | 
| 167 | 
            +
                              "BLACKLISTED"
         | 
| 168 | 
            +
                            ).and_return(event)
         | 
| 169 | 
            +
                            expect(TCellAgent).to receive(:send_event)
         | 
| 170 | 
            +
             | 
| 171 | 
            +
                            @app_sensor_event_process.appsensor_event("xss", "PASSWD", nil, "%3Cscript%3Ealert(1)%3C%2Fscript%3E")
         | 
| 172 | 
            +
                          end
         | 
| 173 | 
            +
                        end
         | 
| 174 | 
            +
             | 
| 175 | 
            +
                        context "a term that is not blacklisted" do
         | 
| 176 | 
            +
                          it "should obfuscate the payload" do
         | 
| 177 | 
            +
                            event = double("event")
         | 
| 178 | 
            +
                            configuration = double(
         | 
| 179 | 
            +
                              "configuration",
         | 
| 180 | 
            +
                              whitelist_present: true,
         | 
| 181 | 
            +
                              raise_exceptions: true,
         | 
| 182 | 
            +
                              blacklisted_params: double("bp", {"has_key?" => false}),
         | 
| 183 | 
            +
                              whitelisted_params: double("wp", {"has_key?" => false})
         | 
| 184 | 
            +
                            )
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                            expect(TCellAgent).to receive(:configuration).and_return(configuration)
         | 
| 187 | 
            +
                            expect(TCellAgent).to receive(:configuration).and_return(configuration)
         | 
| 188 | 
            +
                            expect(TCellAgent).to receive(:configuration).and_return(configuration)
         | 
| 189 | 
            +
                            expect(TCellAgent::SensorEvents::TCellAppSensorEvent).to receive(:new).with(
         | 
| 190 | 
            +
                              nil,
         | 
| 191 | 
            +
                              "xss",
         | 
| 192 | 
            +
                              nil,
         | 
| 193 | 
            +
                              nil,
         | 
| 194 | 
            +
                              "PASSWD",
         | 
| 195 | 
            +
                              nil,
         | 
| 196 | 
            +
                              nil,
         | 
| 197 | 
            +
                              nil,
         | 
| 198 | 
            +
                              nil,
         | 
| 199 | 
            +
                              nil,
         | 
| 200 | 
            +
                              "NOT_WHITELISTED"
         | 
| 201 | 
            +
                            ).and_return(event)
         | 
| 202 | 
            +
                            expect(TCellAgent).to receive(:send_event)
         | 
| 203 | 
            +
             | 
| 204 | 
            +
                            @app_sensor_event_process.appsensor_event("xss", "PASSWD", nil, "%3Cscript%3Ealert(1)%3C%2Fscript%3E")
         | 
| 205 | 
            +
                          end
         | 
| 206 | 
            +
                        end
         | 
| 207 | 
            +
                      end
         | 
| 208 | 
            +
                    end
         | 
| 209 | 
            +
                  end
         | 
| 210 | 
            +
             | 
| 211 | 
            +
                  describe "#for_params" do
         | 
| 212 | 
            +
                    context "with body_params" do
         | 
| 213 | 
            +
                      it "should iterate over body params" do
         | 
| 214 | 
            +
                        app_sensor_event_process = TCellAppSensorEventProcessor.new
         | 
| 215 | 
            +
                        app_sensor_event_process.request_content_length = 67
         | 
| 216 | 
            +
                        app_sensor_event_process.request_content_type = "application/json"
         | 
| 217 | 
            +
                        app_sensor_event_process.request_body = {username:"tester",password:"pass"}.to_json
         | 
| 218 | 
            +
             | 
| 219 | 
            +
                        expect(app_sensor_event_process.body_params).to eq({"username"=>"tester","password"=>"pass"})
         | 
| 220 | 
            +
             | 
| 221 | 
            +
                        iterated_over = {}
         | 
| 222 | 
            +
             | 
| 223 | 
            +
                        app_sensor_event_process.for_params do |method, param_name, param_value|
         | 
| 224 | 
            +
                          iterated_over[param_name] = param_value
         | 
| 225 | 
            +
                        end
         | 
| 226 | 
            +
             | 
| 227 | 
            +
                        expect(iterated_over).to eq({"username"=>"tester", "password"=>"pass"})
         | 
| 228 | 
            +
                      end
         | 
| 229 | 
            +
                    end
         | 
| 230 | 
            +
                  end
         | 
| 231 | 
            +
             | 
| 232 | 
            +
                  describe "#body_params" do
         | 
| 233 | 
            +
                    context "with text/html content type" do
         | 
| 234 | 
            +
                      it "should set the body params to empty" do
         | 
| 235 | 
            +
                        app_sensor_event_process = TCellAppSensorEventProcessor.new
         | 
| 236 | 
            +
                        app_sensor_event_process.request_content_length = 67
         | 
| 237 | 
            +
                        app_sensor_event_process.request_content_type = "text/html"
         | 
| 238 | 
            +
                        app_sensor_event_process.request_body = {username:"tester",password:"pass"}.to_json
         | 
| 239 | 
            +
             | 
| 240 | 
            +
                        expect(app_sensor_event_process.body_params).to eq({})
         | 
| 241 | 
            +
                      end
         | 
| 242 | 
            +
                    end
         | 
| 243 | 
            +
             | 
| 244 | 
            +
                    context "with application/json content type" do
         | 
| 245 | 
            +
                      before(:each) do
         | 
| 246 | 
            +
                        @app_sensor_event_process = TCellAppSensorEventProcessor.new
         | 
| 247 | 
            +
                        @app_sensor_event_process.request_content_length = 67
         | 
| 248 | 
            +
                        @app_sensor_event_process.request_content_type = "application/json"
         | 
| 249 | 
            +
                      end
         | 
| 250 | 
            +
             | 
| 251 | 
            +
                      context "with empty request body" do
         | 
| 252 | 
            +
                        it "should set the body params to empty" do
         | 
| 253 | 
            +
                          @app_sensor_event_process.request_body = nil
         | 
| 254 | 
            +
             | 
| 255 | 
            +
                          expect(@app_sensor_event_process.body_params).to eq({})
         | 
| 256 | 
            +
                        end
         | 
| 257 | 
            +
                      end
         | 
| 258 | 
            +
             | 
| 259 | 
            +
                      context "with bad json in the body" do
         | 
| 260 | 
            +
                        it "should set the body params to empty" do
         | 
| 261 | 
            +
                          @app_sensor_event_process.request_body = '{"username":"tester""password":"pass"}'
         | 
| 262 | 
            +
             | 
| 263 | 
            +
                          expect(@app_sensor_event_process.body_params).to eq({})
         | 
| 264 | 
            +
                        end
         | 
| 265 | 
            +
                      end
         | 
| 266 | 
            +
             | 
| 267 | 
            +
                      context "with valid json in the body" do
         | 
| 268 | 
            +
                        it "should set the body params" do
         | 
| 269 | 
            +
                          @app_sensor_event_process.request_body = {username:"tester",password:"pass"}.to_json
         | 
| 270 | 
            +
             | 
| 271 | 
            +
                          expect(@app_sensor_event_process.body_params).to eq({"username"=>"tester","password"=>"pass"})
         | 
| 272 | 
            +
                        end
         | 
| 273 | 
            +
                      end
         | 
| 274 | 
            +
             | 
| 275 | 
            +
                      context "with a json body that's too big" do
         | 
| 276 | 
            +
                        it "should set the body params to empty" do
         | 
| 277 | 
            +
                          @app_sensor_event_process.request_content_length = 2000000
         | 
| 278 | 
            +
                          @app_sensor_event_process.request_body = '{"username":"tester""password":"pass"}'
         | 
| 279 | 
            +
             | 
| 280 | 
            +
                          expect(@app_sensor_event_process.body_params).to eq({})
         | 
| 281 | 
            +
                        end
         | 
| 282 | 
            +
                      end
         | 
| 283 | 
            +
                    end
         | 
| 284 | 
            +
                  end
         | 
| 285 | 
            +
             | 
| 286 | 
            +
                end
         | 
| 287 | 
            +
             | 
| 288 | 
            +
              end
         | 
| 289 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: tcell_agent
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.2. | 
| 4 | 
            +
              version: 0.2.11
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Garrett
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2016- | 
| 11 | 
            +
            date: 2016-04-06 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rest-client
         | 
| @@ -234,6 +234,7 @@ files: | |
| 234 234 | 
             
            - spec/lib/tcell_agent/agent/static_agent_spec.rb
         | 
| 235 235 | 
             
            - spec/lib/tcell_agent/api/api_spec.rb
         | 
| 236 236 | 
             
            - spec/lib/tcell_agent/appsensor_spec.rb
         | 
| 237 | 
            +
            - spec/lib/tcell_agent/configuration_spec.rb
         | 
| 237 238 | 
             
            - spec/lib/tcell_agent/instrumentation_spec.rb
         | 
| 238 239 | 
             
            - spec/lib/tcell_agent/policies/appsensor_policy_spec.rb
         | 
| 239 240 | 
             
            - spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb
         | 
| @@ -252,6 +253,7 @@ files: | |
| 252 253 | 
             
            - spec/lib/tcell_agent/rails_spec.rb
         | 
| 253 254 | 
             
            - spec/lib/tcell_agent/sensor_events/dlp_spec.rb
         | 
| 254 255 | 
             
            - spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb
         | 
| 256 | 
            +
            - spec/lib/tcell_agent/sensor_events/tcell_app_sensor_event_processor_spec.rb
         | 
| 255 257 | 
             
            - spec/lib/tcell_agent/sensor_events/util/redirect_utils_spec.rb
         | 
| 256 258 | 
             
            - spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb
         | 
| 257 259 | 
             
            - spec/lib/tcell_agent/utils/bounded_queue_spec.rb
         | 
| @@ -338,6 +340,7 @@ test_files: | |
| 338 340 | 
             
            - spec/lib/tcell_agent/agent/static_agent_spec.rb
         | 
| 339 341 | 
             
            - spec/lib/tcell_agent/api/api_spec.rb
         | 
| 340 342 | 
             
            - spec/lib/tcell_agent/appsensor_spec.rb
         | 
| 343 | 
            +
            - spec/lib/tcell_agent/configuration_spec.rb
         | 
| 341 344 | 
             
            - spec/lib/tcell_agent/instrumentation_spec.rb
         | 
| 342 345 | 
             
            - spec/lib/tcell_agent/policies/appsensor_policy_spec.rb
         | 
| 343 346 | 
             
            - spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb
         | 
| @@ -356,6 +359,7 @@ test_files: | |
| 356 359 | 
             
            - spec/lib/tcell_agent/rails_spec.rb
         | 
| 357 360 | 
             
            - spec/lib/tcell_agent/sensor_events/dlp_spec.rb
         | 
| 358 361 | 
             
            - spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb
         | 
| 362 | 
            +
            - spec/lib/tcell_agent/sensor_events/tcell_app_sensor_event_processor_spec.rb
         | 
| 359 363 | 
             
            - spec/lib/tcell_agent/sensor_events/util/redirect_utils_spec.rb
         | 
| 360 364 | 
             
            - spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb
         | 
| 361 365 | 
             
            - spec/lib/tcell_agent/utils/bounded_queue_spec.rb
         |