Skip to content

Commit

Permalink
Hide sensitive header values in show (#1127)
Browse files Browse the repository at this point in the history
With this patch the values for the headers `Authorization`,
`Proxy-Authorization`, `Cookie` and `Set-Cookie` are masked with `*`s
when `HTTP.Request`s and `HTTP.Response`s are `show`n. These headers may
contain sensitive information and masking the values reduces the risk of
leaking something.
  • Loading branch information
nkottary authored Nov 28, 2023
1 parent f9389ae commit 57d57a5
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Server errors are no longer serialized back to the client since this might leak sensitive
information through the error message. ([#1126])
- When `show`ing `HTTP.Request` and `HTTP.Response` the values for the headers
`Authorization`, `Proxy-Authorization`, `Cookie`, and `Set-Cookie` are masked with `*`s
since they might include sensitive information. ([#1127])
### Fixed
- Restrict `HTTP.isredirect` to arguments of integer types. ([#1117])
- Fix `HTTP.getcookies` error when key doesn't exist. ([#1119])
Expand Down
11 changes: 10 additions & 1 deletion src/Messages.jl
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,16 @@ function Base.show(io::IO, m::Message)
end
println(io, typeof(m), ":")
println(io, "\"\"\"")
writeheaders(io, m)

# Mask the following (potentially) sensitive headers with "******":
# - Authorization
# - Proxy-Authorization
# - Cookie
# - Set-Cookie
header_str = sprint(writeheaders, m)
header_str = replace(header_str, r"(*CRLF)^((?>(?>Proxy-)?Authorization|(?>Set-)?Cookie): ).+$"mi => s"\1******")
write(io, header_str)

summary = bodysummary(m.body)
validsummary = isvalidstr(summary)
validsummary && write(io, summary)
Expand Down
14 changes: 14 additions & 0 deletions test/messages.jl
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,20 @@ using JSON
# https://github.com/JuliaWeb/HTTP.jl/issues/828
# don't include empty headers in request when writing
@test repr(Request("GET", "/", ["Accept" => ""])) == "Request:\n\"\"\"\nGET / HTTP/1.1\r\n\r\n\"\"\""

# Test that sensitive header values are masked when `show`ing HTTP.Request and HTTP.Response
for H in ["Authorization", "Proxy-Authorization", "Cookie", "Set-Cookie"], h in (lowercase(H), H)
req = HTTP.Request("GET", "https://xyz.com", [h => "secret", "User-Agent" => "HTTP.jl"])
req_str = sprint(show, req)
@test !occursin("secret", req_str)
@test occursin("$h: ******", req_str)
@test occursin("HTTP.jl", req_str)
resp = HTTP.Response(200, [h => "secret", "Server" => "HTTP.jl"])
resp_str = sprint(show, resp)
@test !occursin("secret", resp_str)
@test occursin("$h: ******", req_str)
@test occursin("HTTP.jl", resp_str)
end
end

@testset "queryparams" begin
Expand Down

0 comments on commit 57d57a5

Please sign in to comment.