Skip to content

Commit

Permalink
Limit DiameterURI ports to 0-65535 digits on decode
Browse files Browse the repository at this point in the history
A port number is a 16-bit integer, but the regexp used to parse it in
commit 1590920 slavishly followed the RFC 6733 grammar in matching an
arbitrary number of digits. Make decode fail if it's anything more than
5, to avoid doing erlang:list_to_integer/1 on arbitrarily large lists.
Also make it fail if the resulting integer is outside of the expected
range.
  • Loading branch information
Anders Svensson committed Mar 27, 2015
1 parent 545ff77 commit f3e95a4
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 4 deletions.
12 changes: 10 additions & 2 deletions lib/diameter/src/base/diameter_types.erl
Original file line number Diff line number Diff line change
Expand Up @@ -566,17 +566,25 @@ msb(false) -> ?TIME_2036.
scan_uri(Bin) ->
RE = "^(aaas?)://"
"([-a-zA-Z0-9.]+)"
"(:([0-9]+))?"
"(:0{0,5}([0-9]{1,5}))?"
"(;transport=(tcp|sctp|udp))?"
"(;protocol=(diameter|radius|tacacs\\+))?$",
%% A port number is 16-bit, so an arbitrary number of digits is
%% just a vulnerability, but provide a little slack with leading
%% zeros in a port number just because the regexp was previously
%% [0-9]+ and it's not inconceivable that a value might be padded.
%% Don't fantasize about this padding being more than the number
%% of digits in the port number proper.
{match, [A, DN, PN, T, P]} = re:run(Bin,
RE,
[{capture, [1,2,4,6,8], binary}]),
Type = to_atom(A),
{PN0, T0} = defaults(diameter_codec:getopt(rfc), Type),
PortNr = to_int(PN, PN0),
0 = PortNr bsr 16, %% assert
#diameter_uri{type = Type,
fqdn = from_bin(DN),
port = to_int(PN, PN0),
port = PortNr,
transport = to_atom(T, T0),
protocol = to_atom(P, diameter)}.

Expand Down
6 changes: 4 additions & 2 deletions lib/diameter/test/diameter_codec_test.erl
Original file line number Diff line number Diff line change
Expand Up @@ -352,14 +352,16 @@ values('DiameterURI') ->
{[],
["aaa" ++ S ++ "://diameter.se" ++ P ++ Tr ++ Pr
|| S <- ["", "s"],
P <- ["", ":1234"],
P <- ["", ":1234", ":0", ":65535"],
Tr <- ["" | [";transport=" ++ X
|| X <- ["tcp", "sctp", "udp"]]],
Pr <- ["" | [";protocol=" ++ X
|| X <- ["diameter","radius","tacacs+"]]],
Tr /= ";transport=udp"
orelse (Pr /= ";protocol=diameter" andalso Pr /= "")],
["aaa://diameter.se;transport=udp;protocol=diameter",
["aaa://diameter.se:65536",
"aaa://diameter.se:-1",
"aaa://diameter.se;transport=udp;protocol=diameter",
"aaa://diameter.se;transport=udp",
"aaa://:3868",
"aaax://diameter.se",
Expand Down

0 comments on commit f3e95a4

Please sign in to comment.