Private Methods and Fields

When I first started writing code (mostly for automation), I was writing procedurally. Object Oriented code wasn’t yet in my skillset. However, as I began to pick up Object Oriented programming with Java, I started discovering some important programming aspects missing in different languages.

Java and C++ have a lot of similar programming aspects. Ideas like encapsulation really make sense and appeared necessary. Returning back to the languages I once loved, I was a bit shocked that this idea of private fields and methods were non-existent. Even more shocking, was the defense of developers, stating that private methods and fields are unnecessary.

Private

Private methods allow the developer to occlude functionality from outside of a class. This way the private method is only called from other methods within the Class.

Similarly, private fields are variables defined in the Class that can not be overwritten outside of the Class.

Groovy & Grails

Returning back to Groovy and Grails I was somewhat surprised that the private keyword didn’t actually make anything private at all.

%MINIFYHTMLe87527f4be67050892088ab9e7c7269f23%class Car{

    private color(){
        println("red")
    }
}

Car car = new Car()
car.color()  Code language: PHP (php)

While working with a team on a Grails project I found that many of the developers (who came from Java backgrounds) were unaware that their private methods could actually be called outside the Class. Consider the above code.

The Car class example above has a private method of color… which shouldn’t be accessible. Yet if you inherit or instantiate this Class, Groovy and Grails will grant you access to the method.

Groovy called this a bug in 2009, but has since dropped it from their bug list. The Groovy community states that Groovy makes everything private but creates hidden Getters and Setters for each private class.

This eliminates any notion of private methods and fields. It’s rather like changing all the locks on your house (saying “My house is now private”) but then giving everyone in town keys to your home.

From a developer perspective our IDE’s will auto complete, showing us methods for a Class, that we shouldn’t even have direct access to *More on this in a bit.

In order to truly create Privacy in Groovy and Grails – you must use Traits, and use an Interface to access the Traits. Private methods or fields in Traits, is truly private.

Python

I loved Python. Python was one of my first languages learned. The libraries available are amazingly diverse and very deep. Notebooks (like Jupyter) are amazing for testing ideas and presenting them in a Notebook like format.

However, as I returned to Python, now having a background in Object Oriented Programming, I discovered that Python also doesn’t handle private methods or fields.

What I mean is that Python doesn’t enforce privacy, instead privacy is an annotation. The way privacy is annotated in Python is through the text mangling of fields or methods… that weird double underscore in method names:

__init()__

By adding double underscores, other developers are expected to know that this means it’s special… it’s a method that should be considered carefully and most likely not directly accessed.

However, Python allows you to access it.

Ruby

Ruby offers a private annotation inline with the code. This says that all definitions of fields or methods after “private” are private. However, you can access these so-called private elements as long as you do so within the object.

In Java this would be called “Protected.” Protected elements are those that can not be accessed outside the object, but can be accessed from an instantiated Class (much like the Groovy class example above.)

Arguments Against Private

Proponents of these languages offer a variety of defenses. Just look on Stack Overflow for “python private method” or “javascript private method” and see the answers you get.

Most commonly we are told by the defenders that private fields/methods is about a lack of trust between the developers on a team. Consider this quote from Stack Overflow:

Written by someone who hates private methods and fields

Arguments For Private

Five years ago I wouldn’t have had a strong opinion on this. After taking courses in Java and C++, I have to say I’m totally onboard with private fields and methods. In fact, I can totally see where teams I worked with in the past had errors introduced through the lack of private methods.

In the quote above tells a story that encapsulation has nothing (even weakly) to do with security. Yet, I’ve filled the role of penetration tester from time to time, I have to say he’s quite wrong.

Making everything public (or everything having public getters and setters) introduces vulnerabilities that might leak parts of an application out to public endpoints.

Not only that, but unintentional development could overwrite private fields (that had tokens for a data store) or kick off methods directly, bypassing the business logic that should have been required.

Example

Imagine you have a team with a lot of turnover. Let’s say the team works on a web application. This application has a registration process that is pretty locked down. It restricts registrants from specific countries, and also isolates registration to those with emails from high domain scores (like private domains) as opposed to free emails (@gmail for example.)

The people who wrote he original registration code have since left the company. The marketing teams decide that their product can grow into new markets if we allow third party affiliates to send registrations to us.

With this new requirement, a public endpoint will be created that is less restricted, and only accessible from these specific third-party affiliates. Users registered this way have different access levels, but still get pulled into the marketing funnel and hopefully generate more income.

New devs look at the goals here and decide to repurpose the old existing registration system. Keeping it DRY, they simply create a new public endpoint / controller that inherits from the existing Registration Class.

However, when they get to the point of passing the submitted registration form data to the database, they call very dangerous method. Without double checking the Registration class, they neglected to notice that the method they are calling should only come after several other methods have verified domain scores of the registrants and fraud checks.

By inheriting the Registration class, the IDE gave them access to all the methods available. Instead of using the proper starting point, they directly access a saveRegistration() method, and pass in parameters to save the registrant to the database.

THE END RESULT is a public endpoint that violates the terms of service, and fills the database with bad registrants.

Had we used private methods, a new set of dev’s wouldn’t need to rely on the original dev team. They wouldn’t need documentation (which rarely exists anyways) and would have not been able to call this dangerous method directly. They would only access the methods that would start the proper setting of data through the fraud checks and finally pass it all to a private method to save to the database.

Python will show an indicator that this method shouldn’t directly be accessed (using double __ in the method name), but how many times to developers miss things like that? Especially under tight deadlines or pressure.

Python requires humans to enforce programming rules. Groovy lies and says, “oh it’s private” but it really isn’t and can be directly accessed. Ruby allows some protections, but not full protections from within the object.

QA Perspective

I am paid to break software – To find points of pressure, or edge cases that can compromise an application.

Looking back, I’m confident that many bugs were due to situations just like this – Where development teams have developers of varying degrees of skill level…. Mix that with tight deadlines and lots of turnover and you get an accident where a field in memory is overwritten with a null and the whole system collapses (such as a field that has a key to access a key value store on start up.)

Not to mention team confusion, especially if a team is lacking in communication. We’re simply relying on one person (an Architect or code reviewer) to spot these issues from the dev side and a QA person to spot this from the client side.

Why not allow the language to enforce these rules? Making elements private does us a lot of good. We restrict and control our application to fit business rules and make it harder for others to bypass functionality accidentally.

About Author /

Leave a Comment

Your email address will not be published.

Start typing and press Enter to search