rufus-treechecker 1.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -82,9 +82,10 @@ module Rufus
82
82
  # - exclude_fcall
83
83
  # - exclude_vcall
84
84
  # - exclude_fvcall
85
- # - exclude_fvkcall
85
+ # - exclude_fvccall
86
86
  # - exclude_call_on
87
87
  # - exclude_call_to
88
+ # - exclude_rebinding
88
89
  # - exclude_def
89
90
  # - exclude_class_tinkering
90
91
  # - exclude_module_tinkering
@@ -95,6 +96,7 @@ module Rufus
95
96
  #
96
97
  # Those rules take no arguments
97
98
  #
99
+ # - exclude_access_to : prevents calling or rebinding a list of classes
98
100
  # - exclude_eval : bans eval, module_eval and instance_eval
99
101
  # - exclude_global_vars : bans calling or modifying global vars
100
102
  # - exclude_alias : bans calls to alias and alias_method
@@ -123,7 +125,7 @@ module Rufus
123
125
  #
124
126
  class TreeChecker
125
127
 
126
- VERSION = '1.0'
128
+ VERSION = '1.0.1'
127
129
 
128
130
  #
129
131
  # pretty-prints the sexp tree of the given rubycode
@@ -209,9 +211,9 @@ module Rufus
209
211
  # Here is how it's built :
210
212
  #
211
213
  # return TreeChecker.new do
212
- # exclude_fvkcall :abort
213
- # exclude_fvkcall :exit, :exit!
214
- # exclude_fvkcall :system
214
+ # exclude_fvccall :abort
215
+ # exclude_fvccall :exit, :exit!
216
+ # exclude_fvccall :system
215
217
  # exclude_eval
216
218
  # exclude_alias
217
219
  # exclude_global_vars
@@ -223,9 +225,9 @@ module Rufus
223
225
  def self.new_classic_tree_checker
224
226
 
225
227
  return TreeChecker.new do
226
- exclude_fvkcall :abort
227
- exclude_fvkcall :exit, :exit!
228
- exclude_fvkcall :system
228
+ exclude_fvccall :abort
229
+ exclude_fvccall :exit, :exit!
230
+ exclude_fvccall :system
229
231
  exclude_eval
230
232
  exclude_alias
231
233
  exclude_global_vars
@@ -272,7 +274,7 @@ module Rufus
272
274
  :exclude_fcall,
273
275
  :exclude_vcall,
274
276
  :exclude_fvcall,
275
- :exclude_fvkcall,
277
+ :exclude_fvccall,
276
278
  :exclude_call_on,
277
279
  :exclude_call_to
278
280
 
@@ -293,6 +295,38 @@ module Rufus
293
295
  EOS
294
296
  end
295
297
 
298
+ #
299
+ # This rule :
300
+ #
301
+ # exclude_rebinding Kernel
302
+ #
303
+ # will raise a security error for those pieces of code :
304
+ #
305
+ # k = Kernel
306
+ # k = ::Kernel
307
+ #
308
+ def exclude_rebinding (*args)
309
+
310
+ message = args.last.is_a?(String) ? args.pop : nil
311
+
312
+ args.each do |a|
313
+ c0 = parse(a.to_s)
314
+ c1 = parse("::#{a.to_s}")
315
+ @current_checks << [ :do_exclude_rebinding, c0, message ]
316
+ @current_checks << [ :do_exclude_rebinding, c1, message ]
317
+ end
318
+ end
319
+
320
+ #
321
+ # prevents access (calling methods and rebinding) to a class (or a list
322
+ # of classes
323
+ #
324
+ def exclude_access_to (*args)
325
+
326
+ exclude_call_on *args
327
+ exclude_rebinding *args
328
+ end
329
+
296
330
  #
297
331
  # bans method definitions
298
332
  #
@@ -391,8 +425,8 @@ module Rufus
391
425
  #
392
426
  def exclude_raise
393
427
 
394
- @current_checks << [ :do_exclude_fvkcall, :raise, "raise is forbidden" ]
395
- @current_checks << [ :do_exclude_fvkcall, :throw, "throw is forbidden" ]
428
+ @current_checks << [ :do_exclude_fvccall, :raise, "raise is forbidden" ]
429
+ @current_checks << [ :do_exclude_fvccall, :throw, "throw is forbidden" ]
396
430
  end
397
431
 
398
432
  #
@@ -447,12 +481,13 @@ module Rufus
447
481
  end
448
482
 
449
483
  #
450
- # excludes :fcall and :vcall and :call on Kernel
484
+ # excludes :fcall and :vcall and :call (to)
451
485
  #
452
- def do_exclude_fvkcall (sexp, args)
486
+ def do_exclude_fvccall (sexp, args)
453
487
 
454
488
  do_exclude_fvcall(sexp, args)
455
- do_exclude_head(sexp, cons([ :call, [ :const, :Kernel ] ], args))
489
+ #do_exclude_head(sexp, cons([ :call, [ :const, :Kernel ] ], args))
490
+ do_exclude_call_to(sexp, args)
456
491
  end
457
492
 
458
493
  #
@@ -475,28 +510,44 @@ module Rufus
475
510
  do_exclude_head(sexp, [ [:call, args[0]] ] + (args[1, -1] || []))
476
511
  end
477
512
 
513
+ #
514
+ # this method is called by all the methods checking composite sexps.
515
+ #
516
+ def do__exclude (sexp, args, default_error_message, &block)
517
+
518
+ return unless sexp.is_a?(Array)
519
+
520
+ raise SecurityError.new(
521
+ args[1] || default_error_message
522
+ ) if block.call(args)
523
+ end
524
+
478
525
  #
479
526
  # raises a security error if a call to a given method of any instance
480
527
  # is found
481
528
  #
482
529
  def do_exclude_call_to (sexp, args)
483
530
 
484
- return unless sexp.is_a?(Array)
531
+ do__exclude(sexp, args, "calls to '#{args[0]}' are forbidden") do
485
532
 
486
- raise SecurityError.new(
487
- args[1] || "calls to '#{args[0]}' are forbidden"
488
- ) if sexp[0] == :call and sexp[2] == args[0]
533
+ (sexp[0] == :call and sexp[2] == args[0])
534
+ end
489
535
  end
490
536
 
491
- def do_exclude_head (sexp, args)
537
+ def do_exclude_rebinding (sexp, args)
492
538
 
493
- return unless sexp.is_a?(Array)
539
+ do__exclude(sexp, args, "rebinding '#{args[0]}' is forbidden") do
494
540
 
495
- head = args[0]
541
+ (sexp[0] == :lasgn and sexp[2] == args[0])
542
+ end
543
+ end
496
544
 
497
- raise SecurityError.new(
498
- args[1] || "#{head.inspect} is forbidden"
499
- ) if sexp[0, head.length] == head
545
+ def do_exclude_head (sexp, args)
546
+
547
+ do__exclude(sexp, args, "#{args[0].inspect} is forbidden") do
548
+
549
+ (sexp[0, args[0].length] == args[0])
550
+ end
500
551
  end
501
552
 
502
553
  def do_exclude_class_tinkering (sexp, args)
data/test/ft_0_basic.rb CHANGED
@@ -218,10 +218,29 @@ class BasicTest < Test::Unit::TestCase
218
218
  assert_ok(tc, 'lambda { a = 2 }')
219
219
  end
220
220
 
221
- def test_12_freeze
221
+ def test_12_rebinding
222
222
 
223
- # TODO : are there some rules with composite values ?
224
- # can't remember of any :(
223
+ tc = Rufus::TreeChecker.new do
224
+ exclude_call_to :class
225
+ exclude_rebinding Kernel, Rufus::TreeChecker
226
+ end
227
+
228
+ assert_nok(tc, 'k = Kernel')
229
+ assert_nok(tc, 'k = ::Kernel')
230
+ assert_nok(tc, 'c = Rufus::TreeChecker')
231
+ assert_nok(tc, 'c = ::Rufus::TreeChecker')
232
+ assert_nok(tc, 's = "".class')
233
+ end
234
+
235
+ def test_13_access_to
236
+
237
+ tc = Rufus::TreeChecker.new do
238
+ exclude_access_to File
239
+ end
240
+
241
+ assert_nok(tc, 'f = File')
242
+ assert_nok(tc, 'f = ::File')
243
+ assert_nok(tc, 'File.read "hello.txt"')
225
244
  end
226
245
 
227
246
  #def test_X
@@ -21,9 +21,9 @@ class OldTreeCheckerTest < Test::Unit::TestCase
21
21
  def test_0
22
22
 
23
23
  tc = Rufus::TreeChecker.new do
24
- exclude_fvkcall :abort
25
- exclude_fvkcall :exit, :exit!
26
- exclude_fvkcall :system
24
+ exclude_fvccall :abort
25
+ exclude_fvccall :exit, :exit!
26
+ exclude_fvccall :system
27
27
  exclude_eval
28
28
  exclude_alias
29
29
  exclude_global_vars
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rufus-treechecker
3
3
  version: !ruby/object:Gem::Version
4
- version: "1.0"
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mettraux