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