tmpio.rb causes an "insecure operation" error when being run in taint mode. This is due not to a problem in tmpio.rb but in Ruby's File class. Here are the details on the problem and a simple workaround for it.
I filed this bug report in February 2018: https://bugs.ruby-lang.org/issues/14485. The problem is that when a File object is created using an untainted string for the path, File nevertheless changes that path to tainted. It is agreed thatit's a bug: File should not taint an untainted path. However, efforts to fix the bug seem to have stalled out. Now, in tmpio.rb, a random, untainted path is generated and stored in the Unicorn::TmpIO object. Then, a few lines later, the class attempts to unlink that file using the path stored in the object. Because of the bug in File, the path is now tainted, resulting in an insecure operation error. I propose a simple workaround. Store the path in its own variable. Pass the variable to the Unicorn::TmpIO object, but use the original variable to unlink the file. This technique worked in experimentation for me. Here's a modified version of tmpio.rb. # -*- encoding: binary -*- # :stopdoc: require 'tmpdir' # some versions of Ruby had a broken Tempfile which didn't work # well with unlinked files. This one is much shorter, easier # to understand, and slightly faster. class Unicorn::TmpIO < File # creates and returns a new File object. The File is unlinked # immediately, switched to binary mode, and userspace output # buffering is disabled def self.new path = nil fp = begin path = "#{Dir::tmpdir}/#{rand}" super(path, RDWR|CREAT|EXCL, 0600) rescue Errno::EEXIST retry end unlink(path) fp.binmode fp.sync = true fp end # pretend we're Tempfile for Rack::TempfileReaper alias close! close end
