Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Fix security vulnerability allowing command line exploit when using e…
…xim or sendmail from the command line
- Loading branch information
Mikel Lindsaar
committed
Mar 6, 2012
1 parent
47e288e
commit ac56f03
Showing
7 changed files
with
277 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| # encoding: utf-8 | ||
|
|
||
| # The following is an adaptation of ruby 1.9.2's shellwords.rb file, | ||
| # it is modified to include '+' in the allowed list to allow for | ||
| # sendmail to accept email addresses as the sender with a + in them | ||
| # | ||
| module Mail | ||
| module ShellEscape | ||
| # Escapes a string so that it can be safely used in a Bourne shell | ||
| # command line. | ||
| # | ||
| # Note that a resulted string should be used unquoted and is not | ||
| # intended for use in double quotes nor in single quotes. | ||
| # | ||
| # open("| grep #{Shellwords.escape(pattern)} file") { |pipe| | ||
| # # ... | ||
| # } | ||
| # | ||
| # +String#shellescape+ is a shorthand for this function. | ||
| # | ||
| # open("| grep #{pattern.shellescape} file") { |pipe| | ||
| # # ... | ||
| # } | ||
| # | ||
| def escape_for_shell(str) | ||
| # An empty argument will be skipped, so return empty quotes. | ||
| return "''" if str.empty? | ||
|
|
||
| str = str.dup | ||
|
|
||
| # Process as a single byte sequence because not all shell | ||
| # implementations are multibyte aware. | ||
| str.gsub!(/([^A-Za-z0-9_\s\+\-.,:\/@\n])/n, "\\\\\\1") | ||
|
|
||
| # A LF cannot be escaped with a backslash because a backslash + LF | ||
| # combo is regarded as line continuation and simply ignored. | ||
| str.gsub!(/\n/, "'\n'") | ||
|
|
||
| return str | ||
| end | ||
|
|
||
| module_function :escape_for_shell | ||
| end | ||
| end | ||
|
|
||
| class String | ||
| # call-seq: | ||
| # str.shellescape => string | ||
| # | ||
| # Escapes +str+ so that it can be safely used in a Bourne shell | ||
| # command line. See +Shellwords::shellescape+ for details. | ||
| # | ||
| def escape_for_shell | ||
| Mail::ShellEscape.escape_for_shell(self) | ||
| end | ||
| end |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,161 @@ | ||
| # encoding: utf-8 | ||
| require 'spec_helper' | ||
|
|
||
| describe "exim delivery agent" do | ||
|
|
||
| before(:each) do | ||
| # Reset all defaults back to original state | ||
| Mail.defaults do | ||
| delivery_method :smtp, { :address => "localhost", | ||
| :port => 25, | ||
| :domain => 'localhost.localdomain', | ||
| :user_name => nil, | ||
| :password => nil, | ||
| :authentication => nil, | ||
| :enable_starttls_auto => true } | ||
| end | ||
| end | ||
|
|
||
| it "should send an email using exim" do | ||
| Mail.defaults do | ||
| delivery_method :exim | ||
| end | ||
|
|
||
| mail = Mail.new do | ||
| from 'roger@test.lindsaar.net' | ||
| to 'marcel@test.lindsaar.net, bob@test.lindsaar.net' | ||
| subject 'invalid RFC2822' | ||
| end | ||
|
|
||
| Mail::Exim.should_receive(:call).with('/usr/sbin/exim', | ||
| '-i -t -f "roger@test.lindsaar.net"', | ||
| 'marcel@test.lindsaar.net bob@test.lindsaar.net', | ||
| mail) | ||
| mail.deliver! | ||
| end | ||
|
|
||
| describe "return path" do | ||
|
|
||
| it "should send an email with a return-path using exim" do | ||
| Mail.defaults do | ||
| delivery_method :exim | ||
| end | ||
|
|
||
| mail = Mail.new do | ||
| to "to@test.lindsaar.net" | ||
| from "from@test.lindsaar.net" | ||
| sender "sender@test.lindsaar.net" | ||
| subject "Can't set the return-path" | ||
| return_path "return@test.lindsaar.net" | ||
| message_id "<1234@test.lindsaar.net>" | ||
| body "body" | ||
| end | ||
|
|
||
| Mail::Exim.should_receive(:call).with('/usr/sbin/exim', | ||
| '-i -t -f "return@test.lindsaar.net"', | ||
| 'to@test.lindsaar.net', | ||
| mail) | ||
|
|
||
| mail.deliver | ||
|
|
||
| end | ||
|
|
||
| it "should use the sender address is no return path is specified" do | ||
| Mail.defaults do | ||
| delivery_method :exim | ||
| end | ||
|
|
||
| mail = Mail.new do | ||
| to "to@test.lindsaar.net" | ||
| from "from@test.lindsaar.net" | ||
| sender "sender@test.lindsaar.net" | ||
| subject "Can't set the return-path" | ||
| message_id "<1234@test.lindsaar.net>" | ||
| body "body" | ||
| end | ||
|
|
||
| Mail::Exim.should_receive(:call).with('/usr/sbin/exim', | ||
| '-i -t -f "sender@test.lindsaar.net"', | ||
| 'to@test.lindsaar.net', | ||
| mail) | ||
|
|
||
| mail.deliver | ||
| end | ||
|
|
||
| it "should use the from address is no return path or sender are specified" do | ||
| Mail.defaults do | ||
| delivery_method :exim | ||
| end | ||
|
|
||
| mail = Mail.new do | ||
| to "to@test.lindsaar.net" | ||
| from "from@test.lindsaar.net" | ||
| subject "Can't set the return-path" | ||
| message_id "<1234@test.lindsaar.net>" | ||
| body "body" | ||
| end | ||
|
|
||
| Mail::Exim.should_receive(:call).with('/usr/sbin/exim', | ||
| '-i -t -f "from@test.lindsaar.net"', | ||
| 'to@test.lindsaar.net', | ||
| mail) | ||
| mail.deliver | ||
| end | ||
|
|
||
| it "should escape the return path address" do | ||
| Mail.defaults do | ||
| delivery_method :exim | ||
| end | ||
|
|
||
| mail = Mail.new do | ||
| to 'to@test.lindsaar.net' | ||
| from '"from+suffix test"@test.lindsaar.net' | ||
| subject 'Can\'t set the return-path' | ||
| message_id '<1234@test.lindsaar.net>' | ||
| body 'body' | ||
| end | ||
|
|
||
| Mail::Exim.should_receive(:call).with('/usr/sbin/exim', | ||
| '-i -t -f "\"from+suffix test\"@test.lindsaar.net"', | ||
| 'to@test.lindsaar.net', | ||
| mail) | ||
| mail.deliver | ||
| end | ||
| end | ||
|
|
||
| it "should still send an email if the settings have been set to nil" do | ||
| Mail.defaults do | ||
| delivery_method :exim, :arguments => nil | ||
| end | ||
|
|
||
| mail = Mail.new do | ||
| from 'from@test.lindsaar.net' | ||
| to 'marcel@test.lindsaar.net, bob@test.lindsaar.net' | ||
| subject 'invalid RFC2822' | ||
| end | ||
|
|
||
| Mail::Exim.should_receive(:call).with('/usr/sbin/exim', | ||
| '-f "from@test.lindsaar.net"', | ||
| 'marcel@test.lindsaar.net bob@test.lindsaar.net', | ||
| mail) | ||
| mail.deliver! | ||
| end | ||
|
|
||
| it "should escape evil haxxor attemptes" do | ||
| Mail.defaults do | ||
| delivery_method :exim, :arguments => nil | ||
| end | ||
|
|
||
| mail = Mail.new do | ||
| from '"foo\";touch /tmp/PWNED;\""@blah.com' | ||
| to 'marcel@test.lindsaar.net' | ||
| subject 'invalid RFC2822' | ||
| end | ||
|
|
||
| Mail::Exim.should_receive(:call).with('/usr/sbin/exim', | ||
| "-f \"\\\"foo\\\\\\\"\\;touch /tmp/PWNED\\;\\\\\\\"\\\"@blah.com\"", | ||
| 'marcel@test.lindsaar.net', | ||
| mail) | ||
| mail.deliver! | ||
| end | ||
| end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters