Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove SAFE=1 and Safe::safe #666

Merged
merged 6 commits into from Jan 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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