Jint: Prevent reflection / GetType

Created on 1 Mar 2016  Â·  17Comments  Â·  Source: sebastienros/jint

Hi,
is there a way to limit usage of reflection?
I don't want people to use .GetType on .NET types.

Currently I'm checking if the code contains "GetType" but that might not be 100% secure.
Is there maybe some event I can use to resolve methodcalls manually? Instead of them being autoresolved?

Or is there some setting to prevent usage of reflection?

Most helpful comment

Just wanted to comment that in ObjectWrapper.cs, I changed line 84 to add a BindingFlag for DeclaredOnly and it seems to block calls to "GetHashCode" and "GetType"

            // if no properties were found then look for a method (edited)
            var methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public)
                .Where(m => EqualsIgnoreCasing(m.Name, propertyName))
                .ToArray();

All 17 comments

You can prevent the usage of .NET classes as a whole, or register specific namespaces. Isn't that sufficient?

I want to expose my objects in js, for that I made wrapper objects in .net which only expose properties and methods that I want.

However they still have .GetType of course, which is a security concern for me since it can be used to get to the real object, and possible much more.

Right, there is nothing that .NET can do to prevent that. You can just create new objects instead of wrapper (see AutoMapper) and pass them. Like a DTO.

All objects will have GetType(), since that is directly on "object" in .net

Is there maybe a hook like OnMethodCall or OnResolveMethod or something?
So I can resolve the method manually, or just deny access do it?

you can use a dynamic object and override the method resolution

On Tue, Mar 1, 2016 at 1:58 PM, asdfgasdfsafgsdfa [email protected]
wrote:

All objects will have GetType(), since that is directly on "object" in
.net

Is there maybe a hook like OnMethodCall or OnResolveMethod or something?
So I can resolve the method manually, or just deny access do it?

—
Reply to this email directly or view it on GitHub
https://github.com/sebastienros/jint/issues/275#issuecomment-190852140.

@doronguttman is right. Your wrapper could prevent that.

I see, thanks for the information, I will do that.

Hi,
thanks for filing this issue, I didn't think about passing .Net objects to the JS engine would allow the JS to call .GetType(). This is also a security issue for us since custom JS code could retrieve fields of various classes storing sensitive information in the application.

Would it be sufficient on the objects that I pass to Jint to declare a new method "GetType" to hide the original method? Like this:

C# public class Api { public new void GetType() { // Don't allow JS code to get the type } }

When I tried this it seemed to work (in Javascript I got undefined from calling .GetType()), but I don't know if there are ways to circumvent this (in .Net you can do ((object)api).GetType() which would still get the type).
If this is sufficient, I would prefer this solution instead of using a (dynamic) wrapper object. I just would have all classes which can be passed to Jint to declare a new GetType() method.

Is this also needed for Array objects? When I tested this, it seems Jint creates a native Javascript Array when a .Net object returns a .Net Array so GetType() wouldn't be possible on that.

I wonder if Jint could be modified to not allow calling methods with name "GetType" on .Net objects, since I don't think everyone will realize that Javascript code can call .GetType() on passed .Net objects to get access to other classes' fields.
This would also allow to pass already existing .Net types (otherwise you would have to create a dynamic wrapper which in turn creates new wrappers for methods that return other objects).

Thanks!

@T18970237136

I am pretty sure it can be circumvented somehow. And even if not, there _may_ be ways to instantiate "new object()" and then use GetType on that...

The best solution for that would be to have some kind of invoke event, or better yet some class you can assign.

For example:

class InvokeFilter { virtual MethodInfo ResolveMethod(... ) { /_whatever jint does by default already_/ } }

then you could implement your own invoke filter and pass on stuff you dont want to filter to base.ResolveMethod(...)

I dont think this is hard to implement at all, maybe i will make a PR for that later.
But I'm not sure if @sebastienros will accept that :S

I'm about to implement this with a custom attribute - JintInteropAttribute.

The GetOwnProperty method on the ObjectWrapper class can be updated to filter the reflection based on the presence of this attribute.

This should lock down .NET objects passed to Jint (by default hiding methods such as GetType, ToString and GetHashCode etc). Class members can then be made accessible by decorating with the attribute e.g.

[JintInterop]
public void CallMe()
{
}

(NB I have no requirement to allow direct access to .NET classes and namespaces)

Instead of create a custom attribute, you should just create an event in the options that is called whenever reflection on a member is invoked (property, field, method, ...) and return true/false to allow/disallow it. Then you can create your own logic in your code to block it, like using a custom attribute, or checking the names, ... This way it doesn't even impact the performance for the usual cases.

That's a good idea. Also reduces potential for dependency on Jint in projects that may not otherwise need to know about it.

I have issued a pull request to aid with this problem #523

This shouldn't be a problem, because the JsValue.FromObject method converts Syste.Type to a TypeReference.

So you can't use normal reflection, you can only use the already known types.

You can also add an IObjectConverter to disallow specific types.

Just wanted to comment that in ObjectWrapper.cs, I changed line 84 to add a BindingFlag for DeclaredOnly and it seems to block calls to "GetHashCode" and "GetType"

            // if no properties were found then look for a method (edited)
            var methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public)
                .Where(m => EqualsIgnoreCasing(m.Name, propertyName))
                .ToArray();

well, I ask the other way around, how do you enable GetType? because for me it's always returns null. I need GetMethod functionality

Was this page helpful?
0 / 5 - 0 ratings

Related issues

christianrondeau picture christianrondeau  Â·  10Comments

mikeswanson picture mikeswanson  Â·  3Comments

tricuongle picture tricuongle  Â·  5Comments

karoberts picture karoberts  Â·  3Comments

arivera12 picture arivera12  Â·  35Comments