J
John W. Long
Hi,
I've created a small class and supporting methods for sending email from a
web page. I use it like this:
msg = Web::Email::Message.new(
:from => from,
:to => to,
:subject => subject,
:body => body.untaint # security vulnerability?
)
Web::Email.send(msg)
All of the email strings from, :to, etc...) could potentially come from
the the outside world. I'm doing some munging on the :from, :to, and
:subject strings replacing \n \r \f \e and \b with something
non-threatening. Right now I'm just untainting the :body string, but I have
the distinct feeling that I may be exposing myself to a security
vulnerability because I don't really understand what the Net::SMTP class is
doing in the background.
Could someone who understands how Net::SMTP works check over my code (see
below) and comment on security vulnerabilities? Also I looked for details on
specification for email, but a brief search on google didn't turn up
anything. Can someone point me in the right direction?
Thanks,
John Long
http://wiseheartdesign.com
<code>
# you will probably want to paste this into
# a syntax highlighting editor like Scite
require 'net/smtp'
module Web
module Email
class Message
attr_accessor :from, :to, :subject, :body
def initialize(hash = {})
@from = hash[:from]
@to = hash[:to]
@subject = hash[:subject]
@body = hash[:body]
end
def message
time = current_time
<<-SMTP_MSG
Subject: #{@subject}
Message-Id: <#{"%.8f" % time.to_f}@iblp.org>
Date: #{time.strftime("%a, %d %b %Y %H:%M:%S %z %Z")}
From: #{@from}
To: #{@to}
#{@body}
SMTP_MSG
end
def current_time
Time.now
end
end
def self.send(msg)
msg.subject = safe_subject(msg.subject) # munges and untaints string
msg.from = safe_address(msg.from)
msg.to = safe_address(msg.to)
raise ArgumentError, 'msg.body tainted' if msg.body.tainted?
raise ArgumentError, 'msg tainted' if msg.tainted?
Net::SMTP.start('localhost', 25) {|smtp|
smtp.sendmail(msg.message, msg.from, msg.to)
}
end
def self.safe_subject(subject)
subject.gsub(/[\n\r\f\e\b]/, ' ').untaint
end
def self.safe_address(address)
address.gsub(/[\n\r\f\e\b]/, '').untaint
end
end
end
</code>
I've created a small class and supporting methods for sending email from a
web page. I use it like this:
msg = Web::Email::Message.new(
:from => from,
:to => to,
:subject => subject,
:body => body.untaint # security vulnerability?
)
Web::Email.send(msg)
All of the email strings from, :to, etc...) could potentially come from
the the outside world. I'm doing some munging on the :from, :to, and
:subject strings replacing \n \r \f \e and \b with something
non-threatening. Right now I'm just untainting the :body string, but I have
the distinct feeling that I may be exposing myself to a security
vulnerability because I don't really understand what the Net::SMTP class is
doing in the background.
Could someone who understands how Net::SMTP works check over my code (see
below) and comment on security vulnerabilities? Also I looked for details on
specification for email, but a brief search on google didn't turn up
anything. Can someone point me in the right direction?
Thanks,
John Long
http://wiseheartdesign.com
<code>
# you will probably want to paste this into
# a syntax highlighting editor like Scite
require 'net/smtp'
module Web
module Email
class Message
attr_accessor :from, :to, :subject, :body
def initialize(hash = {})
@from = hash[:from]
@to = hash[:to]
@subject = hash[:subject]
@body = hash[:body]
end
def message
time = current_time
<<-SMTP_MSG
Subject: #{@subject}
Message-Id: <#{"%.8f" % time.to_f}@iblp.org>
Date: #{time.strftime("%a, %d %b %Y %H:%M:%S %z %Z")}
From: #{@from}
To: #{@to}
#{@body}
SMTP_MSG
end
def current_time
Time.now
end
end
def self.send(msg)
msg.subject = safe_subject(msg.subject) # munges and untaints string
msg.from = safe_address(msg.from)
msg.to = safe_address(msg.to)
raise ArgumentError, 'msg.body tainted' if msg.body.tainted?
raise ArgumentError, 'msg tainted' if msg.tainted?
Net::SMTP.start('localhost', 25) {|smtp|
smtp.sendmail(msg.message, msg.from, msg.to)
}
end
def self.safe_subject(subject)
subject.gsub(/[\n\r\f\e\b]/, ' ').untaint
end
def self.safe_address(address)
address.gsub(/[\n\r\f\e\b]/, '').untaint
end
end
end
</code>