summaryrefslogtreecommitdiff
path: root/lib/safe.rb
blob: 7c95555495de7c8560a099d05f78f418a366b576 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# this is a safe-mode for ruby, which is still incomplete.

unless defined? SecurityError
  class SecurityError<Exception
  end
end

module Restricted

  printf STDERR, "feel free for some warnings:\n" if $VERBOSE
  module Bastion
    include Restricted
    extend Restricted
    BINDING = binding
    def Bastion.to_s; "main" end
  end

  class R_File<File
    NG_FILE_OP = []
    def R_File.open(*args)
      raise SecurityError, "can't use File.open() in safe mode" #'
    end
  end

  IO = nil
  File = R_File
  FileTest = nil
  Dir = nil
  ObjectSpace = nil

  def eval(string)
    begin
      super(string, Bastion::BINDING)
    rescue
      $@ = caller
      raise
    end
  end
  module_function :eval

  DEFAULT_SECURITY_MANAGER = Object.new

  def Restricted.set_securuty_manager(sec_man)
    if @sec_man
      raise SecurityError, "cannot change security manager"
    end
    @sec_man = sec_man
  end

  def Restricted.securuty_manager
    return @sec_man if @sec_man
    return DEFAULT_SECURITY_MANAGER
  end

  for cmd in ["test", "require", "load", "open", "system"]
    eval format("def DEFAULT_SECURITY_MANAGER.%s(*args)
                   raise SecurityError, \"can't use %s() in safe mode\"
                 end", cmd, cmd) #'
    eval format("def %s(*args)
                   Restricted.securuty_manager.%s(*args)
                 end", cmd, cmd) 
  end

  def `(arg) #`
    Restricted.securuty_manager.send(:`, arg) #`)
  end

  def DEFAULT_SECURITY_MANAGER.`(arg) #`
    raise SecurityError, "can't use backquote(``) in safe mode"
  end
end

if $DEBUG
  p eval("File.open('/dev/null')")
  p Restricted.eval("self")
  p Restricted.eval("open('/dev/null')")
  p Restricted.eval("File.open('/dev/null')")
end