You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
CVE-2024-51417: System.Linq.Dynamic.Core allows remote access to properties on reflection types and static properties/fields #867
System.Linq.Dynamic.Core allows remote access to properties on reflection types and static properties/fields.
Details
Access to properties on reflection types allows listing installed nuget packages' names and versions through attributes and base types they require. Then it is possible to google and exploit their vulnerabilities.
Access to static properties/fields allows just as implied.
Initial research shows that whitelisting the allowed types would be a solution to fix both issues, however this will impact the usability from this library.
No timeline is known yet.
Reacted by Rasmus Martinsson, Quentin H, David Eskilsson, musAnday, Jason Rebelo, Andrew Gretton, Russ Harding, Omar Olivo and ShayBenOrbo
Just so I'm clear, there is no work around at this time?
If the code is not building because you treat warnings as errors, you can add <WarningsNotAsErrors>NU1903</WarningsNotAsErrors>
to your csproj file to temporarily not treat this warning as an error so your code will build again. Then you can remove that when it is patched.
Reacted by Warren Buckley, David Eskilsson, Justin Chew, James Monger, Jusef Belkasemi and Jamie Walters
It also passes trough our devops pipelines this way, so we are not completely blocked at the moment, off course this can't be a permanent solution
Reacted by James Monger, Stef Heyenrath, Justin Chew, Robert te Kaat, Russ Harding, Jeroen, Ivar Nesje, SumanDatta99, Tom O'Neil, Neven Marić and 2 more
The only way this will be an issue if you expose the functionality from System.Linq.Dynamic.Core via an unprotected external public API or interface.
Issue 2. Static properties/fields
Also in this case, accessing a static class (normal or via reflection) is also possible in normal C#.
Possible solution
A possible way of solving this issue is that the user needs to whitelist all types which are allowed to use by System.Linq.Dynamic.Core.
This will have impact on the usability, but this will mitigate this CVE because by default no types will be allowed.
Issue 1 I think only is possible because the PredefinedTypesHelper.IsPredefinedType contains the object, can that be the case?
Should issue 2 be solved if the [DynamicLinqType] was checked as well for static members?
@mariusz96 Thanks for the detailed information in this issue.
@StefH
Thanks for changing your mind about fixing this!
The only way this will be an issue if you expose the functionality from System.Linq.Dynamic.Core via an unprotected external public API or interface.
I do believe that exposing dynamic filters/queries to the client is very much the intended use case of the library. However, using GetType() as an entry point to the reflection system or accessing static properties like on Environment class is not.
Possible solution
A possible way of solving this issue is that the user needs to whitelist all types which are allowed to use by System.Linq.Dynamic.Core. This will have impact on the usability, but this will mitigate this CVE because by default no types will be allowed.
If you mean to extend the existing mechanism of white-listing methods to additionally white-list all properties and fields then it makes sense and should fix the vulnerability.
Also, when IQueryable works with database it does not seem too much work for the end user to add some attributes/configuration on their table types so they can use them with the library. Might be harder for dependent nuget packages or end users with different use cases though.
Issue 1 I think only is possible because the PredefinedTypesHelper.IsPredefinedType contains the object, can that be the case? Should issue 2 be solved if the [DynamicLinqType] was checked as well for static members?
When removing the object type from PredefinedTypes, this issue seems to be solved. So the provided POC code will now throw an exception when this change in PredefinedTypesHelper is applied.
Related unit-test code:
[Theory][InlineData("c => string.Join(\"_\", c.GetType().Assembly.DefinedTypes.SelectMany(t => t.CustomAttributes).Select(a => a.AttributeType).Select(t => t.AssemblyQualifiedName))")][InlineData("c => string.Join(\"_\", c.GetType().Assembly.DefinedTypes.Select(t => t.BaseType).Select(t => t.AssemblyQualifiedName))")][InlineData("c => string.Join(\"_\", c.GetType().Assembly.FullName))")]publicvoidUsingSystemReflectionAssembly_ThrowsException(stringselector){// Arrangevarqueryable=new[]{newMessage("Alice","Bob")}.AsQueryable();// ActActionaction=()=>queryable.Select(selector);// Assertaction.Should().Throw<ParseException>().WithMessage("Methods on type 'Object' are not accessible");}
Issue 2: Static properties/fields
This can be solved by only allowing classes which are annotated with [DynamicLinqType]. If the class is not annotated, an exception will be thrown.
With the removal of object from the PredefinedTypes I guess it will also remove the .Equals(...) and .ToString(). Maybe it's better with an ability where it's possible to specify the MethodInfo (or MemberInfo if this should be expanded into properties/fields as well) that should be (dis)allowed, or in a combination that the PredefinedTypes will exclude object but have an explicit list of MethodInfo's that will be allowed. This is something that may be useful for classes that is decorated with DynamicLinqType where it may be only one of many method that should be exposed.
Reacted by cedricboon, Michael Washington, Jeffrey Debloudts, Mike-E, Victor Gladkikh, Piotr Kiełkowicz, Gary Ewan Park, Henrik Söderström, Luigi Maestrelli, MSugiura and 10 more
Thanks for the quick reaction on this vulnerability!
1.6.0-preview-02 This version adds support for Equals(object obj), Equals(object objA, object objB), ReferenceEquals(object objA, object objB) and ToString() on object type.
To enable this functionality, set AllowEqualsAndToStringMethodsOnObject to true on the ParsingConfig settings class.
Am I getting this right: Enabling the functionality would make an application vulnerable again?
We are using this library to pass dynamic predicates into a queryable.Where(), which fails without setting the flag.
Thanks for the quick reaction on this vulnerability!
1.6.0-preview-02 This version adds support for Equals(object obj), Equals(object objA, object objB), ReferenceEquals(object objA, object objB) and ToString() on object type.
To enable this functionality, set AllowEqualsAndToStringMethodsOnObject to true on the ParsingConfig settings class.
Am I getting this right: Enabling the functionality would make an application vulnerable again?
We are using this library to pass dynamic predicates into a queryable.Where(), which fails without setting the flag.
The main part of the vulnerability was the fact that you could call GetType() on object, this is not allowed anymore.
Hello, I hope this is still read in a closed issue. @StefH: I have a question about the fix and the AllowEqualsAndToStringMethodsOnObject config switch.
In our code users can search for Guids using .ToString().StartsWith and that triggers the ParseError in ParseMemberAccess since version 1.6.
The method is ToString, the method.DeclaringType is System.Object, but the value of the parameter type is System.Guid.
Why is method.declaringType used to check PredefinedTypes list instead of the value of parameter type? System.Guid is in that list and ToString will be called on that type not System.Object so that would be my logical choice to check.
Here is a demo console app. Sorry for the formating.
internalclassProgram{staticvoidMain(string[]args){List<DataWithId>guids=newList<DataWithId>{newDataWithId(Guid.NewGuid(),"bla1"),newDataWithId(Guid.NewGuid(),"bla2"),newDataWithId(Guid.NewGuid(),"bla3"),newDataWithId(Guid.NewGuid(),"bla4"),newDataWithId(newGuid("F370C098-8A29-4CF0-9B58-7F3CE258B607"),"bla5"),};IQueryable<DataWithId>queryable=guids.AsQueryable();queryable=AddWhere(queryable,"Id","F370C098");varresult=queryable.ToList();Console.WriteLine(result.Count);}privatestaticIQueryable<DataWithId>AddWhere(IQueryable<DataWithId>queryable,stringfieldName,stringvalue){queryable=queryable.Where(fieldName+".ToString().StartsWith(\""+value.ToLowerInvariant()+"\")");// --> Unwanted exception, works with suggested code change//var pc = new ParsingConfig();//pc.AllowEqualsAndToStringMethodsOnObject = true;//queryable = queryable.Where(pc, fieldName + ".ToString().StartsWith(\"" + value.ToLowerInvariant() + "\")"); // --> works but is potentially unsafereturnqueryable;}publicclassDataWithId{publicDataWithId(Guidid,stringfield){Id=id;Field=field;}publicGuidId{get;set;}publicstringField{get;set;}}}
For Linq2Object we could just use the other overload of ToString. queryable = queryable.Where(fieldName + ".ToString(\"D\").StartsWith(\"" + value.ToLowerInvariant() + "\")");
That changes the method.DeclaringType to System.Guid. But that is only a trick for this special scenario with Linq2Objects.
In our real world scenario with Linq2NHibernate that doesn't work. But it suggests that the wrong method.DeclaringType is indeed the problem.
did you have a chance yet to review my proposed change with the example app?
Why is method.declaringType used to check PredefinedTypes list instead of the value of parameter type? System.Guid is in that list and ToString will be called on that type not System.Object so that would be my logical choice to check.
We would like to avoid spreading AllowEqualsAndToStringMethodsOnObject all over our code.
If I try to do ToString() over a property that is defined as an int I'm getting the error. Is this the expected behaviour?? The property is defined as an int, not an object
Activity
kwaazaar commentedon Jan 22, 2025
Reported by nuget
daesk commentedon Jan 22, 2025
Hi, @StefH anyone working on this? Any timeline.
We are using the latest version and all our github action and devops builds are failing now
StefH commentedon Jan 22, 2025
We are investigating the issue.
Initial research shows that whitelisting the allowed types would be a solution to fix both issues, however this will impact the usability from this library.
No timeline is known yet.
wbuck commentedon Jan 22, 2025
Just so I'm clear, there is no work around at this time?
jojoman2 commentedon Jan 22, 2025
If the code is not building because you treat warnings as errors, you can add
<WarningsNotAsErrors>NU1903</WarningsNotAsErrors>to your csproj file to temporarily not treat this warning as an error so your code will build again. Then you can remove that when it is patched.
DJFoxHound commentedon Jan 22, 2025
We've added the following to our impacted project's csproj file:
It also passes trough our devops pipelines this way, so we are not completely blocked at the moment, off course this can't be a permanent solution
StefH commentedon Jan 22, 2025
@mariusz96
Thanks for the detailed information in this issue.
Issue 1. Properties on reflection types
The same result can also be achieved by calling normal C# code:
The only way this will be an issue if you expose the functionality from System.Linq.Dynamic.Core via an unprotected external public API or interface.
Issue 2. Static properties/fields
Also in this case, accessing a static class (normal or via reflection) is also possible in normal C#.
Possible solution
A possible way of solving this issue is that the user needs to whitelist all types which are allowed to use by System.Linq.Dynamic.Core.
This will have impact on the usability, but this will mitigate this CVE because by default no types will be allowed.
Tasteful commentedon Jan 22, 2025
Issue 1 I think only is possible because the
PredefinedTypesHelper.IsPredefinedTypecontains theobject, can that be the case?Should issue 2 be solved if the
[DynamicLinqType]was checked as well for static members?mariusz96 commentedon Jan 22, 2025
@StefH
Thanks for changing your mind about fixing this!
I do believe that exposing dynamic filters/queries to the client is very much the intended use case of the library. However, using
GetType()as an entry point to the reflection system or accessing static properties like onEnvironmentclass is not.If you mean to extend the existing mechanism of white-listing methods to additionally white-list all properties and fields then it makes sense and should fix the vulnerability.
Also, when IQueryable works with database it does not seem too much work for the end user to add some attributes/configuration on their table types so they can use them with the library. Might be harder for dependent nuget packages or end users with different use cases though.
StefH commentedon Jan 22, 2025
@Tasteful
This are indeed a good suggestions.
Issue 1. Properties on reflection types
When removing the object type from PredefinedTypes, this issue seems to be solved. So the provided POC code will now throw an exception when this change in PredefinedTypesHelper is applied.
Related unit-test code:
Issue 2: Static properties/fields
This can be solved by only allowing classes which are annotated with
[DynamicLinqType]. If the class is not annotated, an exception will be thrown.Related unit-test code:
@mariusz96
Would this solve this CVE ?
Tasteful commentedon Jan 22, 2025
With the removal of
objectfrom thePredefinedTypesI guess it will also remove the.Equals(...)and.ToString(). Maybe it's better with an ability where it's possible to specify theMethodInfo(orMemberInfoif this should be expanded into properties/fields as well) that should be (dis)allowed, or in a combination that thePredefinedTypeswill excludeobjectbut have an explicit list ofMethodInfo'sthat will be allowed. This is something that may be useful for classes that is decorated withDynamicLinqTypewhere it may be only one of many method that should be exposed.14 remaining items
StefH commentedon Jan 26, 2025
Version 1.6.0 is released.
MorgeMoensch commentedon Jan 27, 2025
Thanks for the quick reaction on this vulnerability!
Am I getting this right: Enabling the functionality would make an application vulnerable again?
We are using this library to pass dynamic predicates into a
queryable.Where(), which fails without setting the flag.StefH commentedon Jan 27, 2025
The main part of the vulnerability was the fact that you could call
GetType()onobject, this is not allowed anymore.Bump System.Linq.Dynamic.Core from 1.3.8 to 1.6.0.1 ClosedXML#376
Bump System.Linq.Dynamic.Core from 1.3.8 to 1.6.0.1 ClosedXML#376
Bump System.Linq.Dynamic.Core from 1.3.8 to 1.6.0.1 #376 (#377)
FS-FrankLakmann commentedon Aug 18, 2025
Hello, I hope this is still read in a closed issue.
@StefH: I have a question about the fix and the AllowEqualsAndToStringMethodsOnObject config switch.
In our code users can search for Guids using .ToString().StartsWith and that triggers the ParseError in ParseMemberAccess since version 1.6.
The method is ToString, the method.DeclaringType is System.Object, but the value of the parameter type is System.Guid.
Why is method.declaringType used to check PredefinedTypes list instead of the value of parameter type? System.Guid is in that list and ToString will be called on that type not System.Object so that would be my logical choice to check.
StefH commentedon Aug 18, 2025
@FS-FrankLakmann
Can you provide a full example?
FS-FrankLakmann commentedon Aug 19, 2025
Here is a demo console app. Sorry for the formating.
FS-FrankLakmann commentedon Aug 19, 2025
For Linq2Object we could just use the other overload of ToString.
queryable = queryable.Where(fieldName + ".ToString(\"D\").StartsWith(\"" + value.ToLowerInvariant() + "\")");That changes the method.DeclaringType to System.Guid. But that is only a trick for this special scenario with Linq2Objects.
In our real world scenario with Linq2NHibernate that doesn't work. But it suggests that the wrong method.DeclaringType is indeed the problem.
FS-FrankLakmann commentedon Sep 29, 2025
Hello @StefH,
did you have a chance yet to review my proposed change with the example app?
We would like to avoid spreading AllowEqualsAndToStringMethodsOnObject all over our code.
Thanks in advance
Frank
StefH commentedon Sep 29, 2025
@FS-FrankLakmann
I think this PR will solve your question.
#911
And I think this PR is safe and I hope it does not introduce extra security issues.
pabermod commentedon May 15, 2026
If I try to do ToString() over a property that is defined as an int I'm getting the error. Is this the expected behaviour?? The property is defined as an int, not an object