Keep private information out of your logs with Swift

One simple trick to avoid unintentionally leaking your users private info

Image for post
Image for post

So imagine you have an app with a fairly simple model struct like this:

And to help you debug problems in your code, you have a remote-logging system that will send error messages to your backend (say, Sentry or something similar). The function looks like this:

And then, whenever something fishy is happening, you use the logError function so that you can investigate it later:

But wait! This message alone is not that useful. So to help you pinpoint exactly what’s happening, you usually include your model objects as well:

Wonderful, isn’t it?

…Well, there’s a problem

Open your logs, and here’s what you’re likely to see alongside your error messages:

Yikes. All this sensitive data like name, city and date of birth, is leaked to your logs now. Funny thing is that it’s really not something you even need in this case, but still something that you’re totally responsible for.

Don’t commit your users’ personal information to your logs!

But how, you would ask? Should I go over every single logError line in my code and make sure that I only submit the data I need? Should I now worry about it every time I write another log statement? How am I gonna make sure my teammates don’t make the same mistake?

Solution

Luckily, there’s a simple universal solution that can help you solve this problem once and for all. And it involves… 🥁

Property wrappers! Yay, not only are we making our code safer for our users, but also much, much trendier for our developers. Win-win!

So, here’s a neat little property wrapper for this:

This wrapper doesn't do much: it simply makes sure that when your code is trying to print , debugPrint or dump a property, it will show --redacted-- instead of an actual value. And since virtually any existing logging system uses one of these functions, it will effectively remove any @LoggingExcluded property from our logs.

So let’s update our User struct:

And to make sure it works as expected, let’s test our User instance with each of the three logging functions: print , debugPrint and dump :

Works absolutely flawlessly!

So there you have it — just prefix your property with @LoggingExcluded when you want to keep some information out of your logs, and it will never show up in your logs no matter what you do.

I’ve tried this approach in both “Ask Yourself Everyday” and “Time and Again”, and it worked perfectly for me. Now I always sleep peacefully knowing that my users’ data is absolutely safe.

Does this work for you? Do you already use a similar pattern in your code? Have you tried implementing this but for some reason it’s not suitable for your codebase? Or do you have any other questions about this? Let me know in the comments section below! I’m truly excited to hear from you.

Appendix 1: Adding Codable conformance

Thanks for reading the post! Don’t hesitate to ask or suggest anything in the “responses” section below. You can also contact me on Twitter or find me on GitHub. If you have written a piece (or stumbled upon one) exploring similar topic — make sure to post a link to it in the responses so I can include it right below.

Further learning:

Hi! If you want to support me, please check out my apps: Ask Yourself Everyday, Time and Again and Women’s Football 2017. For business inquiries, reach me at oleg@dreyman.dev. Thanks for reading!

iOS development know-it-all, Co-founder at nicephoton.com. Talk to me about Swift, coffee, photography & motorsports.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store