-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: Opinionated restrictions for TypeName parsing #100920
Comments
Tagging subscribers to this area: @dotnet/area-system-reflection-metadata |
|
More context: My specific objection was with having yet another type name parser mantained by .NET team.
The options do not cover all possible names that are invalid in C#. For example, emojis are invalid in C# type names too. Would it make more sense for the opionated hardened layer built on top of this to scan the input for allowed/disallowed characters using something like IndexOfAny (no parsing required)?
The interpretation of this rule is runtime-version specific. For example,
Nit: This assumes that the input was generated by .NET type name formatter. The type and assembly names are frequently hand-authored and it is not unusual to see casing and white space differences in hand-authored names.
Is the list of pre-defined cultures going to depend on the ICU that happens to be installed on the machine? I think that having the type parser to have different behavior from machine to machine is poor behavior, and it may actually open you to interesting security issues. Do we actually need this given the AssemblyNameInfo proposal?
I am not convinced by this example. All you need is to check that the name ends with $"`{expectedGenericArity}". No need to parse anything. |
We have been saying that there is going to be a hardened binary serializer type resolver (with allow lists, etc.) built on top the core type name parser. Most (if not all) of these rules can be enforced by the hardened binary serializer type resolver. No new package required. Why is that not possible? |
|
You are right, I am going to remove it from the proposal.
Our main target for the opinionated restrictions are serializers, as they usually work with untrusted input. Do you really believe that there are serializers which implement their own type-name formatting rather than using
The implementation is going to use
Yes and no.
And also that it does not end with $"`\{expectedGenericArity}"? |
I'm not yet sure what the shipping vehicle would be for an allow-list binder, so if we do produce a type name validator as a by-product of that feature, we could evaluate the best shipping vehicle(s)--either together or separate. That binder would likely be the first consumer of this logic. Taking inspiration from @jkotas's comments, we could choose to defer this proposal here until we've built that binder, prove the need for the logic to be reusable in other contexts, and then consider refactoring the logic out into a natural place for reuse. |
Our own binary serializer can take the assembly name from using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using (var fs = new FileStream("temp.bin", FileMode.Create))
{
var bf = new BinaryFormatter();
bf.Serialize(fs, new MyType());
}
[TypeForwardedFrom("MyAssembly, PUBLICkeyTOKEN=b77a5c561934e089")]
[Serializable]
class MyType
{
} I won't be surprised if other binary-formatter like serializers that store type names into the payload have additional paths to introduce atypical formatting of type names.
I am not sure what you meant by this exactly. I agree that you can invent many empirical rules for validating type names. For example, you can create a rule that enforces that the type name does not start with a digit (System.Reflection.Metadata does not look like a good home for this sort of empirical rules). |
Background and Motivation
Over the years @GrabYourPitchforks has built an opinionated parser for type name parsing from untrusted input.
The parser has been adopted internally at Microsoft and for .NET 9 we have decided to productize it (and ), in order to help us with
BinaryFormatter
removal effort.Based on feedback from @jkotas who noticed the problem of having multiple type name parsers implemented by various teams, we have decided to extend the parser with the possibility to parse all type names supported by CLR itself.
The initial proposal for
TypeName
#97566 contained a very vague boolean flagStrictValidation
. In this proposal I would like to introduce two[Flags] enum
that allow the users to enable opinionated restrictions.Note: From my perspective (I don't have security background and I am not the original author of the parser), the flags can be grouped into few categories:
List`1[[DateTime], [Attacker]]
)Type.FullName
never use whitespaces other than space, while the CLR allows for tabs)I don't have strong opinions about the last category, but I believe than 1&2 are a must have.
Proposed API
Assuming that #100867 gets approved, it's going to require following changes:
Usage Examples
Alternative Designs
We could implement those restrictions on top of the existing
TypeName
API, but it would:And again, it was not our goal in the first place (we needed an opinionated, secure parser, not a general-purpose parser)
Risks
Using
int
-based enumeration limits us to only 32 flags, but it should be enough.The text was updated successfully, but these errors were encountered: