Class: Contrast::Components::Settings::Interface
- Extended by:
- Config
- Includes:
- Logger::InstanceMethods
- Defined in:
- lib/contrast/components/settings.rb
Overview
This is a class.
Constant Summary
Constants included from Config
Config::CONTRAST_LOG, Config::CONTRAST_NAME, Config::DATE_TIME
Instance Attribute Summary collapse
-
#agent_state ⇒ Object
readonly
Agent state.
-
#app_settings_last_httpdate ⇒ String
readonly
This value should be sent be TS in the Last-Modified header to sync and save resources if the two dates are the same.
-
#application_state ⇒ Object
readonly
Current Application State.
-
#assess_state ⇒ Object
readonly
Current state for Assess.
-
#excluder ⇒ Contrast::Agent::Excluder
readonly
A wrapper around the exclusion rules for the application.
-
#last_app_update_ms ⇒ Integer
readonly
The time, in ms, that application settings last changed.
-
#last_server_update_ms ⇒ Integer
readonly
The time, in ms, that server settings last changed.
-
#protect_state ⇒ Object
readonly
Current State for Protect.
-
#sensitive_data_masking ⇒ Contrast::Agent::Reporting::Settings::SensitiveDataMasking
readonly
This the structure that will hold the masking rules send from TS.
-
#server_settings_last_httpdate ⇒ String
readonly
This value should be sent be TS in the Last-Modified header to sync and save resources if the two dates are the same.
-
#tainted_columns ⇒ Object
readonly
tainted_columns are database columns that receive unsanitized input.
Instance Method Summary collapse
-
#initialize ⇒ Interface
constructor
A new instance of Interface.
-
#reset_state(purge: false) ⇒ Object
Wipe state to zero.
-
#update_agent_lib_log(new_log_level) ⇒ Object
Update AgentLib log level.
-
#update_assess_server_features(assess) ⇒ Object
Update Assess server features.
-
#update_assess_state ⇒ Struct
We save the session_id, reset and set it again if available.
- #update_exclusion_matchers(exclusions) ⇒ Object
- #update_from_application_settings(settings_response) ⇒ Object
- #update_from_server_features(features_response) ⇒ Object
-
#update_loggers(server_features) ⇒ Object
Updates logging settings.
- #update_matchers_and_sensitive_data(app_settings) ⇒ Object
-
#update_sensitive_data_policy(sensitive_data_masking) ⇒ Object
Update the sensitive data masking policy from settings, received from TS.
Methods included from Logger::InstanceMethods
Constructor Details
#initialize ⇒ Interface
Returns a new instance of Interface.
94 95 96 |
# File 'lib/contrast/components/settings.rb', line 94 def initialize reset_state end |
Instance Attribute Details
#agent_state ⇒ Object (readonly)
Agent state. Used for extracting Agent level settings.
logger_path Path to the log file. logger_level Log level for the logger. cef_logger_path Path to the log file. cef_logger_level Log level for the logger.
43 44 45 |
# File 'lib/contrast/components/settings.rb', line 43 def agent_state @agent_state end |
#app_settings_last_httpdate ⇒ String (readonly)
This value should be sent be TS in the Last-Modified header to sync and save resources if the two dates are the same. format: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
92 93 94 |
# File 'lib/contrast/components/settings.rb', line 92 def app_settings_last_httpdate @app_settings_last_httpdate end |
#application_state ⇒ Object (readonly)
Current Application State.
modes_by_id [Hash<Rule_id => Mode] Returns Hash with rules and their current mode.
68 69 70 |
# File 'lib/contrast/components/settings.rb', line 68 def application_state @application_state end |
#assess_state ⇒ Object (readonly)
Current state for Assess. enabled [Boolean] Indicate if the assess feature set is enabled for this server or not.
sampling [Hash<AssessSampling>] Hash of AssessSampling Used to control the sampling feature in the agent:
baseline [Integer] The number of baseline requests to take before switching to sampling
for the window.
enabled [Boolean] If the sampling feature should be used or not.
frequency [Integer] The number of requests to skip before observing during the sampling
window after the baseline.
responseFrequency [Integer]
window [Integer]
disabled_assess_rules [array<AssessRuleID(String)>] Assess rules to disable for this application.
58 59 60 |
# File 'lib/contrast/components/settings.rb', line 58 def assess_state @assess_state end |
#excluder ⇒ Contrast::Agent::Excluder (readonly)
Returns a wrapper around the exclusion rules for the application.
82 83 84 |
# File 'lib/contrast/components/settings.rb', line 82 def excluder @excluder end |
#last_app_update_ms ⇒ Integer (readonly)
Returns the time, in ms, that application settings last changed.
78 79 80 |
# File 'lib/contrast/components/settings.rb', line 78 def last_app_update_ms @last_app_update_ms end |
#last_server_update_ms ⇒ Integer (readonly)
Returns the time, in ms, that server settings last changed.
80 81 82 |
# File 'lib/contrast/components/settings.rb', line 80 def last_server_update_ms @last_server_update_ms end |
#protect_state ⇒ Object (readonly)
Current State for Protect. enabled [Boolean] Indicate if the protect feature set is enabled for this server or not.
Protection rules are returned as: rules [Hash<RULE_ID => MODE>, nil] Hash with rule_id as key and mode as value
64 65 66 |
# File 'lib/contrast/components/settings.rb', line 64 def protect_state @protect_state end |
#sensitive_data_masking ⇒ Contrast::Agent::Reporting::Settings::SensitiveDataMasking (readonly)
This the structure that will hold the masking rules send from TS.
76 77 78 |
# File 'lib/contrast/components/settings.rb', line 76 def sensitive_data_masking @sensitive_data_masking end |
#server_settings_last_httpdate ⇒ String (readonly)
This value should be sent be TS in the Last-Modified header to sync and save resources if the two dates are the same. format: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
87 88 89 |
# File 'lib/contrast/components/settings.rb', line 87 def server_settings_last_httpdate @server_settings_last_httpdate end |
#tainted_columns ⇒ Object (readonly)
tainted_columns are database columns that receive unsanitized input.
36 37 38 |
# File 'lib/contrast/components/settings.rb', line 36 def tainted_columns @tainted_columns end |
Instance Method Details
#reset_state(purge: false) ⇒ Object
Wipe state to zero.
221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/contrast/components/settings.rb', line 221 def reset_state purge: false @agent_state = AGENT_STATE_BASE.dup # Keep the protect state, since once set the rules depend ont it. # The state will be update on first settings response from TS. @protect_state = PROTECT_STATE_BASE.dup if purge || @protect_state.nil? update_assess_state @application_state = APPLICATION_STATE_BASE.dup @tainted_columns = {} @sensitive_data_masking = SENSITIVE_DATA_MASKING_BASE.dup @excluder = Contrast::Agent::Excluder.new end |
#update_agent_lib_log(new_log_level) ⇒ Object
Update AgentLib log level
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/contrast/components/settings.rb', line 170 def update_agent_lib_log new_log_level agent_lib_log_level = Contrast::AgentLib::InterfaceBase::LOG_LEVEL[0] if new_log_level.empty? agent_lib_log_level ||= Contrast::AgentLib::InterfaceBase::LOG_LEVEL.key(new_log_level.upcase) # detect if the provided level is invalid and log if it is # by default if we pass invalid log level - it will leave the last active unless Contrast::AgentLib::InterfaceBase::LOG_LEVEL.value?(new_log_level.upcase) cur_active = Contrast::AGENT_LIB.log_level logger.debug('The provided level was invalid, so the logger stays to the last active: ', active: cur_active, provided_level: new_log_level) end Contrast::AGENT_LIB.(true, agent_lib_log_level) end |
#update_assess_server_features(assess) ⇒ Object
Update Assess server features
124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/contrast/components/settings.rb', line 124 def update_assess_server_features assess return if settings_empty?(assess.enabled?) @assess_state.enabled = assess.enabled? update_config_from_settings(%i[assess enable], assess.enabled?) @assess_state.sampling_settings = assess.sampling samplings_path = Contrast::Components::Sampling::Interface::CANON_NAME.split('.').map(&:to_sym) Contrast::Components::Sampling::Interface::CONFIG_VALUES.each do |field| lookup_field = field == 'enable' ? :enabled : field.to_sym update_config_from_settings(samplings_path + [field.to_sym], assess.sampling.send(lookup_field)) end end |
#update_assess_state ⇒ Struct
We save the session_id, reset and set it again if available. This done so that reporting between updates won’t trigger argument error for missing session_id given one is already set and used with the first application create response received from TS.
239 240 241 242 243 244 245 246 |
# File 'lib/contrast/components/settings.rb', line 239 def update_assess_state current_session_id = @assess_state&.session_id @assess_state = ASSESS_STATE_BASE.dup # There is application settings update for the session id if new is received. # Here we make sure not to delete the already set one. @assess_state&.session_id = current_session_id unless current_session_id&.empty? @assess_state end |
#update_exclusion_matchers(exclusions) ⇒ Object
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/contrast/components/settings.rb', line 249 def update_exclusion_matchers exclusions matchers = [] exclusions.url_exclusions.each do |exclusion| matchers << Contrast::Agent::ExclusionMatcher.new(exclusion) end exclusions.input_exclusions.each do |exclusion| matchers << Contrast::Agent::ExclusionMatcher.new(exclusion) end # Do not populate the matchers unless we have any. There are certain checks in # SourceMethod that will safe-guard return if there are no exclusions received. # The matching operation is expensive, and the excluder calls are made for each # source, and we do not want to check for exclusions if they are empty. This is # probably redundant as all exclusions default to empty, but will save useless # new object creation at very least. return if Contrast::Utils::DuckUtils.empty_duck?(matchers) @excluder = Contrast::Agent::Excluder.new(matchers) end |
#update_from_application_settings(settings_response) ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/contrast/components/settings.rb', line 187 def update_from_application_settings settings_response return unless (app_settings = settings_response&.application_settings) extract_protect_app_settings(app_settings) update_matchers_and_sensitive_data(app_settings) @assess_state.disabled_assess_rules = app_settings.assess.disabled_rules update_config_from_settings(%i[assess rules disabled_rules], app_settings.assess.disabled_rules) new_session_id = app_settings.assess.session_id unless settings_empty?(new_session_id) @assess_state.session_id = new_session_id # TODO: RUBY-99999 Update the default values and effective config update from TS. # Using the session_id from the settings response to update the config. # The Effective Config sources values are fetched from the # Contrast::CONFIG.config.loaded_config. Some values are displayed from # their components, however not updated here. Using this may cause some # specs to fails check the update of all values from TS. # Contrast::CONFIG.application.session_id = new_session_id update_config_from_settings(%i[application session_id], new_session_id) end @last_app_update_ms = Contrast::Utils::Timer.now_ms @app_settings_last_httpdate = header_application_last_update end |
#update_from_server_features(features_response) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/contrast/components/settings.rb', line 99 def update_from_server_features features_response return unless (server_features = features_response&.server_features) update_loggers(server_features) # TODO: RUBY-99999 Update Bot-Blocker from server settings - check enable value. # For now all protection rules are rebuild on Application update. Bot blocker uses the default # enable from the base rule, and update it's mode on app settings update. # Here we receive also bots for that rule. unless settings_empty?(server_features.protect.enabled?) @protect_state.enabled = server_features.protect.enabled? update_config_from_settings(%i[protect enable], server_features.protect.enabled?) end update_assess_server_features(server_features.assess) @last_server_update_ms = Contrast::Utils::Timer.now_ms # update via response header. We receive header from TS with last update info, setting the # next request's header with the same time will save needless update of settings if there # are no new server features updates after the said time. @server_settings_last_httpdate = header_server_last_update rescue StandardError => e logger.warn('The following error occurred from server update: ', e: e) end |
#update_loggers(server_features) ⇒ Object
Updates logging settings
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/contrast/components/settings.rb', line 140 def update_loggers server_features log_file = server_features.log_file log_level = server_features.log_level # Update logger: Contrast::Logger::Log.instance.update(log_file, log_level) if log_file || log_level unless settings_empty?(log_file) update_config_from_settings(%i[agent logger path], log_file) @agent_state.logger_path = log_file end unless settings_empty?(log_level) update_config_from_settings(%i[agent logger level], log_level) @agent_state.logger_level = log_level end # Update AgentLib Logger update_agent_lib_log(log_level.to_s) # Update CEFlogger: return if server_features.security_logger.settings_blank? cef_logger.build_logger(server_features.security_logger.log_level, server_features.security_logger.log_file) unless settings_empty?(log_file) update_config_from_settings(%i[agent security_logger path], log_file) @agent_state.cef_logger_level = log_file end return unless settings_empty?(log_level) update_config_from_settings(%i[agent security_logger level], log_level) @agent_state.cef_logger_level = log_level end |
#update_matchers_and_sensitive_data(app_settings) ⇒ Object
211 212 213 214 215 216 |
# File 'lib/contrast/components/settings.rb', line 211 def update_matchers_and_sensitive_data app_settings update_exclusion_matchers(app_settings.exclusions) app_settings.protect.virtual_patches = app_settings.protect.virtual_patches unless settings_empty?(app_settings.protect.virtual_patches) update_sensitive_data_policy(app_settings.sensitive_data_masking) end |
#update_sensitive_data_policy(sensitive_data_masking) ⇒ Object
Update the sensitive data masking policy from settings, received from TS. In case the settings are empty, keep current ones.
Ts Response settings for sensitive data masking policy
274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/contrast/components/settings.rb', line 274 def update_sensitive_data_policy sensitive_data_masking @sensitive_data_masking.mask_http_body = sensitive_data_masking.mask_http_body? unless settings_empty?(sensitive_data_masking.mask_http_body?) @sensitive_data_masking.mask_attack_vector = sensitive_data_masking.mask_attack_vector? unless settings_empty?(sensitive_data_masking.mask_attack_vector?) return if settings_empty?(sensitive_data_masking.rules) @sensitive_data_masking.rules = sensitive_data_masking.rules # update with the newly received rules. Contrast::Agent::Reporting::Masker.send(:update_dictionary) end |