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: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: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: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: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
◼
►
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:10
◼
►
And it made an OS where a lot of things are, just scrolling lists, really performant and
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: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: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: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
◼
►
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: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: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:18
◼
►
So moving on from now, like direct security attacks, I want to talk a little bit about
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: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.