AI-generated audit finding — this issue was opened from an automated security/correctness audit. It has not been triaged by a human yet; verify the reasoning, reproducibility, and severity before acting on it.
Medium: The first remote Slic stream ID is not gap-checked — CONFIRMED
Affected code:
Verification:
Confirmed. _lastRemoteBidirectionalStreamId and _lastRemoteUnidirectionalStreamId are ulong? and null on connection start. The expression null + 4 evaluates to null, and streamId > null is false, so the gap check is a no-op for the first remote stream. A peer can legally jump from no stream to, say, stream ID 0x4000000. After that jump, frames addressed to never-opened IDs below the jumped-to value return IsUnknownStream == false, and ReadFrameAsync silently ignores them (for StreamWindowUpdate, StreamReadsClosed, StreamWritesClosed) or reads-and-discards the body (for Stream / StreamLast via the isDataConsumed = false fallback at SlicConnection.cs:1509-1526).
Status: Valid correctness/protocol-strictness issue, not directly exploitable for DoS. Severity: Medium.
Recommendation:
- At initial-stream creation, require
streamId == expected initial ID for role/direction (0 or 1 for bidi, 2 or 3 for uni).
- Alternatively replace
+ 4 gap arithmetic with an explicit "last or initial" helper.
Source report: src-IceRpc-Transports-audit-2026-04-14.md (finding The first remote Slic stream ID is not gap-checked — **CONFIRMED**)
Severity (auditor-assigned): Medium
Medium: The first remote Slic stream ID is not gap-checked — CONFIRMED
Affected code:
IsUnknownStreamstreamId > _lastRemoteXxxStreamId + 4Verification:
Confirmed.
_lastRemoteBidirectionalStreamIdand_lastRemoteUnidirectionalStreamIdareulong?and null on connection start. The expressionnull + 4evaluates tonull, andstreamId > nullisfalse, so the gap check is a no-op for the first remote stream. A peer can legally jump from no stream to, say, stream ID0x4000000. After that jump, frames addressed to never-opened IDs below the jumped-to value returnIsUnknownStream == false, andReadFrameAsyncsilently ignores them (forStreamWindowUpdate,StreamReadsClosed,StreamWritesClosed) or reads-and-discards the body (forStream/StreamLastvia theisDataConsumed = falsefallback at SlicConnection.cs:1509-1526).Status: Valid correctness/protocol-strictness issue, not directly exploitable for DoS. Severity: Medium.
Recommendation:
streamId == expected initial ID for role/direction(0 or 1 for bidi, 2 or 3 for uni).+ 4gap arithmetic with an explicit "last or initial" helper.Source report: src-IceRpc-Transports-audit-2026-04-14.md (finding
The first remote Slic stream ID is not gap-checked — **CONFIRMED**)Severity (auditor-assigned): Medium