From: "John W. Long" Date: 2003-08-26T06:34:13+09:00 Subject: Email and smtp.sendmail security vulnerabilities? 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 # 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