Skip to content

Commit 3197d0f

Browse files
omusKristofferC
authored andcommitted
Avoid possible shredding of passed cred on reject (#28448)
1 parent 04dc666 commit 3197d0f

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

stdlib/LibGit2/src/types.jl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,8 +1303,9 @@ end
13031303

13041304
function approve(cache::CachedCredentials, cred::AbstractCredential, url::AbstractString)
13051305
cred_id = credential_identifier(url)
1306-
if haskey(cache.cred, cred_id) && cred !== cache.cred[cred_id]
1307-
Base.shred!(cache.cred[cred_id])
1306+
if haskey(cache.cred, cred_id)
1307+
# Shred the cached credential we'll be overwriting if it isn't identical
1308+
cred !== cache.cred[cred_id] && Base.shred!(cache.cred[cred_id])
13081309
end
13091310
cache.cred[cred_id] = cred
13101311
nothing
@@ -1313,7 +1314,8 @@ end
13131314
function reject(cache::CachedCredentials, cred::AbstractCredential, url::AbstractString)
13141315
cred_id = credential_identifier(url)
13151316
if haskey(cache.cred, cred_id)
1316-
Base.shred!(cache.cred[cred_id])
1317+
# Shred the cached credential if it isn't the `cred` passed in
1318+
cred !== cache.cred[cred_id] && Base.shred!(cache.cred[cred_id])
13171319
delete!(cache.cred, cred_id)
13181320
end
13191321
nothing
@@ -1413,6 +1415,8 @@ function approve(p::CredentialPayload; shred::Bool=true)
14131415
cred = p.credential
14141416
cred === nothing && return # No credential was used
14151417

1418+
# Each `approve` call needs to avoid shredding the passed in credential as we need
1419+
# the credential information intact for subsequent approve calls.
14161420
if p.cache !== nothing
14171421
approve(p.cache, cred, p.url)
14181422
shred = false # Avoid wiping `cred` as this would also wipe the cached copy
@@ -1441,6 +1445,8 @@ function reject(p::CredentialPayload; shred::Bool=true)
14411445
cred = p.credential
14421446
cred === nothing && return # No credential was used
14431447

1448+
# Note: each `reject` call needs to avoid shredding the passed in credential as we need
1449+
# the credential information intact for subsequent reject calls.
14441450
if p.cache !== nothing
14451451
reject(p.cache, cred, p.url)
14461452
end

stdlib/LibGit2/test/libgit2.jl

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,20 +1741,35 @@ mktempdir() do dir
17411741

17421742
# Overwrite an already cached credential
17431743
dup_cred = deepcopy(cred)
1744-
LibGit2.approve(cache, dup_cred, url) # Shreds `cred`
1744+
LibGit2.approve(cache, dup_cred, url) # Shreds overwritten `cred`
17451745
@test haskey(cache, cred_id)
17461746
@test cache[cred_id] === dup_cred
1747-
@test dup_cred.pass == password
1747+
@test cred.user != "julia"
17481748
@test cred.pass != password
1749+
@test dup_cred.user == "julia"
1750+
@test dup_cred.pass == password
17491751

17501752
cred = dup_cred
17511753

1752-
# Reject an approved should cause it to be removed and shredded
1753-
LibGit2.reject(cache, cred, url)
1754+
# Reject an approved credential
1755+
@test cache[cred_id] === cred
1756+
LibGit2.reject(cache, cred, url) # Avoids shredding the credential passed in
1757+
@test !haskey(cache, cred_id)
1758+
@test cred.user == "julia"
1759+
@test cred.pass == password
1760+
1761+
# Reject and shred an approved credential
1762+
dup_cred = deepcopy(cred)
1763+
LibGit2.approve(cache, cred, url)
1764+
1765+
LibGit2.reject(cache, dup_cred, url) # Shred `cred` but not passed in `dup_cred`
17541766
@test !haskey(cache, cred_id)
17551767
@test cred.user != "julia"
17561768
@test cred.pass != password
1769+
@test dup_cred.user == "julia"
1770+
@test dup_cred.pass == password
17571771

1772+
Base.shred!(dup_cred)
17581773
Base.shred!(cache)
17591774
Base.shred!(password)
17601775
end

0 commit comments

Comments
 (0)