harden redemption, expiry limits and token storage
Findings from a pass over the plugin, smallest first: Redemptions now run one at a time behind a gate. The status checks and the status write that follows them were not atomic, so two requests arriving together with the same one-use token could both mint a guest session. The spent-link check also moved above the tagging step, so hammering an already-used link no longer re-tags a whole series on every hit. The configured maximum expiry is actually respected. Both the API and the picker did Math.max(configured, 720), so setting the ceiling to anything under 30 days was silently ignored. The picker now also hides the quick-pick durations that sit above the ceiling. The share URL, which carries the raw token, is dropped from the record when the link is revoked or expires. Records are never deleted, so dead tokens were accumulating in the store forever. Live links keep it so the dashboard can still copy them, and the README claim that no token is ever written to disk is corrected to say what the code actually does. The HMAC key file is created 0600 instead of inheriting the default mask.
Cette révision appartient à :
@@ -124,6 +124,7 @@ public sealed class ShareTokenService
|
||||
RandomNumberGenerator.Fill(generated);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(_secretPath)!);
|
||||
await File.WriteAllTextAsync(_secretPath, Base64UrlEncode(generated), cancellationToken).ConfigureAwait(false);
|
||||
RestrictToOwner(_secretPath);
|
||||
_secretKey = generated;
|
||||
return _secretKey;
|
||||
}
|
||||
@@ -133,6 +134,27 @@ public sealed class ShareTokenService
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Keeps the HMAC key readable by the server account only. Best effort: a
|
||||
/// no-op on platforms without Unix file modes.
|
||||
/// </summary>
|
||||
private void RestrictToOwner(string path)
|
||||
{
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.SetUnixFileMode(path, UnixFileMode.UserRead | UnixFileMode.UserWrite);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogDebug(ex, "ShareLinks: could not restrict permissions on the token secret file.");
|
||||
}
|
||||
}
|
||||
|
||||
private static string ComputeHash(byte[] secret, ReadOnlySpan<byte> tokenBytes)
|
||||
{
|
||||
using var hmac = new HMACSHA256(secret);
|
||||
|
||||
Référencer dans un nouveau ticket
Bloquer un utilisateur