Module: Sqreen::Rules

Defined in:
lib/sqreen/rules.rb,
lib/sqreen/rules/attrs.rb,
lib/sqreen/rules/waf_cb.rb,
lib/sqreen/rules/xss_cb.rb,
lib/sqreen/rules/rule_cb.rb,
lib/sqreen/rules/execjs_cb.rb,
lib/sqreen/rules/matcher_rule.rb,
lib/sqreen/rules/not_found_cb.rb,
lib/sqreen/rules/shell_env_cb.rb,
lib/sqreen/rules/auth_track_cb.rb,
lib/sqreen/rules/regexp_rule_cb.rb,
lib/sqreen/rules/url_matches_cb.rb,
lib/sqreen/rules/custom_error_cb.rb,
lib/sqreen/rules/signup_track_cb.rb,
lib/sqreen/rules/blacklist_ips_cb.rb,
lib/sqreen/rules/count_http_codes.rb,
lib/sqreen/rules/run_user_actions.rb,
lib/sqreen/rules/headers_insert_cb.rb,
lib/sqreen/rules/rails_parameters_cb.rb,
lib/sqreen/rules/devise_auth_track_cb.rb,
lib/sqreen/rules/run_req_start_actions.rb,
lib/sqreen/rules/user_agent_matches_cb.rb,
lib/sqreen/rules/devise_signup_track_cb.rb,
lib/sqreen/rules/record_request_context.rb,
lib/sqreen/rules/update_request_context.rb,
lib/sqreen/rules/binding_accessor_metrics.rb,
lib/sqreen/rules/binding_accessor_matcher_cb.rb,
lib/sqreen/rules/crawler_user_agent_matches_cb.rb,
lib/sqreen/rules/crawler_user_agent_matches_metrics_cb.rb

Overview

Sqreen rules

Defined Under Namespace

Modules: Attrs, Matcher Classes: ArgumentFilter, AuthTrackCB, BindingAccessorCounter, BindingAccessorMatcherCB, BindingAccessorMetrics, BlacklistIPsCB, CountHTTPCodes, CrawlerUserAgentMatchesCB, CrawlerUserAgentMatchesMetricsCB, CustomErrorCB, DeviseAuthTrackCB, DeviseSignupTrackCB, ExecJSCB, Haml4CompilerBuildAttributeCB, Haml4ParserScriptHookCB, Haml4ParserTagHookCB, Haml4UtilInterpolationHookCB, Haml5EscapableHookCB, HeadersInsertCB, MatcherRuleCB, NotFoundCB, RailsParametersCB, RecordRequestContext, ReflectedUnsafeXSSCB, ReflectedXSSCB, ReflectedXSSHamlCB, RegexpRuleCB, RuleCB, RunReqStartActions, RunUserActions, ShellEnvCB, SignupTrackCB, SlimSplatBuilderCB, TempleEscapableHookCB, URLMatchesCB, UpdateRequestContext, UserAgentMatchesCB, WAFCB, XSSCB

Class Method Summary collapse

Class Method Details

.cb_from_rule(hash_rule, instrumentation_engine = nil, metrics_store = nil, verifier = nil) ⇒ Object

Given a rule, will instantiate the related callback.

Parameters:

  • hash_rule (Hash)

    Rules metadata

  • instrumentation_engine (Instrumentation) (defaults to: nil)

    Instrumentation engine

  • metrics_store (MetricStore) (defaults to: nil)

    Metrics storage facility

  • verifier (SqreenSignedVerifier) (defaults to: nil)

    Signed verifier



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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
# File 'lib/sqreen/rules.rb', line 79

def self::cb_from_rule(hash_rule, instrumentation_engine=nil, metrics_store = nil, verifier = nil)
  # Check rules signature
  if verifier
    raise InvalidSignatureException unless verifier.verify(hash_rule)
  end

  hook = hash_rule[Attrs::HOOKPOINT]
  klass = hook[Attrs::KLASS]

  # The instrumented class can be from anywhere
  instr_class = Rules.walk_const_get klass

  if instr_class.nil?
    rule_name = hash_rule[Attrs::NAME]
    Sqreen.log.debug { "#{klass} does not exists. Skipping #{rule_name}" }
    return nil
  end

  instr_method = hook[Attrs::METHOD]
  instr_method = instr_method.to_sym
  if instrumentation_engine &&
     !instrumentation_engine.valid_method?(instr_class, instr_method)

    Sqreen.log.debug { "#{instr_method} does not exist on #{klass} Skipping #{rule_name}" }
    return nil
  end

  cbname = hook[Attrs::CALLBACK_CLASS]

  cb_class = nil
  js = hash_rule[Attrs::CALLBACKS]

  if js && !Sqreen::Js::JsService.instance.online?
    unless @issue_nojs_warn
      @issue_nojs_warn = true
      Sqreen.log.warn('No JavaScript engine is available. ' \
          'JavaScript callbacks will be ignored')
    end
    Sqreen.log.debug("Ignoring JS callback #{rule_name}")
    return nil
  end

  cb_class = ExecJSCB if js

  if cbname
    cb_class = if cbname.include?('::')
                 # Only load callbacks from sqreen
                 Rules.walk_const_get(cbname) if cbname.start_with?('::Sqreen::', 'Sqreen::')
               else
                 Rules.const_get(cbname) if Rules.const_defined?(cbname) # rubocop:disable Style/IfInsideElse
               end
  end

  if cb_class.nil?
    Sqreen.log.debug { "Cannot setup #{cbname.inspect} [#{rule_name}]" }
    return nil
  end

  unless cb_class.ancestors.include?(RuleCB)
    Sqreen.log.debug "#{cb_class} does not inherit from RuleCB"
    return nil
  end

  rule_cb = cb_class.new(instr_class, instr_method, hash_rule)

  if metrics_store
    (hash_rule[Attrs::METRICS] || []).each do |metric|
      metrics_store.create_metric(metric, rule_cb)
    end
  end

  rule_cb
rescue => e
  rule_name = nil
  rulespack_id = nil
  if hash_rule.respond_to?(:[])
    rule_name = hash_rule[Attrs::NAME]
    rulespack_id = hash_rule[Attrs::RULESPACK_ID]
  end
  Sqreen::RemoteException.record(
    'exception' => e,
    'rulespack_id' => rulespack_id,
    'rule_name' => rule_name)
  Sqreen.log.debug { "Creating cb from rule #{rule_name} failed (#{e.inspect})" }
  nil
end

.local(configuration) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/sqreen/rules.rb', line 61

def self::local(configuration)
  # Parse and return local rules (path defined in environment)

  path = configuration.get(:local_rules)
  return [] unless path
  begin
    File.open(path) { |f| JSON.load(f) }
  rescue Errno::ENOENT
    Sqreen.log.error "File '#{path}' not found"
    []
  end
end

.walk_const_get(str) ⇒ Object



166
167
168
169
170
171
172
173
# File 'lib/sqreen/rules.rb', line 166

def self::walk_const_get(str)
  obj = Object
  str.split('::').compact.each do |part|
    return nil unless obj.const_defined?(part)
    obj = obj.const_get(part)
  end
  obj
end