about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2015-05-18 22:28:40 +0000
committerEric Wong <e@80x24.org>2015-05-18 22:28:40 +0000
commitcc2db04b47c5b5daf73873f3865da715812408db (patch)
tree142cbcb493b8bd427cb8ff242fb99f42869ef5e7
parent313b0236c03eebd9f8074b11ff0b1778e22a87d4 (diff)
downloadyahns-cc2db04b47c5b5daf73873f3865da715812408db.tar.gz
We shouldn't blindly pass the "Server" tag through, since we may
be proxying Apache instances and we don't want to misadvertise,
either.

IMHO, it is best to say nothing at all to save bandwidth and
reduce the potential for attackers in case a vulnerability is
discovered in yahns.
-rw-r--r--lib/yahns/proxy_http_response.rb9
-rw-r--r--lib/yahns/proxy_pass.rb9
2 files changed, 17 insertions, 1 deletions
diff --git a/lib/yahns/proxy_http_response.rb b/lib/yahns/proxy_http_response.rb
index 90a9395..cbdce6f 100644
--- a/lib/yahns/proxy_http_response.rb
+++ b/lib/yahns/proxy_http_response.rb
@@ -66,6 +66,7 @@ module Yahns::HttpResponse # :nodoc:
                 env[REQUEST_METHOD] != HEAD
     flags = MSG_DONTWAIT
     alive = @hs.next? && self.class.persistent_connections
+    response_headers = env['yahns.proxy_pass.response_headers']
 
     res = "HTTP/1.1 #{status}\r\n"
     headers.each do |key,value| # n.b.: headers is an Array of 2-element Arrays
@@ -76,6 +77,14 @@ module Yahns::HttpResponse # :nodoc:
         flags |= MSG_MORE if have_body && value.to_i > 0
       end
 
+      # response header mapping
+      case val = response_headers[key]
+      when :ignore
+        next
+      when String
+        value = val
+      end
+
       res << "#{key}: #{value}\r\n"
     end
 
diff --git a/lib/yahns/proxy_pass.rb b/lib/yahns/proxy_pass.rb
index 15c9f53..89c6ef8 100644
--- a/lib/yahns/proxy_pass.rb
+++ b/lib/yahns/proxy_pass.rb
@@ -172,7 +172,7 @@ class Yahns::ProxyPass # :nodoc:
     end
   end # class ReqRes
 
-  def initialize(dest)
+  def initialize(dest, opts = {})
     case dest
     when %r{\Aunix:([^:]+)(?::(/.*))?\z}
       path = $2
@@ -184,6 +184,12 @@ class Yahns::ProxyPass # :nodoc:
     else
       raise ArgumentError, "destination must be an HTTP URL or unix: path"
     end
+    @response_headers = opts[:response_headers] || {}
+
+    # It's wrong to send the backend Server tag through.  Let users say
+    # { "Server => "yahns" } if they want to advertise for us, but don't
+    # advertise by default (for security)
+    @response_headers['Server'] ||= :ignore
     init_path_vars(path)
   end
 
@@ -237,6 +243,7 @@ class Yahns::ProxyPass # :nodoc:
     ctype = env["CONTENT_TYPE"] and req << "Content-Type: #{ctype}\r\n"
     clen = env["CONTENT_LENGTH"] and req << "Content-Length: #{clen}\r\n"
     input = chunked || (clen && clen.to_i > 0) ? env['rack.input'] : nil
+    env['yahns.proxy_pass.response_headers'] = @response_headers
 
     # finally, prepare to emit the headers
     rr.req_start(c, req << "\r\n".freeze, input, chunked)