The Glare that Obscures
On plasma, shadows, the importance of keeping secrets, medieval siege strategies, and the merits of playing by the rules of the game.
There are two kinds of light - the glow that illuminates, and the glare that obscures.
- James Thurber
The Corona
It’s time to talk about corona. No, not the virus. Not the beer either. The Sun’s corona is an aura of plasma, extending millions of kilometres into space. It’s over a million degrees C hot, and at times the same in F, too. Interestingly, this is much hotter than the solar surface below it, which is a mere 5500 C - just barely enough to boil Tantalum. It’s hard to get a good view of it without burning your eyes out, except during a total solar eclipse, when the Moon conveniently shields us from everything but the corona.
The Sun is about 400 times further away from us than the Moon, and it’s also about 400 times larger in diameter than the Moon. Because these two numbers are about the same, the Moon is just big enough to block out the Sun from our earthbound point of view. A fact that is surely appreciated by scientists studying the corona. A paradox: The sun is easier to study when we can’t see it. Well, at least the corona is.
Security by obscurity
You’ve all heard about security by obscurity: The idea that you protect a system against attack by hiding how the system works. It is often considered bad security. For one, because it can be hard to keep your secrets forever, and once they are lost, your security is gone faster than you can say “reverse engineering”.
Yet few site owners advertise to the world the exact versions and patch levels of their entire software stack. A 50-character-long password can be hard to crack, but if you tell everyone it's that long, you have helped them crack it. I’d say security by obscurity is bad if it’s the only security you have, or if it’s critical to your overall security. If it’s just another layer on top of several other independent, strong layers, then it can be helpful.
Bad Use of Obscurity
Access control in eZ Platform is configured using a deny-by-default role system. A user with no defined roles has no access to anything. Adding roles grants access to specific resources. It’s important to use this system, and nothing else, to grant and limit access.
One case I’ve seen over the years, is the use of templates to limit access to content. Example: I want my articles to contain the name and mugshot of the author. Where do I have that data? In the author’s User content. So, I add code in my article view template to fetch the author User, and use it to display name and photo. Whoops, permission violation, anonymous users viewing the article don’t have read access to this User. Fine, I add a policy to the Anonymous role to grant read access to editor Users. “Problem solved, let’s go out for lunch!” ?
Later, I might want to add the same feature to article comments, so we can see the pretty faces of all users posting comments. No problem, just extend the policy so that Anonymous can read all Users. “We’re only showing username and profile image, so there’s no danger of leaking anything, right...?” ?
Set Sail for Fail
The policy grants access to User content. What else does User contain? The full name, email, perhaps the postal address, phone number, etc. All of which might be interesting to spammers, scammers, doxxers, and worse. Taking improper care of this information would be a violation of the GDPR and other regulations, as well as my users’ trust.
“Yeah, yeah, but like I said, our template only shows the username and profile photo, nothing else! Our wall of security is impenetrable!” ?
Perhaps my wall is impenetrable, but that doesn’t help if one of my gates is wide open and my guards are all on the other side of the castle. You know, a gate such as the one labelled “API”.
The eZ Platform REST API allows you to interact with the system using the HTTP protocol, in a platform independent way. It’s well documented, and allows you to read every field of every content your roles grant you access to. It has no knowledge of templates, because it doesn’t use templates.
The only thing that protects the user data in my example is obscurity: The data are not directly visible. Any knowledgeable user can dump my entire user database, without “hacking” anything. They would be walking in through an open door, because my roles do not protect sensitive data, as they obviously should.
Work With the System, Not Around It
My mistake in the example above was to try to work around the system security. So how should I do it? User content is read protected for good reasons. If I’m going to show the author name and photo with my articles, it would be a better idea to add fields for that in my article content type, and prefill them with content copied from the current user writing the article. That way, I can keep the roles as they are, avoiding any risk of sensitive data exposure. It also gives me the option of setting them to other values, in case I’m writing on behalf of someone else. The prefill could be done using custom workflow actions, for example.
Or I could make an author content type, containing only name and photo, and copy user values to it, then link it to the article. This is even better, since it lets me easily change the author photo/name for all the articles that author has written, if need be. I could also easily make a list of all articles written per author. This I can make readable for all users, since it doesn’t contain anything we don’t intend to be public.
NB1: If there was a way to use roles to limit access on the field level, that would open up interesting possibilities. We don’t have this in eZ Platform yet, but it’s being considered. Watch this space!
NB2: If you want to show usernames and photos in comments, make sure your users understand and accept this.
I hope this was illuminating. Please remember our guidelines for safely reporting security issues in eZ Systems products, and do the same for other vendors. Until next time, stay safe!