fix(inbound): single-use nonce on relay provenance proofs (review 2026-10-21 05/O1)
This commit is contained in:
@@ -62,6 +62,29 @@ public class RelayProvenanceTests
|
||||
if (tamper == "none") Assert.Equal(original.Items[AuditWriteMiddleware.InboundExecutionIdItemKey], row.ExecutionId);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a captured relay proof cannot be replayed.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task O1_ReplayedProof_IsRejectedOnSecondUse()
|
||||
{
|
||||
// Review 2026-10-21 05/O1: the proof carries a nonce and the receiver remembers it.
|
||||
var options = new InboundApiOptions { ApiKeyPepper = new string('p', 32) };
|
||||
var original = Context("{}", "10.4.5.6");
|
||||
original.Items[AuditWriteMiddleware.InboundExecutionIdItemKey] = Guid.NewGuid();
|
||||
var header = RelayProvenance.Sign(original, "{}"u8.ToArray(), options.ApiKeyPepper)!;
|
||||
|
||||
var first = Context("{}", "10.0.0.2");
|
||||
first.Request.Headers[RelayProvenance.Header] = header;
|
||||
await RelayProvenance.VerifyAsync(first, options);
|
||||
var replay = Context("{}", "10.0.0.2");
|
||||
replay.Request.Headers[RelayProvenance.Header] = header;
|
||||
await RelayProvenance.VerifyAsync(replay, options);
|
||||
|
||||
Assert.True(RelayProvenance.IsVerified(first));
|
||||
Assert.False(RelayProvenance.IsVerified(replay));
|
||||
Assert.Equal("10.0.0.2", RelayProvenance.CallerIp(replay));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that directly forged forwarding headers cannot change the audited caller.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user