rufus-treechecker 1.0 → 1.0.1

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.
@@ -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