Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

webmachine_dispatcher crashes on malformed Host header #143

Closed
wants to merge 2 commits into from

5 participants

dklee Kelly McLaughlin Thomas Järvstrand Sean Cribbs Engel A. Sanchez
dklee

When a misconfigured client sends in a Host header of the form "Host: foo.bar.baz:80:80" (or really anything not of the expected form "{host}" or "{host}:{port}" webmachine handler process crashes instead of gracefully returning an error code.

CRASH REPORT Process with 0 neighbours crashed with reason: no case clause matching ["foo.bar.com","80","80"] in webmachine_dispatcher:split_host_port/1 line 55

Kelly McLaughlin kellymclaughlin Return a 400 when a request includes an invalid host header
Fixes #143

Return a 400 Bad Request instead of 500 when a request includes an
invalid host header. Also update the error logging used in
webmachine_mochiweb:handle_error/3.
e655fd4
Kelly McLaughlin
Collaborator

The PR changes the behavior to return a 400 Bad Request instead of 500. Curl output looks like this:

11:07:06:webmachine(klm-handle-invalid-host-header) $ curl -H 'Host: localhost:80:80' localhost:8000/demo/test -v* About to connect() to localhost port 8000 (#0)
*   Trying ::1...
* Connection refused
*   Trying 127.0.0.1...
* connected
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /demo/test HTTP/1.1
> User-Agent: curl/7.28.0
> Accept: */*
> Host: localhost:80:80
>
< HTTP/1.1 400 Bad Request
< Server: MochiWeb/1.1 WebMachine/1.10.0 (never breaks eye contact)
< Date: Tue, 07 May 2013 17:07:29 GMT
< Content-Type: text/html
< Content-Length: 157
<
* Connection #0 to host localhost left intact
<html><head><title>400 Bad Request</title></head><body><h1>Bad Request</h1>Invalid Host<p><hr><address>mochiweb+webmachine web server</address></body></html>* Closing connection #0
Thomas Järvstrand

When we try this patch it causes the webmachine_perf_log_handler to crash because neither finish_time nor end_time get set in the log data.

Kelly McLaughlin kellymclaughlin Handle undefined request time values in performance log handler
Handle the case where the end time or finish time fields of a log data
record are undefined when calculating request times in the performance
log handler. This situation can happen when the request contains an
invalid parameter and is not handle by the decision core module.
75c5793
Kelly McLaughlin
Collaborator

I've updated the function that calculates the time difference for the performance log handler so that it can handle undefined parameters and will not crash the perf log handler.

Kelly McLaughlin kellymclaughlin closed this pull request from a commit
Kelly McLaughlin kellymclaughlin Return a 400 when a request includes an invalid host header
Fixes #143

Return a 400 Bad Request instead of 500 when a request includes an
invalid host header. Also update the error logging used in
webmachine_mochiweb:handle_error/3.
e655fd4
Engel A. Sanchez engelsanchez was assigned
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 7, 2013
  1. Kelly McLaughlin

    Return a 400 when a request includes an invalid host header

    kellymclaughlin authored
    Fixes #143
    
    Return a 400 Bad Request instead of 500 when a request includes an
    invalid host header. Also update the error logging used in
    webmachine_mochiweb:handle_error/3.
Commits on May 28, 2013
  1. Kelly McLaughlin

    Handle undefined request time values in performance log handler

    kellymclaughlin authored
    Handle the case where the end time or finish time fields of a log data
    record are undefined when calculating request times in the performance
    log handler. This situation can happen when the request contains an
    invalid parameter and is not handle by the decision core module.
This page is out of date. Refresh to see the latest.
7 src/webmachine_dispatcher.erl
View
@@ -59,7 +59,10 @@ split_host_port(HostAsString, Scheme) ->
{split_host(HostPart), default_port(Scheme)};
[] ->
%% no host header
- {[], default_port(Scheme)}
+ {[], default_port(Scheme)};
+ _ ->
+ %% Invalid host header
+ {invalid_host, default_port(Scheme)}
end.
split_host(HostAsString) ->
@@ -150,6 +153,8 @@ default_port(https) -> 443.
%% @type dispfail() = {no_dispatch_match, pathtokens()}.
+try_host_binding(_Dispatch, invalid_host, _Port, _Path, _Depth, _RD) ->
+ {error, invalid_host};
try_host_binding(Dispatch, Host, Port, Path, Depth, RD) ->
%% save work during each dispatch attempt by reversing Host up front
try_host_binding1(Dispatch, lists:reverse(Host), Port, Path, Depth, RD).
8 src/webmachine_mochiweb.erl
View
@@ -54,6 +54,8 @@ loop(Name, MochiReq) ->
%% Run the dispatch code, catch any errors...
try webmachine_dispatcher:dispatch(Host, Path, DispatchList, RD) of
+ {error, invalid_host} ->
+ handle_error(400, "Invalid Host", Req);
{no_dispatch_match, _UnmatchedHost, _UnmatchedPathTokens} ->
handle_error(404, {none, none, []}, Req);
{Mod, ModOpts, HostTokens, Port, PathTokens, Bindings,
@@ -86,11 +88,7 @@ handle_error(Code, Error, Req) ->
{ok,ReqState3} = Req2:send_response(Code),
Req3 = {webmachine_request,ReqState3},
{LogData,_ReqState4} = Req3:log_data(),
- case application:get_env(webmachine,webmachine_logger_module) of
- {ok, LogModule} ->
- spawn(LogModule, log_access, [LogData]);
- _ -> nop
- end.
+ spawn(webmachine_log, log_access, [LogData]).
get_wm_option(OptName, {WMOptions, OtherOptions}) ->
{Value, UpdOtherOptions} =
4 src/webmachine_util.erl
View
@@ -368,6 +368,10 @@ unescape_quoted_string([Char | Rest], Acc) ->
%% @doc Compute the difference between two now() tuples, in milliseconds.
%% @spec now_diff_milliseconds(now(), now()) -> integer()
+now_diff_milliseconds(undefined, undefined) ->
+ 0;
+now_diff_milliseconds(undefined, T2) ->
+ now_diff_milliseconds(os:timestamp(), T2);
now_diff_milliseconds({M,S,U}, {M,S1,U1}) ->
((S-S1) * 1000) + ((U-U1) div 1000);
now_diff_milliseconds({M,S,U}, {M1,S1,U1}) ->
Something went wrong with that request. Please try again.