PodSearch

Under the Radar

16: Designing for Misuse

 

00:00:00 ◼   ► Welcome to Under the Radar, a show about independent iOS app development.

00:00:03 ◼   ► I'm Marco Arment. And I'm David Smith. Under the Radar is never longer than 30 minutes,

00:00:07 ◼   ► so let's get started. So today I want to talk about designing for misuse

00:00:12 ◼   ► and maybe abuse too, and maybe some malicious use, but you know just

00:00:16 ◼   ► general categories of misuse of people trying to use your apps

00:00:21 ◼   ► either maliciously or in ways that you didn't intend or consider

00:00:25 ◼   ► when you design them and kinda how you can deal with that and how you can

00:00:29 ◼   ► mitigate or minimize the negative effects of that.

00:00:33 ◼   ► I mean, so you have a number of apps,

00:00:36 ◼   ► I'm thinking of things like my recipe book,

00:00:38 ◼   ► or audio books even, where like,

00:00:40 ◼   ► somebody could potentially get a ton of data in there,

00:00:44 ◼   ► like a ton of records, or like a ton of audio books,

00:00:47 ◼   ► or stuff like that, like,

00:00:48 ◼   ► when you design things, do you account for like,

00:00:52 ◼   ► very, very heavy users who might be using the app

00:00:55 ◼   ► to do or store way more than you designed it for?

00:01:01 ◼   ► It's something I definitely didn't do initially

00:01:05 ◼   ► and had to learn a lot of lessons about doing.

00:01:09 ◼   ► Like in preparation for this episode, I took a look in my recipe sync system,

00:01:13 ◼   ► and I was like, I wonder how many recipes the biggest users have.

00:01:17 ◼   ► And the biggest user has 13,000 recipes--

00:01:21 ◼   ► Oh my god.

00:01:23 ◼   ► --in their sync account.

00:01:25 ◼   ► And they use the app--

00:01:27 ◼   ► I also checked how often-- are they actually still using it?

00:01:30 ◼   ► And it's like their last--

00:01:31 ◼   ► they added their last one yesterday.

00:01:33 ◼   ► So they are still using it with 13,000 recipes.

00:01:37 ◼   ► And I did not in any way design the app

00:01:38 ◼   ► to scale for two 13,000 recipes.

00:01:42 ◼   ► So it's something that I've had to learn.

00:01:44 ◼   ► And I'll get the support requests from people who are like,

00:01:46 ◼   ► why won't it--

00:01:47 ◼   ► sync seems really slow.

00:01:49 ◼   ► And I go and check their account.

00:01:50 ◼   ► And they have, even if not 13,000,

00:01:53 ◼   ► even like two or three thousand recipes and I'm like yeah that's that's gonna be

00:01:58 ◼   ► tough on an iPad to to just move that amount of data around and quickly search

00:02:03 ◼   ► it and things that I mean the numbers aren't massive in and of themselves but

00:02:08 ◼   ► I think like you're saying it's you have to design your app and be adaptive to it

00:02:13 ◼   ► in that way or otherwise it things will just fall down horribly because like

00:02:19 ◼   ► Like, if your app doesn't scale well or gracefully, it's going to kind of fall apart.

00:02:26 ◼   ► And so now, when I'm doing these kinds of things, I always have to think in the back

00:02:29 ◼   ► of my mind, like, how many records or how many entries could someone reasonably have?

00:02:36 ◼   ► It's like, how many records could someone unreasonably have?

00:02:42 ◼   ► What's the limit here beyond which it would be completely impractical for them to even

00:02:45 ◼   ► get there?

00:02:47 ◼   ► And it's also probably worth saying, that person who has 13,000 recipes, they've been

00:02:53 ◼   ► entering them into the system for I think three years now.

00:02:56 ◼   ► They've been using the app for three years.

00:02:59 ◼   ► And so even, you have to keep in mind that things will just gradually grow and extend

00:03:05 ◼   ► over time.

00:03:06 ◼   ► That it's not even just, "Oh, someone's being silly and just creating a million entries

00:03:11 ◼   ► in my system."

00:03:12 ◼   ► It's like, no, they could just use it a lot.

00:03:15 ◼   ► And over the course of several years, because hopefully your app will be around for several

00:03:18 ◼   ► years, it'll get to a point that things are way beyond what you may have originally thought

00:03:24 ◼   ► or expected.

00:03:25 ◼   ► Oh yeah, I mean, like, you know, and this isn't that unreasonable of a thing to, like,

00:03:31 ◼   ► from the user point of view, like, you might, you might think as a user, "Oh, I'm using

00:03:35 ◼   ► everything as design," but like, there's probably like one or two things in your setup, either

00:03:40 ◼   ► the apps you use, or maybe like a giant folder on your computer, or some giant database you

00:03:45 ◼   ► have like, oh, I happen to be a music collector and have like 100,000 MP3s or I happen to

00:03:50 ◼   ► have a lot of photos or whatever else. Almost everybody has the extremes of something. Our

00:03:56 ◼   ► friend Merlin Mann over at Back to Work has often talked about his trouble finding Dropbox

00:04:01 ◼   ► text file markdown editors because that whole category of apps that there's a million

00:04:05 ◼   ► of on the App Store to edit Dropbox note text files, because he has like thousands of them

00:04:10 ◼   ► because he uses them in all sorts of ways that a lot of people don't consider or don't

00:04:13 ◼   ► think of. And a lot of times, like, he'll try a new app and it'll just crash or it'll

00:04:18 ◼   ► be searching will be impossibly slow or something. You know, this happens a lot. Like, almost

00:04:23 ◼   ► everybody has like one thing where they are pushing the bounds on. Like, I have, with

00:04:28 ◼   ► Overcast, I have users that first started reporting like slow sync issues and I would

00:04:34 ◼   ► again, I would dig in with them and I'd find out that they would have like 150 podcast

00:04:39 ◼   ► subscriptions. And it's like most people have trouble keeping up with three to five

00:04:43 ◼   ► podcasts every week and this guy has 150, but he's using them. He's using the app.

00:04:49 ◼   ► Like I'm not going to, like, that's these people's prerogative. If they want to use

00:04:53 ◼   ► the app that way, if it's not like malicious against you in any way, what's the problem?

00:04:57 ◼   ► So you have to design for these kind of extremes and you have to test for them. Like, you'd

00:05:01 ◼   ► be surprised how quickly either your app or your server, the server-side process, if you're

00:05:08 ◼   ► syncing them to a server, dealing with server anyway,

00:05:10 ◼   ► how quickly you can hit memory limits.

00:05:13 ◼   ► 'Cause like a lot of these, like, you know,

00:05:14 ◼   ► my backend is all PHP, and yes,

00:05:16 ◼   ► make fun of it as much as you want,

00:05:17 ◼   ► but almost every language has on the server side

00:05:19 ◼   ► some kind of memory limit that you can configure.

00:05:22 ◼   ► Often it's set by default to something, you know,

00:05:24 ◼   ► in like the hundreds of megabytes usually at most.

00:05:27 ◼   ► So, you know, you might have like a PHP process

00:05:30 ◼   ► might be able to max out at like 32 megs or 128 megs,

00:05:34 ◼   ► something in that range.

00:05:35 ◼   ► Well, if somebody has like 10,000 items

00:05:37 ◼   ► that you're trying to sync

00:05:38 ◼   ► and the server's trying to deal with that,

00:05:39 ◼   ► you actually might hit that,

00:05:40 ◼   ► like depending on the design of your system.

00:05:42 ◼   ► Similarly on iOS, like if you're trying to read

00:05:45 ◼   ► all those records into memory to do some kind of

00:05:47 ◼   ► batch operation or some kind of inefficient counting

00:05:50 ◼   ► or something like that, if you have your own

00:05:53 ◼   ► custom data interaction layer here,

00:05:56 ◼   ► and you are dealing with 10,000 records, 100,000 records

00:05:59 ◼   ► in an app that you designed to have a few hundred records,

00:06:02 ◼   ► you might blow the memory limit on the iOS device

00:06:04 ◼   ► and the app might get killed or crash.

00:06:06 ◼   ► So this is pretty important stuff

00:06:09 ◼   ► to at least deal with gracefully,

00:06:11 ◼   ► or as gracefully as you can.

00:06:12 ◼   ► You know, your app should at least not crash

00:06:15 ◼   ► if a heavy user uses it.

00:06:16 ◼   ► And so you should be, as much as it's possible to,

00:06:19 ◼   ► you should be testing for this.

00:06:21 ◼   ► Like, if you have an app with any kind of user login system,

00:06:24 ◼   ► have a user that has way more content or data or records

00:06:29 ◼   ► than you think is normal,

00:06:31 ◼   ► or that you even think anybody would ever have.

00:06:33 ◼   ► You know, like during the development of Vesper,

00:06:36 ◼   ► our friend Brent Simmons was blogging here and there

00:06:39 ◼   ► about how they had a test data

00:06:42 ◼   ► that was like thousands of notes.

00:06:44 ◼   ► And they knew that almost nobody would ever take

00:06:46 ◼   ► thousands and thousands of notes,

00:06:48 ◼   ► but they wanted to make sure the app worked well

00:06:50 ◼   ► and didn't crash and hopefully was fast

00:06:53 ◼   ► and was still actually good and functional

00:06:55 ◼   ► with way more data than they expected.

00:06:57 ◼   ► So like, you know, first priority, don't break.

00:07:01 ◼   ► you know, don't crash, don't make the UI like break

00:07:05 ◼   ► in weird ways, like something overflowing its bounds

00:07:08 ◼   ► or rendering in the wrong spot, 'cause like some assumption

00:07:10 ◼   ► was broken about how long something would be.

00:07:13 ◼   ► And try to not slow down noticeably.

00:07:16 ◼   ► So there's many strategies for this that, you know,

00:07:18 ◼   ► beyond the scope of this episode.

00:07:20 ◼   ► But you know, generally you wanna have some kind of database

00:07:23 ◼   ► back in, you know, not like a P list with 10,000 entries

00:07:26 ◼   ► in it, like, you wanna have some kind of database.

00:07:29 ◼   ► If you use core data, it will do a lot of this for you,

00:07:31 ◼   ► especially if you use the fetch results controllers, right?

00:07:34 ◼   ► 'Cause you use those here and there, right?

00:07:36 ◼   ► - Yeah, and they handle,

00:07:36 ◼   ► that's how most of this gets done in my apps.

00:07:39 ◼   ► It's like rely on problems that were solved

00:07:43 ◼   ► at a different level.

00:07:44 ◼   ► Because Core Data was designed to scale

00:07:47 ◼   ► from 10 records to 10,000 or 10 million records.

00:07:51 ◼   ► It's intended to be able to do that.

00:07:53 ◼   ► And so if you use it that way,

00:07:56 ◼   ► it does all the nice batching for you

00:07:58 ◼   ► and only pulling in pointers to things

00:08:01 ◼   ► rather than their whole contents initially

00:08:04 ◼   ► and all that kind of stuff.

00:08:05 ◼   ► If you do it thoughtfully in that way,

00:08:08 ◼   ► then a lot of this work can be done for you,

00:08:11 ◼   ► or at least the first pass at this kind of work

00:08:13 ◼   ► can be done for you.

00:08:15 ◼   ► - Exactly.

00:08:16 ◼   ► So generally, don't break under heavy usage like this

00:08:20 ◼   ► if you can help it.

00:08:21 ◼   ► And then try not to slow down.

00:08:22 ◼   ► And so use this as appropriate.

00:08:24 ◼   ► Make sure, watch your memory limits.

00:08:25 ◼   ► It helps to, if you can, run some testing

00:08:28 ◼   ► where you can go into instruments and watch memory usage of your app and see how it changes

00:08:32 ◼   ► if somebody has 10 rows versus 10,000 rows. And it should not be going up linearly with

00:08:40 ◼   ► the amount of data that's being stored in your app. Your in-memory set should not be

00:08:44 ◼   ► scaling up. Your on-disk set obviously could, but in-memory should not. So beyond the technical

00:08:52 ◼   ► side of making sure it works. And, you know, again, that's not a small thing, but beyond

00:08:58 ◼   ► the technical side of things, there are things you can do in the design of the app to kind

00:09:03 ◼   ► of help make this manageable for people and help yourself out too with the amount of load

00:09:09 ◼   ► that you're placing on various parts of it and how something might break.

00:09:13 ◼   ► So I think one of the staples of iOS app usability and design is the table view. The table view,

00:09:20 ◼   ► First of all, it's designed in such a way,

00:09:22 ◼   ► especially when paired with core data

00:09:23 ◼   ► or an intelligent other layer,

00:09:25 ◼   ► it's designed in such a way

00:09:26 ◼   ► that it can scale ridiculously well.

00:09:28 ◼   ► When you combine the way the cells are reused

00:09:31 ◼   ► and only certain amounts of data are paged in at once,

00:09:33 ◼   ► combine that with the estimations of cell heights

00:09:37 ◼   ► and the estimations of sections

00:09:40 ◼   ► and numbers of things in sections,

00:09:41 ◼   ► and then you have the first letter on the right side,

00:09:44 ◼   ► like in the phone contacts app,

00:09:46 ◼   ► you have the letter jumping on the side where you can sort,

00:09:48 ◼   ► and that's also, by the way, helpful in different languages

00:09:50 ◼   ► that you don't support, use apples please,

00:09:52 ◼   ► just use apples thing and you'll be mostly okay.

00:09:55 ◼   ► Stuff like that, having easy navigation,

00:09:58 ◼   ► intelligent sorting of long lists,

00:10:00 ◼   ► you might have a list in your app

00:10:02 ◼   ► that's sorted chronologically.

00:10:03 ◼   ► If there's no way to sort it alphabetically

00:10:06 ◼   ► and somebody might have 10,000 items,

00:10:08 ◼   ► that might be problematic.

00:10:10 ◼   ► Think about how your sorting in your app works

00:10:13 ◼   ► and if there's anything you can do

00:10:15 ◼   ► in the UI design of the app

00:10:17 ◼   ► to make it less cumbersome or impossible to use

00:10:21 ◼   ► for somebody who is, in your opinion,

00:10:23 ◼   ► grossly overusing it or grossly overfilling it.

00:10:26 ◼   ► Because that will happen, there will be good reasons for it,

00:10:29 ◼   ► and if possible, don't break under that, right?

00:10:33 ◼   ► And so other things also in that category

00:10:36 ◼   ► would involve search.

00:10:38 ◼   ► Search is a big one here.

00:10:40 ◼   ► Any kind of local search you can offer

00:10:42 ◼   ► that doesn't use a server is easy, first of all.

00:10:46 ◼   ► Almost every database supports it, SQLite supports it.

00:10:49 ◼   ► You can just write your own dumb one if you really want to,

00:10:51 ◼   ► but please use the search index, it's much easier.

00:10:53 ◼   ► Using stuff like that can really help people

00:10:57 ◼   ► who have tons and tons of entries,

00:10:59 ◼   ► can really help them find their data and use your app.

00:11:02 ◼   ► And with search, the way it works with basically

00:11:07 ◼   ► a whole bunch of binary trees and everything,

00:11:09 ◼   ► you can make a vast number of records accessible via search

00:11:13 ◼   ► without a ton of work and without a ton of CPU time

00:11:16 ◼   ► being spent.

00:11:17 ◼   ► So if there's any possibility of somebody having

00:11:21 ◼   ► a ton of data in your app, offer a search if it makes sense to.

00:11:26 ◼   ► Because it lets your app scale well.

00:11:30 ◼   ► Because all of this is really talking about app scaling.

00:11:33 ◼   ► It's like kind of in the way that website scaling is really

00:11:36 ◼   ► talking about number of users or amount of traffic,

00:11:39 ◼   ► app scaling for one person in this case

00:11:41 ◼   ► is talking about the amount of data

00:11:44 ◼   ► they might store in your app and what

00:11:45 ◼   ► kind of technical and organizational challenges

00:11:50 ◼   ► that will present.

00:11:51 ◼   ► Exactly.

00:11:51 ◼   ► And the nice thing, too, is that most

00:11:53 ◼   ► of these changes, these improvements, these ways

00:11:56 ◼   ► of looking at your app at high usage,

00:12:00 ◼   ► whatever that might mean for your app,

00:12:02 ◼   ► will almost always make it better for the typical case.

00:12:07 ◼   ► that you avoid the-- if your app does get linearly worse every time

00:12:13 ◼   ► the user adds a record, that's incredibly problematic

00:12:17 ◼   ► when you have 10,000 records.

00:12:19 ◼   ► But it means that every single time the user is using the app,

00:12:22 ◼   ► they're making it slightly worse for themselves.

00:12:24 ◼   ► That's not good.

00:12:25 ◼   ► You're discouraging use.

00:12:26 ◼   ► Yeah, what you want is to make sure that your app scales gracefully

00:12:31 ◼   ► in this way, but mostly because then that

00:12:33 ◼   ► means that it's probably going to be a lot better for your typical user.

00:12:38 ◼   ► And obviously that's something you want to keep in the back of your mind, that you don't

00:12:41 ◼   ► want to be making changes that are only beneficial if you have 10,000 users or 10,000 records,

00:12:47 ◼   ► because very few users are going to have that.

00:12:49 ◼   ► And so if it makes your app way more complicated, then that's probably not good.

00:12:54 ◼   ► But looking at it in these ways, you get these benefits.

00:12:56 ◼   ► I mean, it's like you were saying with-- like, UITableView is really efficient.

00:13:00 ◼   ► And UITableView is designed for the original iPhone.

00:13:03 ◼   ► As far as I know, that was built into iPhone OS 1, when things were incredibly constrained

00:13:09 ◼   ► and tight.

00:13:10 ◼   ► And it made an OS where a lot of things are, just scrolling lists, really performant and

00:13:16 ◼   ► powerful.

00:13:17 ◼   ► And so then as devices got more capable, it got even better.

00:13:21 ◼   ► And in the same way, it's like if you are designing things so that they work when things

00:13:24 ◼   ► are constrained, in this case, when they're constrained by having large numbers of things,

00:13:29 ◼   ► When you aren't constrained in that way, suddenly everything's just better and faster,

00:13:34 ◼   ► and probably instantaneous for most of your users.

00:13:37 ◼   ► If things only take a few seconds for your extreme users, they're probably going to

00:13:41 ◼   ► be instantaneous or momentary for your typical user.

00:13:48 ◼   ► And that's what you want.

00:13:50 ◼   ► This exercise is helpful in that way, of looking at your app and saying, "Well, where could

00:13:55 ◼   ► I make this better?"

00:13:56 ◼   ► Like an easy obvious case is just to say like,

00:13:58 ◼   ► "Well, let me throw way more things into it than I need

00:14:01 ◼   ► "and see where I can make it better as a result."

00:14:04 ◼   ► - Exactly, and you know, like you mentioned,

00:14:06 ◼   ► like you know, trying to optimize for typical use,

00:14:08 ◼   ► you know, versus the kind of extremes.

00:14:11 ◼   ► And the fact is like when you're talking about

00:14:13 ◼   ► adding any kind of organizational system,

00:14:15 ◼   ► something like, I'm thinking like, you know,

00:14:17 ◼   ► like one level of folders or tags,

00:14:20 ◼   ► which are basically folders, like you know,

00:14:21 ◼   ► one level of organization to like abstract something away,

00:14:26 ◼   ► that can go a long way.

00:14:27 ◼   ► If you have an app where people might often have

00:14:29 ◼   ► more than about 20 to 50 records,

00:14:32 ◼   ► they might want some kind of way to organize that.

00:14:35 ◼   ► And having just one level of folder hierarchy

00:14:39 ◼   ► could also scale to 10,000 items fairly well.

00:14:42 ◼   ► A little goes a long way here.

00:14:45 ◼   ► You don't really have to go overboard

00:14:46 ◼   ► with accommodating for these things in the UI

00:14:48 ◼   ► because the high-end users, any little bit

00:14:53 ◼   ► will help them tremendously

00:14:55 ◼   ► and it won't put too much of a burden on regular users.

00:14:58 ◼   ► - Exactly.

00:14:59 ◼   ► And obviously these are all like,

00:15:00 ◼   ► these are the kinds of things we were talking about

00:15:02 ◼   ► are in the good case, where things are,

00:15:04 ◼   ► people are using your app in the way that you intended it

00:15:06 ◼   ► and just using it a lot.

00:15:08 ◼   ► But obviously also they could talk,

00:15:10 ◼   ► there could be problems that you could run into

00:15:11 ◼   ► on the malicious side.

00:15:13 ◼   ► And we're about to talk about that, but before we do,

00:15:15 ◼   ► could you tell me about something that's awesome?

00:15:16 ◼   ► - We are sponsored this week by DevMate.

00:15:19 ◼   ► Go to devmate.com/radar to learn more.

00:15:22 ◼   ► DevMate is a single SDK with a set

00:15:24 ◼   ► advanced backend features for Mac developers that allows them to easily integrate in-app

00:15:30 ◼   ► purchasing, software licensing, auto-updates, crash reports, user feedback and more all

00:15:36 ◼   ► for Mac apps without being in the Mac App Store.

00:15:38 ◼   ► This is very useful stuff if you're a Mac developer because you don't have to handle

00:15:41 ◼   ► all these things manually for yourself.

00:15:44 ◼   ► Plus all the analytics for your app with sales and downloads are all available real-time

00:15:49 ◼   ► in DevMate's dashboard.

00:15:50 ◼   ► That's real-time sales analytics data.

00:15:53 ◼   ► MacPaw are very excited to announce that DevMate's rich functionality is now free for all and

00:15:58 ◼   ► is instantly accessible after integration.

00:16:01 ◼   ► MacPaw use these tools themselves to help them build their own apps including CleanMyMac

00:16:05 ◼   ► and you can take a look on their site to see examples of the many other developers that

00:16:09 ◼   ► also rely on DevMate.

00:16:12 ◼   ► These days more and more developers are eager to sell outside the Mac App Store.

00:16:16 ◼   ► Having DevMate as an ultimate solution for independent OS X development is a great place

00:16:20 ◼   ► to start.

00:16:21 ◼   ► You can find out more right now by going to devmate.com/radar.

00:16:26 ◼   ► Once again, that's devmate.com/radar.

00:16:28 ◼   ► If you're a Mac developer, you've got to check this out.

00:16:30 ◼   ► Thank you very much to DevMate for sponsoring

00:16:33 ◼   ► Under the Radar and all of Relay FM.

00:16:35 ◼   ► All right.

00:16:36 ◼   ► So obviously, if people are just putting lots of data

00:16:40 ◼   ► in your app, that's not really problematic.

00:16:42 ◼   ► It could be problematic if your app doesn't handle it well.

00:16:45 ◼   ► But there's also cases where rather than just your users

00:16:49 ◼   ► using the app in a positive, like, they just love it, you know, like this person just really

00:16:53 ◼   ► loves baking and wants to put 13,000 recipes in their -- in my sync system, there can also

00:16:59 ◼   ► be cases, especially as your app gets attention or popular or you get attention or become

00:17:05 ◼   ► popular where people might want to misuse your application for whatever reason or in

00:17:11 ◼   ► whatever way. And so it's kind of important that you also think about it from those perspectives

00:17:16 ◼   ► of what's the worst that people could do?

00:17:19 ◼   ► What could people be doing with my app, with my back end?

00:17:23 ◼   ► You know, if someone ran like a Wireshark application

00:17:26 ◼   ► and looked at all the network traffic

00:17:28 ◼   ► between my app and my server,

00:17:30 ◼   ► are there things that I wouldn't want them to know?

00:17:33 ◼   ► Or would be operations that they could do

00:17:35 ◼   ► that would really hurt me?

00:17:37 ◼   ► And you kind of have to start thinking through

00:17:40 ◼   ► these basic security things in order to make sure

00:17:42 ◼   ► that your app is gonna be stable and worthwhile.

00:17:45 ◼   ► And also, like in the same kind of way we were saying before,

00:17:49 ◼   ► if you do these things, it can prevent misuse,

00:17:53 ◼   ► but it also will probably make basic use better,

00:17:55 ◼   ► because then your app is more secure.

00:17:57 ◼   ► Your user's data is more secure.

00:17:59 ◼   ► Things are more reliable.

00:18:00 ◼   ► And so it does take a bit of work

00:18:02 ◼   ► and a bit of thoughtfulness.

00:18:04 ◼   ► But these are things that are kind of basic things that

00:18:06 ◼   ► are probably important if you want to get into any kind

00:18:09 ◼   ► of thing that stores or uses user's data.

00:18:13 ◼   ► Oh, yeah.

00:18:13 ◼   ► And when you have any kind of-- if you

00:18:15 ◼   ► just have a local app that has no web component, at least that you run, but if you just have

00:18:21 ◼   ► a local app, there's only so much a user can do to hurt anyone else or you using the

00:18:26 ◼   ► app. But as soon as you have a service behind it, or especially like a web interface, there

00:18:32 ◼   ► is so much that people can do that, you know, the good thing is that web security is a pretty

00:18:38 ◼   ► well-known field at this point. I mean, it's not solved. It's not flawless, but the major

00:18:44 ◼   ► categories of danger are well known and many of them can be avoided without too much work

00:18:51 ◼   ► these days because we've had a long time to work on web security. And so one of the basics

00:18:57 ◼   ► is obviously to use SSL. If you have any kind of API running over HTTP, use SSL. This is

00:19:04 ◼   ► not difficult these days. In fact, one tip I've come across recently is, so I host all

00:19:09 ◼   ► my stuff on Linode and they have these things called node balancers, which are just like

00:19:14 ◼   ► their own kind of managed load balancing things

00:19:16 ◼   ► for 20 bucks a month.

00:19:18 ◼   ► And so I use node balancers not only for load balancing,

00:19:21 ◼   ► but even when I only have one server behind them,

00:19:24 ◼   ► I use the node balancer for SSL decryption

00:19:27 ◼   ► and also to be kind of a front end

00:19:28 ◼   ► because then the actual IP of the machine

00:19:31 ◼   ► is not being directly exposed to the users.

00:19:34 ◼   ► And also that is handling all the SSL decryption for me.

00:19:38 ◼   ► And Linode keeps these maintained,

00:19:40 ◼   ► it keeps these updated so that whenever SSL changes,

00:19:43 ◼   ► whenever people discover, oh, this old cipher

00:19:45 ◼   ► actually has a weakness that we just learned about,

00:19:48 ◼   ► so nobody should use that, everyone should upgrade

00:19:50 ◼   ► to TLS one point whatever, or disable this certain cipher

00:19:53 ◼   ► or anything, they do all that for you.

00:19:55 ◼   ► So you are always kept on top of it,

00:19:57 ◼   ► you just paste it in your certificate and your key

00:19:59 ◼   ► into their admin panel, and then your server

00:20:02 ◼   ► talks regular HTTP to the load balancer,

00:20:04 ◼   ► and the load balancer, excuse me, the node balancer,

00:20:07 ◼   ► the node balancer then is handling all the security for you.

00:20:09 ◼   ► So that's, I highly recommend if you're on Linode

00:20:11 ◼   ► and you can spare another 20 bucks a month,

00:20:14 ◼   ► outsource your SSL dealing with to a node balancer.

00:20:17 ◼   ► It's a lot easier.

00:20:18 ◼   ► And you know, but even if you have to do it yourself,

00:20:21 ◼   ► you know, just keep on top of it.

00:20:22 ◼   ► There's a Qols SSL test that you can kind of test your site

00:20:26 ◼   ► and see how it does on the security thing.

00:20:27 ◼   ► Just, you know, go test it every few months

00:20:29 ◼   ► or whenever you hear any news about it,

00:20:30 ◼   ► just make sure you're on top of things.

00:20:32 ◼   ► But, or you can just outsource it, like I do, excuse me.

00:20:35 ◼   ► Or you can just outsource it and it's no big deal.

00:20:38 ◼   ► Also for web pages, consider using content security policy.

00:20:43 ◼   ► This is a relatively young web thing.

00:20:46 ◼   ► It's a header you put on responses,

00:20:50 ◼   ► CSP or content security policy.

00:20:52 ◼   ► It's a thing that, it's basically a declaration you make

00:20:55 ◼   ► in the headers that tells the browser

00:20:58 ◼   ► from what domains and what types of JavaScript

00:21:03 ◼   ► and CSS and assets are permitted to be loaded by this page.

00:21:07 ◼   ► And what this is mostly useful for is to eliminate

00:21:10 ◼   ► a whole category of vulnerabilities

00:21:13 ◼   ► like cross-site scripting.

00:21:15 ◼   ► Then there's tons of vulnerabilities

00:21:17 ◼   ► that this just completely negates

00:21:18 ◼   ► for browsers that support it,

00:21:19 ◼   ► and almost every modern browser will enforce it,

00:21:21 ◼   ► as far as I know.

00:21:22 ◼   ► So using content security policy with SSL

00:21:26 ◼   ► and with HSTS, strict transport security,

00:21:29 ◼   ► which will enforce SSL for basically everything

00:21:32 ◼   ► for all modern browsers, using those things,

00:21:34 ◼   ► you are way more secure than the average service.

00:21:37 ◼   ► And plus, basic service security,

00:21:40 ◼   ► as we talked about last week, or two weeks ago, rather.

00:21:43 ◼   ► So that is, that'll get you a huge part of the way there.

00:21:47 ◼   ► And I mean, heck, I even in my podcast app,

00:21:51 ◼   ► I even have SSL certificate pinning,

00:21:54 ◼   ► which is complete overkill for a podcast app.

00:21:56 ◼   ► But what that means is it makes it a lot harder

00:21:59 ◼   ► for anybody to not only snoop my traffic

00:22:01 ◼   ► and break the app that way,

00:22:03 ◼   ► but also for creepy middlemen,

00:22:05 ◼   ► like when you get on airplane Wi-Fi

00:22:07 ◼   ► and it injects ads into everything you see now,

00:22:10 ◼   ► it makes it impossible for those kind of things

00:22:11 ◼   ► to interfere with my app,

00:22:13 ◼   ► and which protects me and it protects my users.

00:22:15 ◼   ► So these kind of things, they seem like overkill

00:22:18 ◼   ► if you're just making an app

00:22:19 ◼   ► for something basically playing podcasts,

00:22:21 ◼   ► but in the modern era, this really isn't overkill,

00:22:24 ◼   ► and it really isn't that hard.

00:22:26 ◼   ► - I think that's the important thing too.

00:22:27 ◼   ► A lot of these things, a little goes a long way.

00:22:31 ◼   ► Like, just, there's all these best practices and things you're talking about, like the

00:22:35 ◼   ► different types of security and the different approaches you can take.

00:22:39 ◼   ► But doing anything is going to do a lot just to get started with.

00:22:43 ◼   ► And if you're going to do it, fair enough, do it properly.

00:22:46 ◼   ► But all of these things, there's no reason to be sending anything in plain text in a

00:22:53 ◼   ► modern app.

00:22:55 ◼   ► It just doesn't make sense.

00:22:56 ◼   ► Maybe media, maybe.

00:22:58 ◼   ► But in general, you just may as well.

00:23:01 ◼   ► Like things are, it doesn't make your things slower or more expensive or those types of

00:23:05 ◼   ► things.

00:23:06 ◼   ► Like it just makes the app better.

00:23:07 ◼   ► And so if you can, do it.

00:23:09 ◼   ► Because you're just trying to minimize the things, the directions that people could,

00:23:13 ◼   ► you know, be mischievous with your application.

00:23:17 ◼   ► Exactly.

00:23:18 ◼   ► So moving on from now, like direct security attacks, I want to talk a little bit about

00:23:22 ◼   ► spam.

00:23:24 ◼   ► If your app has any kind of user-generated content that could potentially be exposed

00:23:30 ◼   ► to other users of the app or to the public, like on your website, and it's some kind

00:23:33 ◼   ► of like top-ranked list or most popular content or anything like that, that is a potential

00:23:39 ◼   ► vector for spam, for people to spam your site or your service or your app in order to promote

00:23:44 ◼   ► their own stuff or deface stuff or make people look at porn or whatever else.

00:23:49 ◼   ► So anything where user-generated content could be shown to a larger audience of your app's

00:23:54 ◼   ► users. You have to be very, very careful about these kind of things that become possible.

00:23:59 ◼   ► You know, it's one thing to just think, oh, well, I'm going to make, you know, suppose

00:24:06 ◼   ► you have, like, in Overcast, I have a recommendations thing. Suppose I was going to show on the

00:24:10 ◼   ► website top recommended things, which I kind of do in the app, but I'll get to that. You

00:24:15 ◼   ► have to think, like, how could somebody spam this in order to promote their own thing or

00:24:20 ◼   ► show inappropriate content or something, you know, somehow break it in a way that would

00:24:24 ◼   ► be valuable to them or would deface the whole thing and make everyone look bad. And you

00:24:30 ◼   ► might think, "Oh, I can just keep on top of it. I'll just check it every day and

00:24:33 ◼   ► I'll delete anything that looks wrong and it'll be fine." The fact is, you can't

00:24:38 ◼   ► and you won't police it yourself. That is, unless you have a very large dedicated staff

00:24:44 ◼   ► doing this around the clock and in every different language around the world, you're probably

00:24:48 ◼   ► not going to be able to police spam yourself. You know, you can look at the big services

00:24:53 ◼   ► like Twitter, for instance, where spam is a thing and it is not a small deal for a company

00:25:00 ◼   ► like Twitter to try to prevent and eliminate spam as it comes. That takes a huge staff.

00:25:06 ◼   ► So, you probably won't have that luxury. So, my solution to this is to generally just

00:25:11 ◼   ► avoid creating mechanisms that can be spammed. So, avoid creating global top lists, you know,

00:25:17 ◼   ► kind of like global rankings, most popular lists. I don't even have like, you can't even

00:25:22 ◼   ► review podcasts in Overcast. You can't like write written user reviews that are shown

00:25:27 ◼   ► to anybody else because that's also spam, you know, promotional problems like defacing

00:25:32 ◼   ► and everything, legal problems. So like, just if you can avoid any area that can be spammed.

00:25:38 ◼   ► If you can't avoid it, try to outsource the control of that spam or the decision on whether

00:25:43 ◼   ► something is spam, try to outsource that to some other larger authority. So, and I'm

00:25:48 ◼   ► not talking about other spam filters, I'm not talking about like, you know, a Kizmet

00:25:51 ◼   ► or anything like that, I'm talking about outsourcing it to some other authority that

00:25:55 ◼   ► themselves would need to have spam get through in a significant way for it to be a problem

00:26:00 ◼   ► for you. So, in Overcast's case, I use iTunes IDs, because iTunes reviews every podcast

00:26:06 ◼   ► that goes in, and I have never seen spam in the iTunes podcast directory. I've seen bad

00:26:12 ◼   ► but I've never actually seen what most people consider

00:26:15 ◼   ► blatant spam in there.

00:26:17 ◼   ► And it also helps control adult content

00:26:19 ◼   ► and stuff like that because they also look for that.

00:26:21 ◼   ► So in Overcast, I won't show a podcast in search results

00:26:25 ◼   ► unless I can match it to something in the iTunes directory.

00:26:28 ◼   ► And if I can't, it stays private.

00:26:29 ◼   ► You can still enter it by URL,

00:26:31 ◼   ► but it's not gonna be shown to people

00:26:32 ◼   ► who weren't looking for it.

00:26:34 ◼   ► So that basically eliminates any problems

00:26:36 ◼   ► with spam or poor content.

00:26:38 ◼   ► And then also for the recommendation side of it,

00:26:41 ◼   ► I use your Twitter following graph. So the only recommendations you will ever see in

00:26:46 ◼   ► Overcast are either from people you follow on Twitter, so if they're spamming you can

00:26:50 ◼   ► unfollow them and it's, you know, that's your choice, you know, so it's either from

00:26:53 ◼   ► people you have chosen to follow on Twitter, or it's from people, if you don't have

00:26:57 ◼   ► enough people who you follow on Twitter, it's from people who are very popular on Twitter,

00:27:01 ◼   ► who have tons and tons of followers to the point where it would be very, very unlikely

00:27:07 ◼   ► for any spam to get in that way.

00:27:09 ◼   ► But for the most part, it's based on people you follow only.

00:27:12 ◼   ► And so that way, the combination of that

00:27:15 ◼   ► plus the iTunes ID filtering means

00:27:17 ◼   ► that it's basically impossible for this mechanism

00:27:20 ◼   ► to show spam in a meaningful way.

00:27:23 ◼   ► And so really, the best thing you can do

00:27:24 ◼   ► if you have something like this is design it

00:27:27 ◼   ► so that it can't be spammed.

00:27:28 ◼   ► And if it can be spammed, outsource the authority

00:27:31 ◼   ► over what is spam to somebody big.

00:27:33 ◼   ► - Exactly, and I think it's probably a good way to,

00:27:36 ◼   ► I personally just avoid situations that user-generated data would ever be shown to someone else.

00:27:43 ◼   ► I can't think of an example in any of my products where I do that.

00:27:46 ◼   ► I look at that problem and I'm like, "That is big, scary, and not something I want to

00:27:51 ◼   ► touch."

00:27:52 ◼   ► So I just don't.

00:27:53 ◼   ► And maybe that means that there are some features in my apps that I could have that would be

00:27:56 ◼   ► really cool, but I don't.

00:27:58 ◼   ► But I just decided that, you know what?

00:28:00 ◼   ► I'm one person.

00:28:01 ◼   ► I'm never going to be able to—or it's going to be really hard to stay on top of it.

00:28:06 ◼   ► So I just don't, and that's okay.

00:28:07 ◼   ► And I think the important thing for this whole episode's discussion is when you're thinking

00:28:13 ◼   ► of that feature, like when I'm deciding not to add features that show user-generated content

00:28:18 ◼   ► to someone else, the fundamental underlying thing that you have to be thoughtful of is

00:28:23 ◼   ► when you're building it, you have to be building it with what's the worst-case scenario in

00:28:27 ◼   ► mind, that it's so easy when you're building something to think of it only from the cool,

00:28:33 ◼   ► like the way you would use it, perspective. But in order for you to have an app that is going to be good for performance for your extreme users,

00:28:41 ◼   ► or have good security and avoid user-generated content problems, you have to always be building it with the worst case in mind.

00:28:49 ◼   ► And that can be the worst case person, the worst case user, the worst case device, the worst case network.

00:28:55 ◼   ► Whatever it is, if you build something with the worst case in mind, it's overall going to be better as a result.

00:29:02 ◼   ► >>Ezra Klein Exactly. And that's all the time we have this week. Thank you very much for

00:29:06 ◼   ► listening and we will see you next week.

00:29:08 ◼   ► >>Paul