Do you use friend to avoid security problems ?

Started by
20 comments, last by Hodgman 8 years, 6 months ago

Hi,

Do you use friend to avoid security problems of public functions ?

Advertisement

Hi,

Do you use friend to avoid security problems of public functions ?

Yes, I always get a friend to keep a lookout when I urinate in public.

Do you use friend to avoid security problems of public functions ?

There isn't any inherit security problems with the use of public functions...

The friend keywords helps enforce class invariants.
The 'friend' relationship in c++ is the tightest coupling you can give two objects. Friends can reach out and touch your privates.

Over the decades they are one of the most rare relationships I see in professional code. Whatever you are trying to do, there are probably better ways to do it.

For example a public function "Notify" called by all class managed by this class when something change.

The user of the API should not have access to this function, but it's needed to be public to be called.

But it's not a security problem here.

Security problem could be a function which change a private array, only needed by class managed by the class which contains this function.

Since it's public, it can be called by the user of the API, which can cause problem.


For example a public function "Notify" called by all class managed by this class when something change.

I don't follow.

Those needing to be notified can register a callback function. A public add/remove pair can handle any system wanting notifications.

If the object needs to be notified, expose a function that triggers a refresh or update.

Notification in either direction does not require access to private members. Both can be part of the public interface.

For example a public function "Notify" called by all class managed by this class when something change.

The user of the API should not have access to this function, but it's needed to be public to be called.

But it's not a security problem here.

Security problem could be a function which change a private array, only needed by class managed by the class which contains this function.

Since it's public, it can be called by the user of the API, which can cause problem.

If you're truly concerned with security, that is, you want to prevent malicious users of your API from doing things that could be harmful to other users or to you, then making functions private will do very little to help you achieve your goals of protection. If a malicious person wants to call a private function, they only need to discover its existence, find its location in the executable, determine the proper calling convention and parameters, and then they can freely call it with whatever parameter values they want. While the above steps aren't trivial, especially for your average script kiddie, for a well practiced malicious agent it's not that hard.

If on the other hand you want to protect an innocent user from naively doing things that might accidentally cause them or others hard, then yes, friend can sometimes be a tool to help you achieve this goal, although it is debatable if it often or ever the most appropriate tool. I don't have a strong opinion personally, except that when I do use it, I take extra care to ensure that it is justified, and that I'm not overlooking a better solution due to lack of imagination or experience. I'll use it more freely in prototypes because the code tends to be throw-away. In more long-lived code, or when refactoring code that I thought was going to be throw-away but apparently is outliving its expected lifespan, I am biased against it.

Note that when Microsoft designed C#, they thought that this usage was valuable and justifiable enough that they added the "internal" keyword which is even more blunt than C++'s "friend" keyword. Though I suspect there's just as much debate over this language feature as exists for "friend".

I personally suspect that there's always a better tool, a better design or architecture available for providing a convenient, safe, and efficient API without resorting to the use of "friend". However, sometimes the cost of finding that alternative design and implementing it might be higher than the cost of just taking the easy route and using "friend". It's up the the wisdom and experience of the decision-making engineer to distinguish between those cases.

"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke

I suppose the original poster might be thinking "security" as in "network security", even though that has nothing to do with C++, maybe more like a SOAP or REST interface.

In that type of scenario when you are concerned about authorized sources, any exposed method can also require an authentication token. Discard unauthorized or unauthenticated commands, either silently or with an appropriate error, based on your usage needs.

As an example, the APIs for point of sale terminals and credit card readers are publicly available and widespread. The public API for transferring funds through banks, through credit card systems, through PayPal, through other systems can all be found with a few seconds of searching. Even though the details are public they require proper authentication before any transactions are completed.

Public availability does not mean insecure.

There is a misconception among beginner programmers that the keywords 'private' and 'protected' from C++ give you higher security.
It doesn't.

Those keywords are there to guide other programmers into what the original author intended (e.g. "you're not supposed to modify this variable directly", "if you need to read this variable, then the approach you're doing right now is incorrect and will be inefficient or turn into spaghetti very soon") and not as a means of protecting data in RAM from hackers.

I had forgotten the details of what friend in C++ does... Working in .Net land most of the time, I can't remember really needing it.

The only time that I remember ever creating friend functions was for C++ ostream stuff. In .Net, you would just override ToString() in most cases instead, however.

C#'s internal is a somewhat different beast. In a nutshell, it is coarser, and basically means public, but only within assembly boundaries*. In that case, it can be useful if you want to hide your implementations to external consumers of your library, and force users to go through your publicly exposed interfaces. Or if you have some utility code that shouldn't be exposed. Of course with reflection, you can always get at things if you try hard enough.

Unit-testing gets to be a pain, though. I'm not real excited about having to mark what could be private, static, pure helpers as internal in order to be able to write tests in a test assembly. Although that pain is often an indication that there are refactorings that should be made.

* there's the whole InternalsVisibleTo mess,which lets you whitelist certain defined assemblies to poke at your internal bits.

Eric Richards

SlimDX tutorials - http://www.richardssoftware.net/

Twitter - @EricRichards22

This topic is closed to new replies.

Advertisement