Skip to content

Commit

Permalink
Merge pull request #666 from tdiary/remove-safe-level1
Browse files Browse the repository at this point in the history
Remove `SAFE=1` and `Safe::safe`
  • Loading branch information
hsbt committed Jan 29, 2018
2 parents c62bdd2 + 298f812 commit eee51c5
Show file tree
Hide file tree
Showing 48 changed files with 127 additions and 202 deletions.
4 changes: 2 additions & 2 deletions benchmark/benchmark_io_default.rb
@@ -1,5 +1,5 @@
module TDiary
PATH = File::dirname( __FILE__ ).untaint
PATH = File::dirname( __FILE__ )
class << self
def root
File.expand_path(File.join(library_root, '..'))
Expand All @@ -12,7 +12,7 @@ def library_root

# directory where the server was started
def server_root
Dir.pwd.untaint
Dir.pwd
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion config.ru
@@ -1,4 +1,4 @@
$:.unshift( File.join(File::expand_path(File::dirname( __FILE__ )), 'lib' ).untaint )
$:.unshift( File.join(File::expand_path(File::dirname( __FILE__ )), 'lib' ) )
require 'tdiary/application'

use ::Rack::Reloader unless ENV['RACK_ENV'] == 'production'
Expand Down
6 changes: 3 additions & 3 deletions index.fcgi
Expand Up @@ -9,12 +9,12 @@
#
require 'fcgi'
# workaround untaint LOAD_PATH for rubygems library path is always tainted.
$:.each{|path| path.untaint if path.include?('fcgi') && path.tainted? }
$:.each{|path| path if path.include?('fcgi') }

if FileTest::symlink?( __FILE__ ) then
org_path = File::dirname( File::readlink( __FILE__ ) ).untaint
org_path = File::dirname( File::readlink( __FILE__ ) )
else
org_path = File::dirname( __FILE__ ).untaint
org_path = File::dirname( __FILE__ )
end
load "#{org_path}/misc/lib/fcgi_patch.rb"

Expand Down
2 changes: 1 addition & 1 deletion index.rb
Expand Up @@ -14,7 +14,7 @@
else
org_path = File::dirname( __FILE__ )
end
$:.unshift( (org_path + '/lib').untaint ) unless $:.include?( org_path + '/lib' )
$:.unshift( (org_path + '/lib') ) unless $:.include?( org_path + '/lib' )
require 'tdiary'

encoding_error = {}
Expand Down
8 changes: 4 additions & 4 deletions lib/tdiary.rb
Expand Up @@ -11,9 +11,9 @@
require 'tdiary/version'
TDIARY_VERSION = TDiary::VERSION

$:.unshift File.join(File::dirname(__FILE__), '../misc/lib').untaint
$:.unshift File.join(File::dirname(__FILE__), '../misc/lib')
['../misc/lib/*/lib', '../vendor/*/lib'].each do |path|
Dir[File.join(File.dirname(__FILE__), path)].each {|dir| $:.unshift dir.untaint }
Dir[File.join(File.dirname(__FILE__), path)].each {|dir| $:.unshift dir }
end

require 'cgi'
Expand All @@ -30,7 +30,7 @@
# module TDiary
#
module TDiary
PATH = File::dirname( __FILE__ ).untaint
PATH = File::dirname( __FILE__ )

# tDiary configuration class, initialize tdiary.conf and stored configuration.
autoload :Configuration, 'tdiary/configuration'
Expand Down Expand Up @@ -126,7 +126,7 @@ def library_root

# directory where the server was started
def server_root
Dir.pwd.untaint
Dir.pwd
end

def configuration
Expand Down
2 changes: 1 addition & 1 deletion lib/tdiary/admin.rb
Expand Up @@ -120,7 +120,7 @@ def initialize( cgi, rhtml, conf )
def do_eval_rhtml( prefix )
super
@plugin.instance_eval { update_proc }
anchor_str = @plugin.instance_eval( %Q[anchor "#{@diary.date.strftime('%Y%m%d')}"].untaint )
anchor_str = @plugin.instance_eval( %Q[anchor "#{@diary.date.strftime('%Y%m%d')}"] )
@io.clear_cache( /(latest|#{@date.strftime( '%Y%m' )})/ )
raise ForceRedirect::new( "#{@conf.index}#{anchor_str}" )
end
Expand Down
2 changes: 1 addition & 1 deletion lib/tdiary/author_only_base.rb
Expand Up @@ -86,7 +86,7 @@ def csrf_check( cgi, conf )

def load_plugins
super
@plugin.instance_eval("def csrf_protection\n#{(@csrf_protection.untaint || '').dump}\nend;")
@plugin.instance_eval("def csrf_protection\n#{(@csrf_protection || '').dump}\nend;")
end
end

Expand Down
6 changes: 3 additions & 3 deletions lib/tdiary/base.rb
Expand Up @@ -31,7 +31,7 @@ def eval_rhtml( prefix = '' )
if e.class == ForceRedirect
raise
else
body = File.read("#{File.dirname(__FILE__)}/../../views/plugin_error.rhtml").untaint
body = File.read("#{File.dirname(__FILE__)}/../../views/plugin_error.rhtml")
r = ERB.new(body).result(binding)
end
end
Expand Down Expand Up @@ -62,7 +62,7 @@ def do_eval_rhtml( prefix )
@io.store_cache( r, prefix ) unless @diaries.empty?
end

r = @plugin.eval_src( r.untaint ) if @plugin
r = @plugin.eval_src( r ) if @plugin

@cookies += @plugin.cookies

Expand Down Expand Up @@ -123,7 +123,7 @@ def erb_src(prefix)
end.join

begin
r = ERB.new(rhtml.untaint).result(binding)
r = ERB.new(rhtml).result(binding)
rescue ::Encoding::CompatibilityError
# migration error on ruby 1.9 only 1st time, reload.
raise ForceRedirect.new(base_url)
Expand Down
2 changes: 1 addition & 1 deletion lib/tdiary/cache/file.rb
Expand Up @@ -28,7 +28,7 @@ def store_data(data, path)
end

def delete_data(path)
File.delete(path.untaint)
File.delete(path)
end

def restore_parser_cache(date, key = nil)
Expand Down
19 changes: 0 additions & 19 deletions lib/tdiary/compatible.rb
Expand Up @@ -3,25 +3,6 @@ class CGI
ENV = ::ENV.to_hash
end

# for Ruby 1.9.3
if ::Object.method_defined?(:untrust)
class Object
def taint
super
untrust
end
end
end

# for Ruby 1.9.X

# preload transcodes outside $SAFE=4 environment, that is a workaround
# for the possible SecurityError. see the following uri for the detail.
# http://redmine.ruby-lang.org/issues/5279
%w(utf-16be euc-jp iso-2022-jp Shift_JIS).each do |enc|
"\uFEFF".encode(enc) rescue nil
end

# Auto convert ASCII_8BIT pstore data (created by Ruby-1.8) to UTF-8.
require 'pstore'
class PStoreRuby18Exception < Exception; end
Expand Down
43 changes: 18 additions & 25 deletions lib/tdiary/configuration.rb
Expand Up @@ -15,11 +15,8 @@ def initialize( cgi = nil, request = nil )
end

def save
result = ERB.new(File.read("#{File.dirname(__FILE__)}/../../views/tdiary.rconf").untaint).result(binding)
result.untaint
Safe::safe do
eval( result, binding, "(TDiary::Configuration#save)", 1 )
end
result = ERB.new(File.read("#{File.dirname(__FILE__)}/../../views/tdiary.rconf")).result(binding)
eval( result, binding, "(TDiary::Configuration#save)", 1 )
@io_class.save_cgi_conf(self, result)
end

Expand Down Expand Up @@ -113,23 +110,20 @@ def load_cgi_conf
end

cgi_conf = @io_class.load_cgi_conf(self)
cgi_conf.untaint

b = binding.taint
b = binding
eval( def_vars1, b )
Safe::safe do
begin
eval( cgi_conf, b, "(TDiary::Configuration#load_cgi_conf)", 1 )
rescue SyntaxError
enc = case @lang
when 'en'
'UTF-8'
else
'EUC-JP'
end
cgi_conf.force_encoding( enc )
retry
end
begin
eval( cgi_conf, b, "(TDiary::Configuration#load_cgi_conf)", 1 )
rescue SyntaxError
enc = case @lang
when 'en'
'UTF-8'
else
'EUC-JP'
end
cgi_conf.force_encoding( enc )
retry
end if cgi_conf
eval( def_vars2, b )
end
Expand All @@ -138,12 +132,12 @@ def load_cgi_conf
def configure_attrs
@options = {}

eval( File::open( 'tdiary.conf' ) {|f| f.read }.untaint, nil, "(tdiary.conf)", 1 )
eval( File::open( 'tdiary.conf' ) {|f| f.read }, nil, "(tdiary.conf)", 1 )

# language setup
@lang = 'ja' unless @lang
begin
instance_eval( File::open( "#{TDiary::PATH}/tdiary/lang/#{@lang}.rb" ){|f| f.read }.untaint, "(tdiary/lang/#{@lang}.rb)", 1 )
instance_eval( File::open( "#{TDiary::PATH}/tdiary/lang/#{@lang}.rb" ){|f| f.read }, "(tdiary/lang/#{@lang}.rb)", 1 )
rescue Errno::ENOENT
@lang = 'ja'
retry
Expand Down Expand Up @@ -195,9 +189,8 @@ def configure_attrs
if @options2 then
@options.update( @options2 )
else
@options2 = {}.taint
@options2 = {}
end
@options.taint

# for 1.4 compatibility
@section_anchor = @paragraph_anchor unless @section_anchor
Expand All @@ -220,7 +213,7 @@ def load_logger
else
require 'logger'
log_path = (@log_path || "#{@data_path}/log")
FileUtils.mkdir_p(log_path.untaint)
FileUtils.mkdir_p(log_path)
TDiary.logger = Logger.new(File.join(log_path, "debug.log"), 'daily')
TDiary.logger.level = Logger.const_get(@log_level || 'DEBUG')
end
Expand Down
22 changes: 0 additions & 22 deletions lib/tdiary/core_ext.rb
Expand Up @@ -106,28 +106,6 @@ def base_url

class RackCGI < CGI; end

=begin
== Safe module
=end
module Safe
def safe
result = nil
if $SAFE < 1 then
Proc.new {
begin
$SAFE = 1
ensure
result = yield
end
}.call
else
result = yield
end
result
end
module_function :safe
end

# Local Variables:
# mode: ruby
# indent-tabs-mode: t
Expand Down
2 changes: 1 addition & 1 deletion lib/tdiary/environment.rb
Expand Up @@ -8,7 +8,7 @@ module TDiary::Cache; end
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])

# FIXME: workaround fix for tainted path from Gemfile.local
$LOAD_PATH.each{|lp| $LOAD_PATH << $LOAD_PATH.shift.dup.untaint}
$LOAD_PATH.each{|lp| $LOAD_PATH << $LOAD_PATH.shift.dup}

if defined?(Bundler)
env = [:default, :rack]
Expand Down
6 changes: 3 additions & 3 deletions lib/tdiary/io/base.rb
Expand Up @@ -31,7 +31,7 @@ def cache_dir
end

def cache_path
@_cache_path ||= cache_dir.untaint
@_cache_path ||= cache_dir
FileUtils.mkdir_p(@_cache_path)
@_cache_path
end
Expand All @@ -41,8 +41,8 @@ def load_styles
paths = @tdiary.conf.options['style.path'] ||
[TDiary::PATH, TDiary.server_root].map {|base| "#{base}/tdiary/style" }
[paths].flatten.uniq.each do |path|
path = path.sub(/\/+$/, '').untaint
Dir.glob("#{path}/*.rb") {|style_file| require style_file.untaint }
path = path.sub(/\/+$/, '')
Dir.glob("#{path}/*.rb") {|style_file| require style_file }
end
TDiary::Style.constants(false).each do |name|
prefix = name.slice(/\A(.*)Diary\z/, 1)
Expand Down
6 changes: 3 additions & 3 deletions lib/tdiary/io/default.rb
Expand Up @@ -92,7 +92,7 @@ def restore_referer( file, diaries )

# convert to referer plugin format
diaries.each do |date,diary|
fname = file.sub( /\.tdr$/, "#{date[6,2]}.tdr".untaint )
fname = file.sub( /\.tdr$/, "#{date[6,2]}.tdr" )
File::open( fname, File::WRONLY | File::CREAT ) do |fhr|
fhr.flock( File::LOCK_EX )
fhr.rewind
Expand Down Expand Up @@ -149,12 +149,12 @@ def load_cgi_conf(conf)
conf.data_path += '/' if /\/$/ !~ conf.data_path
raise TDiaryError, 'Do not set @data_path as same as tDiary system directory.' if conf.data_path == "#{TDiary::PATH}/"

File::open( "#{conf.data_path.untaint}tdiary.conf" ){|f| f.read }
File::open( "#{conf.data_path}tdiary.conf" ){|f| f.read }
rescue IOError, Errno::ENOENT
end

def save_cgi_conf(conf, result)
File::open( "#{conf.data_path.untaint}tdiary.conf", 'w' ) {|o| o.print result }
File::open( "#{conf.data_path}tdiary.conf", 'w' ) {|o| o.print result }
rescue IOError, Errno::ENOENT
end
end
Expand Down
33 changes: 9 additions & 24 deletions lib/tdiary/plugin.rb
Expand Up @@ -80,31 +80,19 @@ def load_plugin( file )
@resource_loaded = false
begin
res_file = File::dirname( file ) + "/#{@conf.lang}/" + File::basename( file )
open( res_file.untaint ) do |src|
instance_eval( src.read.untaint, "(plugin/#{@conf.lang}/#{File::basename( res_file )})", 1 )
open( res_file ) do |src|
instance_eval( src.read, "(plugin/#{@conf.lang}/#{File::basename( res_file )})", 1 )
end
@resource_loaded = true
rescue IOError, Errno::ENOENT
end
File::open( file.untaint ) do |src|
instance_eval( src.read.untaint, "(plugin/#{File::basename( file )})", 1 )
File::open( file ) do |src|
instance_eval( src.read, "(plugin/#{File::basename( file )})", 1 )
end
end

def eval_src( src )
self.taint
@conf.taint
@title_procs.taint
@body_enter_procs.taint
@body_leave_procs.taint
@section_index.taint
@section_enter_procs.taint
@comment_leave_procs.taint
@subtitle_procs.taint
@section_leave_procs.taint
ret = Safe::safe do
eval( src, binding, "(TDiary::Plugin#eval_src)", 1 )
end
ret = eval( src, binding, "(TDiary::Plugin#eval_src)", 1 )
@conf.io_class.plugin_close(@storage)
return ret
end
Expand Down Expand Up @@ -349,13 +337,10 @@ def apply_plugin( str, remove_tag = false )
return '' unless str
r = str.dup
if @conf.options['apply_plugin'] and r.index( '<%' ) then
r = r.untaint
Safe::safe do
begin
r = ERB::new( r ).result( binding )
rescue Exception
r = %Q|<p class="message">Invalid Text</p>#{r}|
end
begin
r = ERB::new( r ).result( binding )
rescue Exception
r = %Q|<p class="message">Invalid Text</p>#{r}|
end
end
r = remove_tag( r ) if remove_tag
Expand Down
5 changes: 2 additions & 3 deletions lib/tdiary/plugin/00default.rb
Expand Up @@ -715,8 +715,7 @@ def comment_mail_send
rescue
rmail = File::open( "#{TDiary::PATH}/../views/mail.rtxt" ){|f| f.read }
end
text = @conf.to_mail( ERB::new( rmail.untaint ).result( binding ) )
receivers.each(&:untaint)
text = @conf.to_mail( ERB::new( rmail ).result( binding ) )
comment_mail( text, receivers )
end

Expand Down Expand Up @@ -821,7 +820,7 @@ def conf_theme_list
def theme_list_local(list)
Dir::glob( theme_paths_local ).sort.map {|dir|
theme = dir.sub( %r[.*/theme/], '')
next unless FileTest::file?( "#{dir}/#{theme}.css".untaint )
next unless FileTest::file?( "#{dir}/#{theme}.css" )
name = theme.split( /_/ ).collect{|s| s.capitalize}.join( ' ' )
list << ["local/#{theme}",name]
}
Expand Down

0 comments on commit eee51c5

Please sign in to comment.