PDA

View Full Version : Prevent subclassing in Objective-C?




MorphingDragon
Apr 27, 2011, 07:59 AM
In Java you can use the Final keyword to prevent subclassing of a class. Does Objective-C have a similar concept?

I have a database access class I would like to protect from malicious/imporoper subclassing by other team members. I thought of (ab)using the Obj-C runtime to enforce this but it would be better if there was a proper solution.



robbieduncan
Apr 27, 2011, 08:57 AM
If you can't trust your team members then perhaps resigning would be better. This may seem like a joke answer but it's not...

MorphingDragon
Apr 27, 2011, 09:32 AM
If you can't trust your team members then perhaps resigning would be better. This may seem like a joke answer but it's not...

This is at request of the client. I trust the other 2 team members (I hired them), but we wont be using the resulting library ourselves, only maintaining it.


Library Specifics
...
xvi. Prevent Subclassing to "Prevent unauthorized editing or extension of the Database Library." - Third Interview

robbieduncan
Apr 27, 2011, 10:03 AM
So you have to be able to prevent categories as well?

Edit: and another class posing as one of yours as well? Basically you can only stop these things if you control the runtime...

MorphingDragon
Apr 27, 2011, 10:26 AM
So you have to be able to prevent categories as well?

Edit: and another class posing as one of yours as well? Basically you can only stop these things if you control the runtime...

I've made a naive implementation which amounts to a check in each method to check if self is of Class and not SubClass (Doesn't work on posing). One of the team members suggested MetaObjects and isa Pointer swizzling since Obj-C is a dynamic language. I just want to see if there was an easier way before trying something so complicated.

chown33
Apr 27, 2011, 11:39 AM
Library Specifics
...
xvi. Prevent Subclassing to "Prevent unauthorized editing or extension of the Database Library." - Third Interview


I assume this is a customer requirement statement, or something similar.

Exactly what is this intended to defend against?

The way it's worded implies there is an authorized editing or extension, which could be a problem if you write a bunch of custom code that prevents all subclassing.

If it's intended to defend against accidents, there are probably simple strategies that would be reasonably effective.

If it's intended to defend against intentional malicious abuse or exploitation, anything you try is probably doomed to failure. I mention this because the 'final' keyword in Java is a pretty weak defense against anything except accidental subclassing. Anyone with some skill and intent can defeat it or work around it.

MorphingDragon
Apr 27, 2011, 09:13 PM
I assume this is a customer requirement statement, or something similar.

Exactly what is this intended to defend against?

The way it's worded implies there is an authorized editing or extension, which could be a problem if you write a bunch of custom code that prevents all subclassing.

If it's intended to defend against accidents, there are probably simple strategies that would be reasonably effective.

If it's intended to defend against intentional malicious abuse or exploitation, anything you try is probably doomed to failure. I mention this because the 'final' keyword in Java is a pretty weak defense against anything except accidental subclassing. Anyone with some skill and intent can defeat it or work around it.

In all honesty I'm not sure what its supposed to provide protection against. I think they just wan't to force a circle into a square hole. The Client as far as I'm aware are all C# junkies, and its considered good practice to seal classes and methods you don't want to be modified to protect them.

I just wanted to try to see if it was possible before trying to talk to a brick wall.

chown33
Apr 27, 2011, 10:12 PM
In all honesty I'm not sure what its supposed to provide protection against. I think they just wan't to force a circle into a square hole. The Client as far as I'm aware are all C# junkies, and its considered good practice to seal classes and methods you don't want to be modified to protect them.

I thought it might be something like that.

Some things come to mind:

First, there are some easy things you can do on the "protection" front, such as use of @private for any/all ivars that don't need to be visible. Obj-C has no such visibility controls for methods, so don't bother with that.

Second, if it's an issue of published vs. unpublished API (not the same as public vs. non-public API), you can put the published API in the YourClass.h file, then define a protocol (YourUnpublishedMethods.h) or a category (YourClass+UnpublishedMethods.h). The implementation of YourClass.m then implements the protocol, if defined that way, or YourClass+UnpublishedMethods.m implements the category. Just remember that this is NOT a private or protected interface. Anyone who knows the method selector and can figure out the types can send a message. Or you can get selector names using a simple 'nm' command on the binary. It's even possible to figure this stuff out using reflection on an instance at runtime, and then invoke it or log the info for later use.

Third, try explaining to them the reason Objective-C doesn't have some of this stuff, and the reason it's so hard to make it act as if it does, is because Objective-C is a dynamic (late-binding) language, where Java, C#, and others are static (early-binding) languages. "Best practice" depends on the language and its design. The compiler is responsible for more things in static binding, and the runtime either assumes the compiler is correct (potential security issue), or the runtime does the additional checks every time (potential performance lossage). It's not hard to trick the Java compiler into compiling code that doesn't match what the runtime runs with (e.g. a virtual dispatch instead of a non-virtual one), and exciting things will happen at runtime. Depending on the runtime environment's settings, this may or may not cause a runtime error.

MorphingDragon
Apr 27, 2011, 11:05 PM
Thanks, I'll note those when I see them on Friday.