Take the following example in Java
A more verbose version can be found in the excellent course on Programming Languages on Coursera
What’s the issue with the code above? Try to think about if for a few seconds.
allowedUsers can be modified to allow access to users which were not specified as allowed by the original author.
Tests display the the issue at hand
Ok. Nevermind. Instead of learning how we can alleviate the above why don’t we use more modern languages which might bring us some immutability. Like Kotlin.
The Java implementation looks as follows in Kotlin
The docs on listOf state
Returns a new read-only list of given elements.
So, is the security issue fixed?
We verify it with kotlinc
Attempts along the lines of
There is neither a
set method to provide array access or the possibility to reassign
Nevertheless, we can cast it to a MutableList and do the following
Oh snap. The actual object can be changed by another reference.
In defense of Kotlin. It’s stressed quite often how the wording
read-only is used instead of
Although the wording
MutableList might suggest using
List would be immutable.
On with the journey.
Let’s crack open a Haskell REPL (stack)
Data is immutable in Haskell. We do not mutate the existing list but build a new list from applying the function. Haskell lends us a hand at avoiding the issue.
Why does all the above matter? It’s about predictability. Would a senior programmer recognize the bug in the Java example? Quite likely. Would a junior or a senior with sleep deprivation on a deadline? Would you want to keep in mind how every other part of the codebase is able to modify the allowed users? I guess the answer is no.
Of course we can fix the issue with Java by simply copying the list in the getter
Although that is something we would have to remember all the time.
Would someone starting out with Kotlin realize the difference between
immutability before stumbling upon it in the docs or when encountering a bug?
Seems how the simplest approach to getting the issues above out of the way is by using immutability by default.
Code examples can be found on GitHub