Reject request http_api request that have malformed Authentication header

This commit is contained in:
Paweł Chmielowski 2019-01-30 16:34:29 +01:00
parent 096b4a50e5
commit 56baa07d48
3 changed files with 27 additions and 24 deletions

View File

@ -852,23 +852,23 @@ code_to_phrase(505) -> <<"HTTP Version Not Supported">>.
-spec parse_auth(binary()) -> {binary(), binary()} | {oauth, binary(), []} | undefined. -spec parse_auth(binary()) -> {binary(), binary()} | {oauth, binary(), []} | undefined.
parse_auth(<<"Basic ", Auth64/binary>>) -> parse_auth(<<"Basic ", Auth64/binary>>) ->
Auth = try base64:decode(Auth64) try base64:decode(Auth64) of
catch _:badarg -> <<>> Auth ->
end, case binary:split(Auth, <<":">>) of
%% Auth should be a string with the format: user@server:password [User, Pass] ->
%% Note that password can contain additional characters '@' and ':' PassUtf8 = unicode:characters_to_binary(Pass, utf8),
case str:chr(Auth, $:) of {User, PassUtf8};
0 -> _ ->
undefined; invalid
Pos -> end
{User, <<$:, Pass/binary>>} = erlang:split_binary(Auth, Pos-1), catch _:_ ->
PassUtf8 = unicode:characters_to_binary(binary_to_list(Pass), utf8), invalid
{User, PassUtf8}
end; end;
parse_auth(<<"Bearer ", SToken/binary>>) -> parse_auth(<<"Bearer ", SToken/binary>>) ->
Token = str:strip(SToken), Token = str:strip(SToken),
{oauth, Token, []}; {oauth, Token, []};
parse_auth(<<_/binary>>) -> undefined. parse_auth(<<_/binary>>) ->
invalid.
parse_urlencoded(S) -> parse_urlencoded(S) ->
parse_urlencoded(S, nokey, <<>>, key). parse_urlencoded(S, nokey, <<>>, key).

View File

@ -254,6 +254,7 @@ get_auth_admin(Auth, HostHTTP, RPath, Method) ->
catch _:{bad_jid, _} -> catch _:{bad_jid, _} ->
{unauthorized, <<"badformed-jid">>} {unauthorized, <<"badformed-jid">>}
end; end;
invalid -> {unauthorized, <<"no-auth-provided">>};
undefined -> {unauthorized, <<"no-auth-provided">>} undefined -> {unauthorized, <<"no-auth-provided">>}
end. end.

View File

@ -139,28 +139,30 @@ depends(_Host, _Opts) ->
extract_auth(#request{auth = HTTPAuth, ip = {IP, _}, opts = Opts}) -> extract_auth(#request{auth = HTTPAuth, ip = {IP, _}, opts = Opts}) ->
Info = case HTTPAuth of Info = case HTTPAuth of
{SJID, Pass} -> {SJID, Pass} ->
try jid:decode(SJID) of try jid:decode(SJID) of
#jid{luser = User, lserver = Server} -> #jid{luser = User, lserver = Server} ->
case ejabberd_auth:check_password(User, <<"">>, Server, Pass) of case ejabberd_auth:check_password(User, <<"">>, Server, Pass) of
true -> true ->
#{usr => {User, Server, <<"">>}, caller_server => Server}; #{usr => {User, Server, <<"">>}, caller_server => Server};
false -> false ->
{error, invalid_auth} {error, invalid_auth}
end end
catch _:{bad_jid, _} -> catch _:{bad_jid, _} ->
{error, invalid_auth} {error, invalid_auth}
end; end;
{oauth, Token, _} -> {oauth, Token, _} ->
case ejabberd_oauth:check_token(Token) of case ejabberd_oauth:check_token(Token) of
{ok, {U, S}, Scope} -> {ok, {U, S}, Scope} ->
#{usr => {U, S, <<"">>}, oauth_scope => Scope, caller_server => S}; #{usr => {U, S, <<"">>}, oauth_scope => Scope, caller_server => S};
{false, Reason} -> {false, Reason} ->
{error, Reason} {error, Reason}
end; end;
_ -> invalid ->
{error, invalid_auth};
_ ->
#{} #{}
end, end,
case Info of case Info of
Map when is_map(Map) -> Map when is_map(Map) ->
Tag = proplists:get_value(tag, Opts, <<>>), Tag = proplists:get_value(tag, Opts, <<>>),