The function ext.NativeTypes(ParseStructTag("json")) does not honour the encoding/json skip directive json:"-". Fields tagged json:"-" are registered in the CEL type system under the literal name "-" and are readable from any user-submitted CEL expression via dyn(obj)["-"].
Additionally, newNativeTypes silently registers every nested struct reachable from the type passed to NativeTypes, including types from third-party dependencies the developer never examined.
In fieldNameByTag, the helper used by ParseStructTag("json") to translate Go struct tags into CEL field names.
See at ext/native.go:146:
func fieldNameByTag(structTagToParse string) func(field reflect.StructField) string {
return func(field reflect.StructField) string {
tag, found := field.Tag.Lookup(structTagToParse)
if found {
splits := strings.Split(tag, ",")
if len(splits) > 0 {
// We make the assumption that the leftmost entry in the tag is the name.
// This seems to be true for most tags that have the concept of a name/key, such as:
// https://pkg.go.dev/encoding/xml#Marshal
// https://pkg.go.dev/encoding/json#Marshal
// https://pkg.go.dev/go.mongodb.org/mongo-driver/bson#hdr-Structs
// https://pkg.go.dev/go.yaml.in/yaml/v3#Marshal
name := splits[0]
return name
}
}
return field.Name
}
}
For a field tagged json:"-", this code splits the tag into []string{"-"} and returns "-" as the CEL field name. It never checks whether "-" is the JSON skip sentinel.
This contradicts the encoding/json rule that the source comment explicitly points readers to:
As a special case, if the field tag is "-", the field is always omitted. Note
that a field with name "-" can still be generated using the tag "-,".
The public option also documents...
0.29.0Exploitability
AV:NAC:LAT:PPR:NUI:NVulnerable System
VC:LVI:NVA:NSubsequent System
SC:NSI:NSA:N6.3/CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N