سؤال

This question is specifically focused around static libraries / frameworks; in other words, code that other people will eventually touch.

I'm fairly well versed in properties, since I started iOS development when iOS 6 was released. I have used hidden properties declared in interface extensions to do all of my "private" property work, including using readonly on public facing properties I don't want others to modify and readwrite within interface extensions.

The important thing is that I do not want other people who are using these static libraries / frameworks to be accessing these properties if I don't allow it, nor writing these properties if I let them read it.

I've known for a while that they could theoretically create their own interface extension and make my readonly properties readwrite themselves, or guess the names of hidden properties.

If I want to prevent this, should I be using ivars with the @private tag with directly declared ivars? Are there potential downfalls to doing it this way? Does it actually get me an additional measure of security, or is it a red herring?

هل كانت مفيدة؟

المحلول 2

You should use private ("hidden") properties here. There is no "security" risk. The "attacker" in this scenario is the caller. The caller has complete access to all memory in the process. She can access anything in your framework she wants and there is absolutely nothing you can do to stop that (nor should you). This is true in any language. You can bypass "private:" designations in C++ as well if you know what you're doing. It's all just memory at the end of the day.

It is not your job to protect yourself or your framework from the caller. You both have the same goal: correct program behavior. Your goal is to protect callers from themselves. Make it difficult for them to use your framework incorrectly and easy to use it correctly.

So, you should use the tool that leads to the most correct code. And that tool is properties, and avoiding directly ivar access except in init and dealloc.

نصائح أخرى

Under ARC the only mode supported by properties and not instance variables is copy - so if you need copy use a property.

If you declare your private instance variables in the @implementation section:

@implementation MyClass
{
   // private instance vars
}

then it takes serious effort to access them from outside the class. As you say accessing a "private" property just takes guessing its name - or using the library calls which tell you.

Is it worth it for security? YMMV. But its a good coding practice regardless.

Addendum

As the comment trail shows there has been much discussion over my use of serious effort.

First let's be clear: Objective-C is in the C family of languages, they all allow the programmer to just about anything they choose while staying within the language[*] - these are not the languages of choice if you want strong typing, access restrictions, etc., etc. within your code.

Second, "effort" is not an absolute measure! So maybe I should have chosen the word "obvious" to qualify it rather than "serious". To access a private property just requires the use of a standard method call where the object has type id - there is little clue in the code that the method being called is hidden. To access a private variable requires either an API call (a runtime function or KVC call) or some pointer manipulation - the resultant code looks nothing like a standard variable assignment. So its more obvious.

That said, apart from uses requiring copy, under ARC there is no good reason to use a private property when a private instance variable will do. For a private variable fred compare:

self.fred = 42;   // property access, may involve a call (if not optimised out)
_fred = 42;       // common way to bypass the accessors and get at the underlying var
fred = 42;        // direct access

Take your pick, there is no right answer, but there isn't a wrong one either - this is the realm of opinion (and that is of course an opinion ;-)). I would often pick the last one, private variable - clean & simple. However @RobNapier in his answer prefers the use of properties.


[*] Note: once you consider linking to external code, say written in assembler, all bets are of in any language. At that point you have to look at the "hardware" (real or virtual) and/or "OS" to provide protection.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top