Module: WebSandboxConsole::SafeRuby

Included in:
WebSandboxConsole
Defined in:
lib/web_sandbox_console/safe_ruby.rb

Instance Method Summary collapse

Instance Method Details

#blacklist_method_remindObject

当拦截黑名单方法时提醒



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/web_sandbox_console/safe_ruby.rb', line 141

def blacklist_method_remind
  Kernel.class_exec do
    # 发现此处method_missing Array 没有flatten方法
    def flatten_arr(arr)
      new_arr = []
      arr.each do |e|
        if e.is_a?(Array)
          new_arr.concat(flatten_arr(e))
        else
          new_arr << e
        end
      end
      new_arr
    end

    def method_missing(name,*params)
      class_methods    = WebSandboxConsole.class_method_blacklists.values
      instance_methods = WebSandboxConsole.instance_method_blacklists.values
      
      if flatten_arr([class_methods, instance_methods]).include?(name.to_sym)
        msg = "PS:当前代码执行过程中可能调用了黑名单方法,若代码正常返回,请忽略此条提醒"
        WebSandboxConsole.log_p(msg, true)
      end
      super
    end
  end
end

#class_method_blacklistsObject

类方法黑名单列表



38
39
40
41
42
43
44
# File 'lib/web_sandbox_console/safe_ruby.rb', line 38

def class_method_blacklists
  blacklist = if class_method_blacklist
    merge_method_hash(CLASS_METHOD_BUILT_IN_BLACKLIST, class_method_blacklist)
  else
    CLASS_METHOD_BUILT_IN_BLACKLIST
  end
end

#compatible_file_cacheObject

兼容文件缓存



118
119
120
121
122
123
124
125
126
127
128
# File 'lib/web_sandbox_console/safe_ruby.rb', line 118

def compatible_file_cache
  ActiveSupport::Cache::FileStore.class_exec do
    def write_entry(key, entry, options)
      true
    end

    def delete_entry(key, options)
      true
    end
  end
end

#compatible_i18n_translateObject

兼容翻译



131
132
133
134
135
136
137
138
# File 'lib/web_sandbox_console/safe_ruby.rb', line 131

def compatible_i18n_translate
  I18n.instance_exec do
    def translate(*args)
      "ActiveRecord::RecordInvalid: 校验失败"
    end
    alias :t :translate
  end
end

#init_safe_envObject

初始化安全环境



4
5
6
7
8
9
10
11
12
13
# File 'lib/web_sandbox_console/safe_ruby.rb', line 4

def init_safe_env
  sanitize_constants
  sanitize_instance_methods
  sanitize_class_methods
  sanitize_logger_new
  sanitize_csv
  compatible_file_cache
  compatible_i18n_translate
  blacklist_method_remind
end

#instance_method_blacklistsObject

实例方法黑名单列表



47
48
49
50
51
52
53
# File 'lib/web_sandbox_console/safe_ruby.rb', line 47

def instance_method_blacklists
  blacklist = if instance_method_blacklist
    merge_method_hash(INSTANT_METOD_BUILT_IN_BLACKLIST,instance_method_blacklist)
  else
    INSTANT_METOD_BUILT_IN_BLACKLIST
  end
end

#merge_method_hash(hash1, hash2) ⇒ Object

将两个hash 内部数组也同时合并,并去重



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/web_sandbox_console/safe_ruby.rb', line 64

def merge_method_hash(hash1, hash2)
  # 格式统一
  hash2.transform_keys!(&:to_sym).transform_keys!(&:to_sym).transform_values!{|i| i.map(&:to_sym)}
  # 共有的key 
  common_keys = hash2.keys & hash1.keys
  # hash2 特有keys
  hash2_special_keys = hash2.keys - hash1.keys
  # 特有keys 直接合到 hash1
  hash1.merge!(hash2.slice(*hash2_special_keys))
  # 共用keys 数组去重
  common_keys.each do |key|
    hash1[key] = (hash1[key] | hash2[key]).uniq
  end
  hash1
end

#sanitize_class_methodsObject

净化 类方法



16
17
18
19
20
21
22
23
24
# File 'lib/web_sandbox_console/safe_ruby.rb', line 16

def sanitize_class_methods
  class_method_blacklists.each do |klass, methods|
    klass = Object.const_get(klass)
    methods.each do |method|
      next if klass.singleton_methods.exclude?(method)
      klass.singleton_class.send(:undef_method, method)
    end
  end
end

#sanitize_constantsObject

净化 常量



56
57
58
59
60
61
# File 'lib/web_sandbox_console/safe_ruby.rb', line 56

def sanitize_constants
  return unless constant_blacklist
  constant_blacklist.each do |const|
    Object.send(:remove_const, const) if defined?(const)
  end
end

#sanitize_csvObject

净化 csv



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/web_sandbox_console/safe_ruby.rb', line 93

def sanitize_csv
  require 'csv' unless defined? CSV

  CSV.instance_eval do
    # 重写方法 以写日志方式 写数据
    def open(filename, mode="r", **options)
      # 无论输入什么路径 都只会在log下创建文件
      basename = File.basename(filename, ".*")
      file_path = "#{Rails.root}/log/#{basename}.csv"
      logger = Logger.new(file_path)
      logger.formatter = proc {|severity, datetime, progname, msg| msg}

      logger.instance_exec do
        # 支持类型 csv 数据写入方式
        def << (data_arr)
          self.info data_arr.join(",") + "\n"
        end
      end

      yield(logger)
    end
  end
end

#sanitize_instance_methodsObject

净化 实例方法



27
28
29
30
31
32
33
34
35
# File 'lib/web_sandbox_console/safe_ruby.rb', line 27

def sanitize_instance_methods
  instance_method_blacklists.each do |klass, methods|
    klass = Object.const_get(klass)
    methods.each do |method|
      next if (klass != Kernel) && klass.instance_methods.exclude?(method)
      klass.send(:undef_method, method)
    end
  end
end

#sanitize_logger_newObject

发现代码 中有 Logger.new(Rails.root.join(‘log’, ‘hubar’)) 写法, 会 触发 File.open方法封装后避免调用 File.open(禁用)



82
83
84
85
86
87
88
89
90
# File 'lib/web_sandbox_console/safe_ruby.rb', line 82

def sanitize_logger_new
  Logger.instance_eval do
    def new(logdev, shift_age = 0, shift_size = 1048576)
      instance = allocate
      instance.send(:initialize, logdev.to_s, shift_age, shift_size)
      instance
    end
  end
end