sqreen 1.5.0-java → 1.6.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,4 +11,14 @@ module Sqreen
11
11
  @app.call(env)
12
12
  end
13
13
  end
14
+
15
+ class ErrorHandlingMiddleware
16
+ def initialize(app)
17
+ @app = app
18
+ end
19
+
20
+ def call(env)
21
+ @app.call(env)
22
+ end
23
+ end
14
24
  end
@@ -21,5 +21,8 @@ require 'sqreen/rules_callbacks/reflected_xss'
21
21
  require 'sqreen/rules_callbacks/execjs'
22
22
 
23
23
  require 'sqreen/rules_callbacks/binding_accessor_metrics'
24
+ require 'sqreen/rules_callbacks/binding_accessor_matcher'
24
25
  require 'sqreen/rules_callbacks/count_http_codes'
25
26
  require 'sqreen/rules_callbacks/crawler_user_agent_matches_metrics'
27
+
28
+ require 'sqreen/rules_callbacks/custom_error'
@@ -0,0 +1,75 @@
1
+ # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
+ # Please refer to our terms for more information: https://www.sqreen.io/terms.html
3
+
4
+ require 'sqreen/rule_callback'
5
+ require 'sqreen/binding_accessor'
6
+ require 'sqreen/rules_callbacks/matcher_rule'
7
+
8
+ module Sqreen
9
+ module Rules
10
+ # Callback that match on a list or matcher+binding accessor
11
+ class BindingAccessorMatcherCB < RuleCB
12
+ attr_reader :rules
13
+
14
+ # matcher on one elem
15
+ class MatcherElem
16
+ def initialize(expr)
17
+ prepare([expr])
18
+ end
19
+ include Matcher
20
+ end
21
+
22
+ def initialize(klass, method, rule_hash)
23
+ super(klass, method, rule_hash)
24
+ @rules = []
25
+ if @data.empty? || @data['values'].nil? || @data['values'].empty?
26
+ msg = "no rules in data (had #{@data.keys})"
27
+ raise Sqreen::Exception, msg
28
+ end
29
+ prepare_rules(@data['values'])
30
+ end
31
+
32
+ def prepare_rules(rules)
33
+ accessors = Hash.new do |hash, key|
34
+ hash[key] = BindingAccessor.new(key, true)
35
+ end
36
+ @rules = rules.map do |r|
37
+ if r['binding_accessor'].empty?
38
+ raise Sqreen::Exception, "no accessors #{r['id']}"
39
+ end
40
+ [
41
+ r['id'],
42
+ r['binding_accessor'].map { |expression| accessors[expression] },
43
+ MatcherElem.new(r['matcher']),
44
+ r['matcher']['value'],
45
+ ]
46
+ end
47
+ end
48
+
49
+ def pre(inst, *args, &_block)
50
+ resol_cache = Hash.new do |hash, accessor|
51
+ hash[accessor] = accessor.resolve(binding, framework, inst, args)
52
+ end
53
+ @rules.each do |id, accessors, matcher, matcher_ref|
54
+ accessors.each do |accessor|
55
+ val = resol_cache[accessor]
56
+ val = [val] if val.is_a?(String)
57
+ next unless val.respond_to?(:each)
58
+ val.each do |v|
59
+ next if matcher.match(v).nil?
60
+ infos = {
61
+ 'id' => id,
62
+ 'binding_accessor' => accessor.expression,
63
+ 'matcher' => matcher_ref,
64
+ 'found' => v,
65
+ }
66
+ record_event(infos)
67
+ return advise_action(:raise, :infos => infos)
68
+ end
69
+ end
70
+ end
71
+ nil
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,57 @@
1
+ # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
+ # Please refer to our terms for more information: https://www.sqreen.io/terms.html
3
+
4
+ require 'sqreen/rule_callback'
5
+ require 'sqreen/exception'
6
+
7
+ module Sqreen
8
+ module Rules
9
+ # Display sqreen presence
10
+ class CustomErrorCB < RuleCB
11
+ attr_reader :status_code, :redirect_url
12
+ def initialize(klass, method, rule_hash)
13
+ @redirect_url = nil
14
+ @status_code = nil
15
+ super(klass, method, rule_hash)
16
+ if @data.nil? || @data['values'].empty?
17
+ raise Sqreen::Exception, 'No data'
18
+ end
19
+ configure_custom_error(@data['values'][0])
20
+ end
21
+
22
+ def configure_custom_error(custom_error)
23
+ case custom_error['type']
24
+ when 'custom_error_page' then
25
+ @status_code = custom_error['status_code'].to_i
26
+ when 'redirection' then
27
+ @redirect_url = custom_error['redirection_url']
28
+ @status_code = custom_error.fetch('status_code', 303).to_i
29
+ else
30
+ raise Sqreen::Exception, "No custom error #{custom_error['type']}"
31
+ end
32
+ end
33
+
34
+ def failing(except, _inst, *_args, &_block)
35
+ return advise_action(nil) unless except.is_a?(Sqreen::AttackBlocked)
36
+ if @redirect_url
37
+ advise_action(:override, :new_return_value => respond_redirect)
38
+ else
39
+ advise_action(:override, :new_return_value => respond_page)
40
+ end
41
+ end
42
+
43
+ def respond_redirect
44
+ [@status_code, { 'Location' => @redirect_url }, ['']]
45
+ end
46
+
47
+ def respond_page
48
+ page = open(File.join(File.dirname(__FILE__), '../attack_detected.html'))
49
+ headers = {
50
+ 'Content-Type' => 'text/html',
51
+ 'Content-Length' => page.size.to_s,
52
+ }
53
+ [@status_code, headers, page]
54
+ end
55
+ end
56
+ end
57
+ end
@@ -93,7 +93,7 @@ module Sqreen
93
93
  accessor.resolve(binding, framework, inst, args, @data, rv)
94
94
  end
95
95
  Sqreen.log.debug { [name, arguments].inspect }
96
- ret = @compiled.call("callbacks.#{name}", *arguments)
96
+ ret = @compiled.call(name, *arguments)
97
97
  unless record_and_continue?(ret)
98
98
  return nil if ret.nil?
99
99
  return advise_action(ret[:status], ret)
@@ -118,13 +118,12 @@ module Sqreen
118
118
 
119
119
  def build_runnable(callbacks)
120
120
  @argument_requirements = {}
121
- @source = 'var callbacks = {'
121
+ @source = ''
122
122
  @js_pre = !callbacks['pre'].nil?
123
123
  @js_post = !callbacks['post'].nil?
124
124
  @js_failing = !callbacks['failing'].nil?
125
125
  callbacks.each do |name, args_or_func|
126
- @source << name
127
- @source << ': '
126
+ @source << "var #{name} = "
128
127
  if args_or_func.is_a?(Array)
129
128
  @source << args_or_func.pop
130
129
  @argument_requirements[name] = build_accessor(args_or_func)
@@ -132,10 +131,8 @@ module Sqreen
132
131
  @source << args_or_func
133
132
  @argument_requirements[name] = []
134
133
  end
135
- @source << ",\n"
134
+ @source << ";\n"
136
135
  end
137
- @source << "\n"
138
- @source << '}'
139
136
  end
140
137
  end
141
138
  end
@@ -5,33 +5,29 @@ require 'sqreen/rule_callback'
5
5
 
6
6
  module Sqreen
7
7
  module Rules
8
- # A configurable matcher rule
9
- class MatcherRuleCB < RuleCB
10
- def initialize(*args)
11
- super(*args)
12
- prepare
13
- end
14
-
8
+ # matcher behavior
9
+ module Matcher
15
10
  def self.prepare_re_pattern(value, options, case_sensitive)
16
11
  res = 0
17
12
  res |= Regexp::MULTILINE if options.include?('multiline')
18
13
  res |= Regexp::IGNORECASE unless case_sensitive
19
- Regexp.compile(value, res)
14
+ r = Regexp.compile(value, res)
15
+ r.match("")
16
+ r
20
17
  end
21
18
 
22
19
  ANYWHERE_OPT = 'anywhere'.freeze
23
- def prepare
20
+ def prepare(patterns)
24
21
  @string = {}
25
- @regex_patterns = []
22
+ @regexp_patterns = []
26
23
 
27
- patterns = @data['values']
28
24
  if patterns.nil?
29
25
  msg = "no key 'values' in data (had #{@data.keys})"
30
26
  raise Sqreen::Exception, msg
31
27
  end
32
28
 
33
29
  @funs = {
34
- ANYWHERE_OPT => lambda { |value, str| str.include?(value) },
30
+ ANYWHERE_OPT => lambda { |value, str| str.include?(value) },
35
31
  'starts_with'.freeze => lambda { |value, str| str.start_with?(value) },
36
32
  'ends_with'.freeze => lambda { |value, str| str.end_with?(value) },
37
33
  'equals'.freeze => lambda { |value, str| str == value },
@@ -61,17 +57,18 @@ module Sqreen
61
57
  @string[opt] = { :ci => [], :cs => [] } unless @string.key?(opt)
62
58
  @string[opt][case_type] << val
63
59
 
64
- when 'regex'
65
- pattern = MatcherRuleCB.prepare_re_pattern(val, opt, case_sensitive)
60
+ when 'regexp'
61
+ pattern = Matcher.prepare_re_pattern(val, opt, case_sensitive)
66
62
  next unless pattern
67
- @regex_patterns << pattern
63
+ @regexp_patterns << pattern
64
+ else
65
+ raise Sqreen::Exception, "No such matcher type #{type}"
68
66
  end
69
67
  end
70
68
 
71
- if [@regex_patterns, @string].map { |s| s == 0 }.all?
72
- msg = "no key 'regex' nor 'match' in data (had #{@data.keys})"
73
- raise Sqreen::Exception, msg
74
- end
69
+ return unless [@regexp_patterns, @string].map(&:empty?).all?
70
+ msg = "no key 'regexp' nor 'match' in data (had #{@data.keys})"
71
+ raise Sqreen::Exception, msg
75
72
  end
76
73
 
77
74
  def match(str)
@@ -95,11 +92,20 @@ module Sqreen
95
92
  end
96
93
  end
97
94
 
98
- @regex_patterns.each do |p|
95
+ @regexp_patterns.each do |p|
99
96
  return p if p.match(str)
100
97
  end
101
98
  nil
102
99
  end
103
100
  end
101
+
102
+ # A configurable matcher rule
103
+ class MatcherRuleCB < RuleCB
104
+ def initialize(*args)
105
+ super(*args)
106
+ prepare(@data['values'])
107
+ end
108
+ include Matcher
109
+ end
104
110
  end
105
111
  end
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
2
  # Please refer to our terms for more information: https://www.sqreen.io/terms.html
3
3
  module Sqreen
4
- VERSION = '1.5.0'.freeze
4
+ VERSION = '1.6.0'.freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sqreen
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: java
6
6
  authors:
7
7
  - Sqreen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-18 00:00:00.000000000 Z
11
+ date: 2017-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: execjs
@@ -48,6 +48,7 @@ files:
48
48
  - README.md
49
49
  - Rakefile
50
50
  - lib/sqreen.rb
51
+ - lib/sqreen/attack_detected.html
51
52
  - lib/sqreen/binding_accessor.rb
52
53
  - lib/sqreen/ca.crt
53
54
  - lib/sqreen/call_countable.rb
@@ -89,10 +90,12 @@ files:
89
90
  - lib/sqreen/rule_callback.rb
90
91
  - lib/sqreen/rules.rb
91
92
  - lib/sqreen/rules_callbacks.rb
93
+ - lib/sqreen/rules_callbacks/binding_accessor_matcher.rb
92
94
  - lib/sqreen/rules_callbacks/binding_accessor_metrics.rb
93
95
  - lib/sqreen/rules_callbacks/count_http_codes.rb
94
96
  - lib/sqreen/rules_callbacks/crawler_user_agent_matches.rb
95
97
  - lib/sqreen/rules_callbacks/crawler_user_agent_matches_metrics.rb
98
+ - lib/sqreen/rules_callbacks/custom_error.rb
96
99
  - lib/sqreen/rules_callbacks/execjs.rb
97
100
  - lib/sqreen/rules_callbacks/headers_insert.rb
98
101
  - lib/sqreen/rules_callbacks/inspect_rule.rb
@@ -131,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
134
  version: '0'
132
135
  requirements: []
133
136
  rubyforge_project:
134
- rubygems_version: 2.6.10
137
+ rubygems_version: 2.6.11
135
138
  signing_key:
136
139
  specification_version: 4
137
140
  summary: Sqreen Ruby agent