fix(mqtt): SparkplugCodec's never-throw guard must span the projection too
The try/catch stopped at Payload.Parser.ParseFrom, leaving the metric-projection loop outside it — so the "never throws for any input" contract had a hole in exactly the part that walks an attacker-shaped object graph. Widened to cover parse AND projection. Self-review finding; no test reddened, because a projection escape needs a generated-code shape the vectors do not produce. That is the point: the guard is the contract, not the observed behaviour of today's inputs. Claude-Session: https://claude.ai/code/session_01GASWkNEi68FSCtvr6rLoEW
This commit is contained in:
@@ -74,19 +74,9 @@ public static class SparkplugCodec
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Payload proto;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
proto = Payload.Parser.ParseFrom(wire);
|
var proto = Payload.Parser.ParseFrom(wire);
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
// Deliberately broad. InvalidProtocolBufferException covers malformed, truncated and
|
|
||||||
// over-nested input, but this is the dispatcher-thread boundary: the contract is a
|
|
||||||
// verdict for EVERY input, and narrowing the catch would trade that guarantee for a
|
|
||||||
// taxonomy nobody downstream can act on.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var metrics = proto.Metrics.Count == 0
|
var metrics = proto.Metrics.Count == 0
|
||||||
? []
|
? []
|
||||||
@@ -105,6 +95,18 @@ public static class SparkplugCodec
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// Deliberately broad, and deliberately spanning the projection as well as the parse.
|
||||||
|
// InvalidProtocolBufferException covers malformed, truncated and over-nested input, but
|
||||||
|
// this is the dispatcher-thread boundary and the projection walks an attacker-shaped
|
||||||
|
// object graph: the contract is a verdict for EVERY input, so a guard that stopped at
|
||||||
|
// the parse would be a contract with a hole in it. Narrowing the catch would trade the
|
||||||
|
// guarantee for a taxonomy nobody downstream can act on.
|
||||||
|
payload = SparkplugPayload.Invalid;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decodes Sparkplug-B wire bytes, returning <see cref="SparkplugPayload.Invalid"/> when they
|
/// Decodes Sparkplug-B wire bytes, returning <see cref="SparkplugPayload.Invalid"/> when they
|
||||||
|
|||||||
Reference in New Issue
Block a user