Net::SMTP/mod_ruby SecurityError

Hi,

I have an application that uses mod_ruby and I need to be able to have
it email a message to an address specified by a user using a web form. I
seem to have everything set-up fine, I run the entered email address
through a validation process before continuing so I'm confident it's
safe to untaint it, but sendmessage() still raises a SecurityError.

Is this something simple I'm doing wrong or is the problem a little more
exotic?

Thanks for any help.

Cheers,

Richard.

Code:

def emailReportTo(email, report)
  require 'net/smtp'
    
  unless validated(email)
    return
  end
    
  msg = <<EOS

···

From: my.email@home
To: #{email}
Subject: Report

EOS
  msg += report
    
  Net::SMTP.start('localhost', 25) do |smtp|
    smtp.send_message(msg, 'my.email@home', email.untaint)
  end
end

Apologies for replying to myself :slight_smile:

Unless I'm very much mistaken I've tracked the problem to the
send_message() method in smtp.rb. This method calls Array#flatten on its
to_addrs parameter which, it seems, causes any elements in that array
that had been explicitly untainted to become tainted again. Later, in
send0(), a SecurityError is then thrown (if $SAFE > 0) regardless of any
programmer's steps to untaint email addresses.

So, my question becomes, is there a way for me to untaint a validated
email address and ensure that it stays untainted even when the array
it's in is flattened by Net::SMTP.send_message?

In the meantime I've hacked my version of smtp.rb to recursively check
all the elements of the to_addrs array to ensure that they're not
tainted and only proceed if that's the case. Then I can flatten the
array and merrily untaint all its elements again in case flatten()
caused them to become tainted.

Cheers,

Richard.

···

On Wed, 2005-04-06 at 20:21 +0900, Richard Turner wrote:

Hi,

I have an application that uses mod_ruby and I need to be able to have
it email a message to an address specified by a user using a web form. I
seem to have everything set-up fine, I run the entered email address
through a validation process before continuing so I'm confident it's
safe to untaint it, but sendmessage() still raises a SecurityError.

Hi,

  In mail "Re: Net::SMTP/mod_ruby SecurityError"

···

Richard Turner <richard.turner@dlf.org.uk> wrote:

> I have an application that uses mod_ruby and I need to be able to have
> it email a message to an address specified by a user using a web form. I
> seem to have everything set-up fine, I run the entered email address
> through a validation process before continuing so I'm confident it's
> safe to untaint it, but sendmessage() still raises a SecurityError.

Unless I'm very much mistaken I've tracked the problem to the
send_message() method in smtp.rb. This method calls Array#flatten on its
to_addrs parameter which, it seems, causes any elements in that array
that had been explicitly untainted to become tainted again. Later, in
send0(), a SecurityError is then thrown (if $SAFE > 0) regardless of any
programmer's steps to untaint email addresses.

So, my question becomes, is there a way for me to untaint a validated
email address and ensure that it stays untainted even when the array
it's in is flattened by Net::SMTP.send_message?

Untaint all addresses explicitly:

  smtp.send_messages from.untaint, to.map {|a| a.untaint }, str

Best Regards,
Minero Aoki

Hi,

···

On Fri, 2005-04-08 at 08:48 +0900, Minero Aoki wrote:

> Unless I'm very much mistaken I've tracked the problem to the
> send_message() method in smtp.rb. This method calls Array#flatten on its
> to_addrs parameter which, it seems, causes any elements in that array
> that had been explicitly untainted to become tainted again. Later, in
> send0(), a SecurityError is then thrown (if $SAFE > 0) regardless of any
> programmer's steps to untaint email addresses.
>
> So, my question becomes, is there a way for me to untaint a validated
> email address and ensure that it stays untainted even when the array
> it's in is flattened by Net::SMTP.send_message?

Untaint all addresses explicitly:

  smtp.send_messages from.untaint, to.map {|a| a.untaint }, str

Ah, I see! Thanks for that. I confess I was quite surprised when I
thought I'd found an error in smtp.rb - it seemed so unlikely - so I'm
glad it was me :slight_smile:

Cheers,

Richard.