How secure is my code, with private variables?

Asked

Viewed 262 times

5

class Conta(object):
    def __init__(self, numero_conta, nome_titular='anonimo'):
        self.__nome_titular = nome_titular
        self.__numero_conta = numero_conta
        self.__saldo = 0.00

    def getNomeTitular(self):
        return self.__nome_titular

    def setNomeTitular(self, nome_titular):
        self.__nome_titular = nome_titular

What I’d like to know exactly is how protected my code is when I use private variables and who I’m depriving my variables from. I know that I deprive a variable for this one is not modified by another class, however, my doubt regarding malicious users, I mean, I am protecting myself from them too?

  • No, especially in Python, because there is no such encapsulation in the language, the only thing it does is rename the properties started in __* for _Classname__*. That is, it would still be possible to change them from outside the class with obj._Conta__saldo = 999999. Behold here.

2 answers

7


This is not a security mechanism, let alone a mechanism that serves users. The mechanism is only to facilitate a little programming.

What it does is exactly what was described in the question, it doesn’t let the private variable be accessed from other parts of the code than this same class, nothing more than that.

In fact it is even worse, this protection occur under normal conditions, if force access on a lower level has no protection at all.

The only thing that occurs is a normal code error if you try to access this variable from outside this class, as if it didn’t exist, but it does exist and has a way to subvert it. It’s like a red light, if you want to pass, you pass.

Python provides very little code protection. If your application needs this to work well, it is wrong.

5

In the paradigm of object orientation, there is what is called encapsulation of properties and methods. It is quite common to find materials in which it is said that the function of encapsulation is to protect the data of an object, which in a way is true, but not in the sense of keeping inaccessible when external to the class. Encapsulation serves for you to define business rules that apply to your properties when done interface with the outside world.

It is common in programming languages to define three levels of encapsulation: public, protected and private. When defined as public, no business rule is required of the property, so it is allowed to be defined directly when external to the class. When defined protected, business rules will apply only when the value comes from outside the class, but classes derived from it are free to define new values directly. When defined as private, only the class itself has the freedom to define values directly; from any other source the business rules will apply.

Business rules are applied to properties through methods getter/Setter.

For the examples below, it was considered a hypothetical, dynamic typing programming language. Class names, methods and properties were generated randomly and have no direct relation to the logic presented.

Considering the definition below of a class with three properties, each with its encapsulation level:

class Foo:

    private meeten
    protected festal
    public tamera

Where the properties protected and private must have business rules, methods are defined getter/Setter for each:

class Foo:

    private meeten
    protected festal
    public tamera

    public getMeeten ():
        ...

    public setMeeten (value):
        ...

    public getFestal ():
        ...

    public setFestal (value):
        ...

Since the above mentioned methods are responsible for the interface of properties with the external environment, it is of paramount importance that they are defined with encapsulation public.

It is now considered some business rules for the application:

  • meeten must be the type string with a maximum of 255 characters;
  • festal must be the type int between 0 and 255;

The implementation of these rules would be something similar to:

    public setMeeten (value):

        if (type(value) != "string"):
            throws TypeError;
        else if (len(value) > 255):
            throws InvalidArgumentException;

        this.meeten = value

    public setFestal (value):

        if (type(value) != "int"):
            throws TypeError;
        else if not (0 <= value <= 255):
            throws InvalidArgumentException;

        this.festal = value

With this it is already possible to understand the protection that the encapsulation generates. Once the business rules are defined, it can be considered that the application will not work when they are not valid. For example, if the property meeten is an integer value. Using the above class, trying to assign an integer to meeten:

inst = Foo()
inst.setMeeten(1)

An exception of the type TypeError would be fired. This is the protection that encapsulation defines. As the application would not work properly when meeten is of the whole type, it forces the value to go through the method setter where business rules are validated. If invalid, the execution flow of the program is changed by the exception, preventing the erroneous execution of the application.

Same goes for the property protected, however, it is considered that in derived classes, the "know what you’re doing" application, then it is given the freedom to directly change the value of the property. For example:

class Bar extend Foo:
    public cheetah ():
        this.festal = 10

The class is allowed Bar directly access the property this.festal, however, understand that if a value is assigned to the property that does not validate the business rules, for example assign a string à festal who should be the int:

this.festal = "anything"

No exception will be triggered and the application can run normally, probably generating an unexpected result. In these cases, it is recommended, even if you have the freedom to access the property directly, to make use of the method setter so as to centralize all business rules in just one place of code.

The properties of the type public are usually so defined when there are no business rules, in which the application would work in an expected way for any type of input.

Obviously, details of this function may vary depending on the language considered. For example, in C++, if a property is defined as private or protected and is tried to access it directly in the external middle of the class, an error will be triggered. Already in Python this encapsulation does not exist. At most, Python remakes the properties and methods started with __* for _Classname__*, so a property called __foo in class Bar would be remapped to _Bar__foo, but direct access to the latter is released, considering access from the external medium Bar._Bar__foo = 0 without error. This is because in Python it is considered that the developer has knowledge of what he is doing, so he is given all this freedom. In C++ (and I believe that Java), it is already a little more rigid, requiring the use of methods getter/setter. In Python, start the property name with __ It’s basically to say to the developer afterwards, "Hey, maybe it’s not a good idea to access this directly. Do this only if you really know what you’re doing.". In C++ it would be "Don’t do this!".

In short, encapsulation only creates a protection for your application to work as it should, defining the class’s "entry ports". In no way does it protect your code from a user accessing it, if it has access to your server and source code. For this, you can read more about on How to protect source code?, as quoted in the comments.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.