WEBVTT
00:00:00.001 --> 00:00:04.760
Do you write Python software that uses a network, opens files, or even accepts user input?
00:00:04.760 --> 00:00:10.280
Of course you do. That's what almost all software does. But these actions can let bad actors exploit
00:00:10.280 --> 00:00:14.980
mistakes and oversights we've made in our code that will allow them to compromise our systems.
00:00:14.980 --> 00:00:20.020
Python is safer than some languages, but there are plenty of issues to be careful of.
00:00:20.020 --> 00:00:25.760
That's why Anthony Shaw and Anthony Lingsworth are here to discuss Python security. This is
00:00:25.760 --> 00:00:30.340
Talk Python To Me, episode 168, recorded June 28th, 2018.
00:00:30.340 --> 00:00:49.380
Welcome to Talk Python To Me, a weekly podcast on Python, the language, the libraries, the ecosystem,
00:00:49.380 --> 00:00:54.140
and the personalities. This is your host, Michael Kennedy. Follow me on Twitter, where I'm at
00:00:54.140 --> 00:00:59.380
M. Kennedy. Keep up with the show and listen to past episodes at talkpython.fm, and follow the
00:00:59.380 --> 00:01:05.240
show on Twitter via at Talk Python. Anthony Shaw, Anthony Lingsworth, welcome to Talk Python.
00:01:05.240 --> 00:01:06.700
Hey, Michael. It's great to be back.
00:01:06.700 --> 00:01:08.600
Hey, Michael. Good to be my first time.
00:01:08.600 --> 00:01:14.760
Yeah, it's good to have you here. So we have a bit of a name conflict here. So Anthony Shaw's
00:01:14.760 --> 00:01:20.560
aunt, and Anthony Lingsworth is Anthony for the rest of the show. Hopefully that works for you all out
00:01:20.560 --> 00:01:25.780
there listening. And we're going to cover something that I think is often overlooked in Python,
00:01:25.780 --> 00:01:31.240
the whole security side of things, right? I mean, I feel like, well, there's no buffer overflow issues and
00:01:31.240 --> 00:01:34.020
things like that. So we must be just totally fine, right?
00:01:34.020 --> 00:01:38.260
No. If only that was the case. If only that was the case.
00:01:38.940 --> 00:01:44.860
Exactly. There's actually a ton of interesting vulnerabilities and things that are pretty common,
00:01:44.860 --> 00:01:49.600
I suspect, still in some circumstances that we're going to go through. But before we do,
00:01:49.600 --> 00:01:54.360
I'd like to hear your guys' story really quick. Anthony, how'd you get into programming in Python?
00:01:54.360 --> 00:01:58.580
I mainly got into programming Python through networking programming. One of my responsibilities
00:01:58.580 --> 00:02:04.160
here is interacting with a lot of Cisco and Juniper and other hardware, and Python is what they use.
00:02:04.160 --> 00:02:09.400
Right on. And Ant, you talked about getting started on Lib Cloud last time, right?
00:02:09.400 --> 00:02:14.740
Yeah, that was me. I was in Seattle and I got sick, and I was stuck in a hotel for the weekend,
00:02:14.740 --> 00:02:17.840
so I learned Python. I never looked back since then.
00:02:17.840 --> 00:02:23.960
Most people say, I got really sick, so I stayed in bed. Other people like you are like,
00:02:23.960 --> 00:02:26.780
oh, I learned a new programming language because I wasn't feeling well.
00:02:26.780 --> 00:02:27.580
I had nowhere to go.
00:02:27.580 --> 00:02:33.520
That's awesome. I totally get it. Let's start first talking about just security in general.
00:02:33.520 --> 00:02:38.620
Anthony, how do you think we should start thinking about security as software developers
00:02:38.620 --> 00:02:41.340
and people that run servers and stuff like that?
00:02:41.340 --> 00:02:46.700
What I tell people is when they start thinking about security, they have to invert how they think.
00:02:46.700 --> 00:02:52.980
Developers are very good at thinking, how do I build something quickly and that's designed well
00:02:52.980 --> 00:02:59.020
and that keeps my customers happy? Security is not like that. Security is how do I break something?
00:02:59.020 --> 00:03:03.120
How do I compromise something? How do I bend the rules?
00:03:03.120 --> 00:03:06.960
So you almost need a tester style thinking.
00:03:06.960 --> 00:03:12.640
So you look at what you've built and think, well, how do I make it do things it's not meant to do?
00:03:12.640 --> 00:03:15.920
I find there's just so much creativity in that.
00:03:15.920 --> 00:03:17.460
It's really hard to think about.
00:03:17.860 --> 00:03:23.700
And unless you see some examples of it in action, it's almost hard to conceptualize some of these things.
00:03:23.700 --> 00:03:30.380
Like I remember the first time I saw the actual code for a buffer overflow exploit.
00:03:30.380 --> 00:03:32.080
Here's how you overflow the buffer.
00:03:32.080 --> 00:03:34.660
Here's how you get it to execute those bits that you've dropped in.
00:03:34.660 --> 00:03:38.240
I'm just like, that is just, that's a different way of thinking, let's say.
00:03:38.240 --> 00:03:42.940
Yeah. I mean, as you say, some of the people who do this, they're really smart and they get really technical.
00:03:42.940 --> 00:03:47.680
But I also want to stress that a lot of this stuff is not rocket science.
00:03:47.680 --> 00:03:52.760
A lot of this is looking at what you do and just trying to keep that mindset.
00:03:52.760 --> 00:03:54.440
Yeah, I think that's a really good point.
00:03:54.440 --> 00:03:59.100
It's easy to get overwhelmed thinking, you know, this stuff is super advanced.
00:03:59.100 --> 00:04:07.640
But actually, 99% of the time, it's like, did you change the password from the default admin password on the database and stuff like that, right?
00:04:07.640 --> 00:04:10.540
That's where people usually start whacking on it, right?
00:04:10.540 --> 00:04:11.900
Exactly. Exactly.
00:04:11.900 --> 00:04:18.160
I mean, most people make a big deal about the super, super complex hacks out there.
00:04:18.160 --> 00:04:26.560
But if you talk to people like Kevin Mitnick and so on, a lot of the stuff they were doing is social engineering, which is just simple, as you say, password stuff or basic configurations.
00:04:26.980 --> 00:04:35.780
A lot of the times with security, if you get the basics right, the simple stuff right, the attackers will just go elsewhere because they're looking for the easiest exploit.
00:04:35.780 --> 00:04:38.120
Yeah, they're just rattling the door to see if it's open, right?
00:04:38.120 --> 00:04:38.740
Exactly.
00:04:38.740 --> 00:04:43.700
Yeah. And how about you? What are your thoughts on the sort of security thinking versus developer thinking?
00:04:43.700 --> 00:04:50.220
Yeah, I mean, I guess that probably the difference between Anthony and I, which is, I guess, confusing because we have the same name.
00:04:50.220 --> 00:04:55.380
Although we sound quite different, hopefully that'll be more obvious to the viewer if we have different accents.
00:04:55.860 --> 00:05:04.960
Is that Anthony spends a lot of his time, I guess, looking at things from the security angle, whereas most of my time has been spent from a development angle.
00:05:04.960 --> 00:05:10.500
And I've been curious about security, I guess, for a long time.
00:05:10.500 --> 00:05:18.560
My first job was doing sort of system support for servers and dealing with hacked servers was a pretty common occurrence.
00:05:18.560 --> 00:05:23.620
And I guess learning how people got into the systems, what they did once they got there.
00:05:24.060 --> 00:05:31.320
And it was kind of shown in the movies, like there's, you know, this person in a dark room with like a green screen and it's all like super technical.
00:05:31.320 --> 00:05:36.480
And they've always got a hoodie on and they're always playing some sort of like metal music in the background.
00:05:36.780 --> 00:05:46.820
But actually, when you're more familiar with, I guess, how systems get compromised, it's just people running scripts that just pinging server after server after server looking for known vulnerabilities.
00:05:47.380 --> 00:05:55.580
And if people haven't configured stuff properly or they've left bad usernames, bad passwords, then they just poke a hole in it and then have their fun, basically.
00:05:55.580 --> 00:05:59.580
I mean, that takes up a lot of people's time and a lot of the security challenges.
00:05:59.820 --> 00:06:07.880
So my kind of curiosity has been, how can I write code in a way that I'm not doing things which the attackers are going to be excited about?
00:06:07.880 --> 00:06:14.600
Like, what mistakes could I be making in my code that they're going to be like, ah, fool, he left this particular vulnerability.
00:06:14.600 --> 00:06:17.760
He didn't read this obscure documentation page.
00:06:17.760 --> 00:06:19.800
And it does come across like that to people.
00:06:19.800 --> 00:06:25.820
Like, it seems hard, which is, I guess, why I put the article together to point out some of the more obvious ones.
00:06:25.820 --> 00:06:28.040
And they're not that complicated.
00:06:28.040 --> 00:06:29.460
Yeah, that's a really good point.
00:06:29.580 --> 00:06:31.260
Most of it isn't that complicated.
00:06:31.260 --> 00:06:33.900
It's just knowing that what is out there.
00:06:33.900 --> 00:06:40.880
You know, me personally, I don't think about it the way that you do, Anthony, in terms of like, how can I break things?
00:06:40.880 --> 00:06:49.620
I think of it more as like a super paranoid, forgetful person, which I'm fairly forgetful in general life as it is, but not paranoid.
00:06:49.620 --> 00:06:52.600
But I'm always thinking like, oh my gosh, what have I forgotten?
00:06:52.600 --> 00:06:56.900
What is the thing that is just wide open that I forgot?
00:06:56.900 --> 00:07:00.400
Did I forget to turn on the firewall that blocks the database port publicly?
00:07:00.400 --> 00:07:04.760
Did I forget to, you know, validate this one thing?
00:07:04.760 --> 00:07:12.440
I think, you know, a while ago there was one admin page on my site that didn't check whether this person was an admin or not.
00:07:12.760 --> 00:07:15.060
And if you could come up with this random URL, you could have found it.
00:07:15.060 --> 00:07:17.180
I'm like, oh my gosh, I can't believe I forgot that.
00:07:17.400 --> 00:07:20.820
So that's sort of my feeling is like a constant uneasiness.
00:07:20.820 --> 00:07:27.120
I know there's thousands of people attacking this site constantly, but throughout, you know, they sort of continuously, I guess.
00:07:27.120 --> 00:07:30.660
And it's like, well, when will they find the thing I forgot?
00:07:30.660 --> 00:07:32.920
It's an ego driven security as it's called.
00:07:32.920 --> 00:07:33.860
But that's cool.
00:07:33.860 --> 00:07:34.500
That's cool.
00:07:34.500 --> 00:07:36.800
If it makes you more secure, then go for it, please.
00:07:37.060 --> 00:07:38.160
Yeah, I think it probably does.
00:07:38.160 --> 00:07:42.080
I mean, I'm always double checking stuff and I think it does really, really help.
00:07:42.080 --> 00:07:44.800
So there's a lot of these things you can address.
00:07:44.800 --> 00:07:48.080
And I think it's probably time to go through this list.
00:07:48.080 --> 00:07:55.880
So when Brian and I spoke about this on Python Bytes just yesterday, actually it came out today, but we recorded it yesterday.
00:07:56.880 --> 00:08:00.860
And he was like, well, the ones that were obvious, they're not even here.
00:08:00.860 --> 00:08:05.960
I mean, some of them are, but some of them are like Python, you know, there's the eval, eval user input.
00:08:05.960 --> 00:08:06.960
Like, don't do that, right?
00:08:06.960 --> 00:08:10.460
So I think you have a really interesting list that you put together here.
00:08:10.460 --> 00:08:13.880
Some of which will be people like, oh yeah, I've heard of that.
00:08:13.880 --> 00:08:14.860
Others like, really?
00:08:14.860 --> 00:08:16.400
I didn't know that was a problem.
00:08:16.400 --> 00:08:20.260
And then they'll frantically pause the podcast and they'll run away and go look at their systems.
00:08:20.260 --> 00:08:25.340
So you want to take us through the topics and we can sort of spend a little time on each one?
00:08:25.340 --> 00:08:26.160
Yeah, sure.
00:08:26.280 --> 00:08:30.080
So I guess I left out some really obvious ones.
00:08:30.080 --> 00:08:32.640
I mean, eval is probably the worst one.
00:08:32.640 --> 00:08:36.820
Like you wouldn't just accept input from the internet and pass it through eval, I'd hope.
00:08:36.820 --> 00:08:38.300
You say that.
00:08:38.300 --> 00:08:39.060
You say that.
00:08:39.060 --> 00:08:40.840
I'm sure it's happening all over the place.
00:08:40.840 --> 00:08:44.860
It's easier to sort that way when you just pass the lambda on the command line.
00:08:44.860 --> 00:08:51.560
Yeah, the PHP equivalent is the reason that you're getting all those entries in your logs looking for wp-admin.
00:08:51.560 --> 00:08:56.160
Anyway, so I guess the number one is
00:08:56.160 --> 00:09:00.180
input injection, which is just common across languages, across frameworks.
00:09:00.580 --> 00:09:05.900
It's nothing specific to Python.
00:09:05.900 --> 00:09:13.840
It's basically noticing that you're creating SQL queries and you're taking a parameter and you're injecting it into a string literal.
00:09:13.840 --> 00:09:20.720
And what they can do is they can escape the quotes you put around the argument or the filter or whatever it was.
00:09:20.840 --> 00:09:24.420
And they can basically run arbitrary SQL queries on your table.
00:09:24.420 --> 00:09:26.920
So SQL injection, I think, is pretty well known.
00:09:26.920 --> 00:09:28.960
It's pretty easy to avoid.
00:09:28.960 --> 00:09:32.200
There are libraries for doing sensible escaping.
00:09:32.200 --> 00:09:38.380
There are libraries for basically parameterizing your SQL queries, which is really the way it should be done.
00:09:38.640 --> 00:09:43.340
But time and time again, that's probably seen as one of the most common things in web applications.
00:09:43.340 --> 00:09:45.640
And it's just one of those things that won't die, right?
00:09:45.640 --> 00:09:52.680
Like it's just there's still popular blog posts that have examples of SQL injection attacks all over.
00:09:52.680 --> 00:09:54.200
And people just read until they get it to work.
00:09:54.200 --> 00:09:55.880
They don't go to the comments and say, don't do this.
00:09:55.880 --> 00:09:56.500
Don't do this.
00:09:56.740 --> 00:10:07.100
Yeah, because it's like when you learn SQL or if you learn how to create SQL queries, it doesn't like there are so many tutorials out there that actually show you the wrong way to do it.
00:10:07.100 --> 00:10:08.840
So this is why it keeps happening.
00:10:08.840 --> 00:10:12.360
Yeah, this is why it keeps happening because people are like, this is how you write a SQL query.
00:10:12.360 --> 00:10:17.240
And then, OK, you want to filter by a particular user or a particular ID or whatever.
00:10:17.240 --> 00:10:18.740
Here's how you write a where clause.
00:10:18.740 --> 00:10:20.300
And, oh, let's take that as a parameter.
00:10:20.300 --> 00:10:22.000
Yeah, yeah, because it's simpler, right?
00:10:22.000 --> 00:10:24.100
People are learning the wrong way to do it every day.
00:10:24.100 --> 00:10:26.900
And we're having to unteach them that kind of practice.
00:10:26.900 --> 00:10:29.240
Luckily, there's a cartoon to remind us.
00:10:29.240 --> 00:10:31.400
SKCD.
00:10:31.400 --> 00:10:32.020
Yeah.
00:10:32.020 --> 00:10:32.440
Yeah.
00:10:32.440 --> 00:10:34.060
Are you familiar with little Bobby tables?
00:10:34.060 --> 00:10:34.960
Yeah, absolutely.
00:10:34.960 --> 00:10:36.160
And I've seen the picture.
00:10:36.160 --> 00:10:40.820
There's a photograph as well as of a car where someone's put on their license plate.
00:10:40.820 --> 00:10:43.480
They've actually tried to put SQL injection on their license plate.
00:10:43.480 --> 00:10:45.740
Get all those license plate readers.
00:10:45.740 --> 00:10:47.040
That was brilliant.
00:10:47.040 --> 00:10:47.560
Yeah.
00:10:47.560 --> 00:10:49.320
So the license plate readers would crash.
00:10:49.320 --> 00:10:50.380
That's the intention anyway.
00:10:50.380 --> 00:10:53.420
And then I guess the other version of that is command injection,
00:10:53.660 --> 00:10:58.140
where you have a script which needs to call a local process on the machine,
00:10:58.140 --> 00:11:03.240
like an encoder or a specific executable or something like that.
00:11:03.240 --> 00:11:07.500
I mean, Python has a few ways of doing that in the standard library.
00:11:07.500 --> 00:11:08.880
There's subprocess.
00:11:08.880 --> 00:11:10.280
There's popen.
00:11:10.280 --> 00:11:14.260
There's in the OS module.
00:11:14.260 --> 00:11:15.000
There's another way.
00:11:15.700 --> 00:11:25.500
And there's many ways that similar to SQL injection, you can take an argument from somewhere and people can escape that argument and use it to run arbitrary commands on the server.
00:11:25.860 --> 00:11:28.320
So that's command injection or shell injection is called.
00:11:28.320 --> 00:11:29.920
That sounds a little bit bad.
00:11:29.920 --> 00:11:31.180
And that one actually was surprising to me.
00:11:31.180 --> 00:11:32.520
I wasn't super familiar with that.
00:11:32.520 --> 00:11:43.240
But if you're going to do popen and pass a string as the command to run, you could easily do dollar sign, dollar sign, next command or semicolon or whatever the separator your shell uses.
00:11:43.340 --> 00:11:49.940
Because you can issue commands that have multiple operations one after another in a single line, right?
00:11:50.060 --> 00:11:56.260
Yeah, so the most common example is somebody writing a, basically calling an executable and then giving it an argument.
00:11:56.260 --> 00:12:00.840
Let's say you want to create a thumbnail or encode an MP4 or something.
00:12:00.840 --> 00:12:07.380
Then you'd call a local process which does the encoding and you'd give it an argument which is the name of the file you want to encode.
00:12:07.380 --> 00:12:18.120
So that's straightforward, except that if instead of a file name, they close the quote and then they do a semicolon or an amphosand, amphosand, and then they can put in any other command they like.
00:12:18.120 --> 00:12:19.440
How could that be wrong?
00:12:19.440 --> 00:12:20.340
How could it go wrong?
00:12:20.340 --> 00:12:27.120
And it's funny because I shared this post and I saw some of the discussion forums, people arguing back saying, oh no, that's not a problem.
00:12:27.120 --> 00:12:29.720
Why, how could that possibly be a vulnerability?
00:12:29.720 --> 00:12:35.740
And even if you kind of like make it really obvious, people don't look at it like an attacker would look at it.
00:12:35.740 --> 00:12:38.160
They look at it like, oh, who would misuse that?
00:12:38.160 --> 00:12:38.780
How could that happen?
00:12:38.780 --> 00:12:39.180
Exactly.
00:12:39.180 --> 00:12:39.820
That's flexibility.
00:12:39.820 --> 00:12:40.420
It's good.
00:12:40.420 --> 00:12:41.320
It means good things.
00:12:41.320 --> 00:12:45.840
Yeah, and I think it's really interesting to have these two contrasts, not just SQL injection.
00:12:45.840 --> 00:12:54.920
And I was going to add too that there's, in addition to the escaping and stuff that Ant is talking about, there's additional things you can do here to protect yourself.
00:12:55.120 --> 00:13:00.500
So, for example, if you can run as the least privileged account you can.
00:13:00.500 --> 00:13:03.600
So, don't run as root or administrator, for example.
00:13:03.600 --> 00:13:11.440
So, if you do happen to have a bug in your application where someone can do command injection, you're going to minimize what it can do.
00:13:11.620 --> 00:13:15.740
So, there's multiple levels of ways you can protect yourself here as well.
00:13:15.740 --> 00:13:18.520
I think that's a really good point for a lot of this stuff, right?
00:13:18.520 --> 00:13:23.120
It's sort of security as layers, not the one big silver bullet, right?
00:13:23.120 --> 00:13:24.200
Yes, very much so.
00:13:24.200 --> 00:13:24.540
Yeah.
00:13:24.540 --> 00:13:29.360
The Python way around that is, well, first of all, avoid doing this if possible.
00:13:29.360 --> 00:13:35.040
I mean, there's many other ways of doing spawning processes and doing them correctly.
00:13:35.240 --> 00:13:45.280
But if you have to, if you need to escape the input, then use the shlex module, which is built into the standard library, and it has a utility function for escaping shell commands.
00:13:45.280 --> 00:13:45.680
Yeah.
00:13:45.680 --> 00:13:52.600
What I really like about your article, which I don't know if we've said it explicitly, it's 10 common security gotchas in Python and how to avoid them.
00:13:52.600 --> 00:13:54.440
And we'll put that in the show notes, of course.
00:13:54.640 --> 00:14:02.200
And for many of these, you have these, oh, did you know there's this other module you can just use that fixes this problem?
00:14:02.200 --> 00:14:08.480
So, that's, it's really nice that you have sort of some way to deal with this, not just like to put paranoia into people.
00:14:08.480 --> 00:14:15.360
This episode of Talk Python To Me is brought to you by Test and Code and the Python Bytes podcasts.
00:14:15.360 --> 00:14:19.380
If you love podcasts in Python, and you're listening to mine, so you must, right?
00:14:19.380 --> 00:14:22.840
Well, don't miss out on these two other great podcasts.
00:14:23.240 --> 00:14:30.980
If you're in a hurry and just want the headlines, get the rapid fire Python Bytes podcast that I co-host with Brian Okken over at pythonbytes.fm.
00:14:30.980 --> 00:14:47.440
Brian also hosts his own show, Test and Code, at testandcode.com, where he explores topics like test-driven development, continuous integration, code coverage, and pytest, of course, as well as agile development, mentoring, public speaking, and lots more in an opinionated mix of interviews and solo episodes.
00:14:47.440 --> 00:14:52.280
Keep up with the latest news and become a better developer by listening to Python Bytes and Test and Code.
00:14:52.840 --> 00:15:00.100
The next group of attacks are all related to deserializing or serializing data.
00:15:00.580 --> 00:15:08.040
And this is a pretty common vector where, let's say you're writing an application that reads configuration from somewhere.
00:15:08.040 --> 00:15:18.640
And that could be in YAML or JSON or XML, or it's receiving a message from somewhere, or you're basically using it as a way of communicating between different processes.
00:15:19.100 --> 00:15:20.520
There's different ways you can do that in Python.
00:15:20.520 --> 00:15:25.420
You could use XML, you could use JSON, you could use YAML, or you could use pickle files.
00:15:25.420 --> 00:15:30.560
So all four of those have massive gaping holes in them, which you could drive a bus through.
00:15:30.560 --> 00:15:34.960
So I kind of explained how you could abuse each one of them.
00:15:35.360 --> 00:15:39.140
I guess people might assume that XML is the safest.
00:15:39.140 --> 00:15:50.960
Yeah, it seems sort of old school, but XML can get complicated on the edges, you know, like weird namespaces and referring back to itself and other sorts of bizarre things that nobody ever does.
00:15:50.960 --> 00:15:51.280
Yeah.
00:15:51.280 --> 00:15:56.940
So the one I kind of explained was the billion, what's called the billion laughs exploit.
00:15:58.100 --> 00:15:58.720
It's funny.
00:15:58.720 --> 00:16:04.340
And it's, you know, look, if you're going to get like taken down, at least it should be a funny sort of hack, right?
00:16:04.340 --> 00:16:04.760
Come on.
00:16:04.760 --> 00:16:06.120
Got to appreciate it.
00:16:06.120 --> 00:16:19.600
So this is if you wanted to, if you received an XML payload from somewhere and an attacker has access to put their own XML in there, then basically XML has this thing called entity expansion.
00:16:19.600 --> 00:16:23.680
I guess the most similar way to think of it is a zip file.
00:16:24.520 --> 00:16:34.560
And what you could do, imagine you created a text file and it just contained spaces, lots and lots and lots of spaces, like let's say a million spaces.
00:16:34.560 --> 00:16:40.400
Now, if you compress that into zip, it compresses down to nothing because the way compression algorithms work.
00:16:40.400 --> 00:16:43.380
But when you extract it, it's like, oh, it's one character.
00:16:43.380 --> 00:16:44.320
Yeah, exactly.
00:16:44.320 --> 00:16:47.200
So it can condense down to pretty much nothing.
00:16:47.200 --> 00:16:53.600
Let's say you compress that into a zip file and then you made 10 of those, you copied it and you pasted it 10 times.
00:16:53.780 --> 00:16:58.980
And then you copied those 10 zip files and then added them to a zip file and then did that again and again and again.
00:16:58.980 --> 00:17:06.420
Now, what happens is if you extracted that zip file, it will go and sort of recursively extract the zips.
00:17:06.420 --> 00:17:13.420
And it can go from something like a one kilobyte zip file to gigabytes or potentially even worse.
00:17:13.900 --> 00:17:16.780
So the XML version, that's called a zip bomb.
00:17:17.020 --> 00:17:24.600
The XML version is a similar idea where in XML, you can have basically you can sort of reference things.
00:17:24.600 --> 00:17:29.900
And so in entity expansion, it can kind of reference something which references something.
00:17:29.900 --> 00:17:34.700
So it's similar to the zip bomb where you kind of create this tree and then it basically exponentially expands.
00:17:35.080 --> 00:17:40.940
So when you're trying to deserialize this special message in XML, it can take up gigabytes of RAM.
00:17:40.940 --> 00:17:44.420
So that is basically the exploit is that it just takes your server offline.
00:17:44.420 --> 00:17:48.400
And here it is fitting on one screen with word wrapping.
00:17:48.400 --> 00:17:48.760
Yeah.
00:17:48.760 --> 00:17:50.000
And it's like eight lines of XML.
00:17:50.000 --> 00:17:50.420
Yeah.
00:17:50.420 --> 00:17:54.100
It sort of teaches you that exponential stuff and like factorial type things.
00:17:54.100 --> 00:17:55.560
They get big fast.
00:17:55.680 --> 00:17:56.160
Yeah, exactly.
00:17:56.160 --> 00:17:57.900
So the XML one's pretty bad.
00:17:57.900 --> 00:18:01.640
There's some other pretty well-known ones with XML.
00:18:01.640 --> 00:18:06.440
So if you actually look at the standard library documentation for Python, and this is how I came across this.
00:18:06.440 --> 00:18:10.840
It does say in a big red box that there are known security challenges with XML.
00:18:10.840 --> 00:18:15.020
And you shouldn't deserialize arbitrary XML documents.
00:18:15.020 --> 00:18:18.100
Unless you do like soap web services, then what could go wrong?
00:18:18.100 --> 00:18:18.500
Exactly.
00:18:18.900 --> 00:18:26.300
So I guess the alternative is you can use a package called defused XML, which is a third party package.
00:18:26.300 --> 00:18:30.800
But it was actually written by Christian Himes, who's one of the core developers on Python.
00:18:30.800 --> 00:18:32.680
He's a security expert at Red Hat.
00:18:32.680 --> 00:18:37.340
So he kind of put together, I guess, a safer version of the XML standard library module.
00:18:37.340 --> 00:18:38.860
And it's a drop-in replacement.
00:18:38.860 --> 00:18:39.420
That's awesome.
00:18:39.420 --> 00:18:44.620
Does it just like not support these self-referential things and some of the other dangerous bits?
00:18:44.620 --> 00:18:46.000
It's like a limited XML?
00:18:46.000 --> 00:18:48.620
Stuff that it would be really unlikely you'd have to use anyway.
00:18:48.760 --> 00:18:48.920
Yeah.
00:18:48.920 --> 00:18:52.080
Anthony, as a network person, how do you think about these issues?
00:18:52.080 --> 00:18:55.260
Like, do you scan for these sorts of things?
00:18:55.260 --> 00:18:57.540
They keep me up at night?
00:18:57.540 --> 00:19:00.380
Look, there's a whole class of exploits with XML.
00:19:00.380 --> 00:19:06.260
There's exploits where you can embed schema information into there and do weird stuff with schema.
00:19:06.260 --> 00:19:12.740
I generally think that if you are going to handle XML, you generally whitelist what you accept.
00:19:12.740 --> 00:19:18.300
You define your own schema and say, if it doesn't match that schema first, I'm not going to parse it.
00:19:18.360 --> 00:19:20.460
I'm only going to parse minimal pieces of it.
00:19:20.460 --> 00:19:29.500
There's also, you can use what's called an XML external entity attack where you reference to a schema or an inclusion from somewhere else.
00:19:29.500 --> 00:19:31.720
And that somewhere else is relative to your server.
00:19:32.400 --> 00:19:41.580
So by getting you to upload a piece of XML, they can try to get your server to load something from your internal network and potentially display it back to the attacker.
00:19:41.580 --> 00:19:45.160
So XML can be used as a reconnaissance tool as well.
00:19:45.500 --> 00:19:52.360
It's not to say that XML is bad, but you have to follow the advice that is giving you now to use it properly and use it well.
00:19:52.360 --> 00:19:52.660
Yeah.
00:19:52.660 --> 00:19:55.460
Stay away from the dangerous bits unless you really need them.
00:19:55.460 --> 00:19:58.520
And it's rare these days, I think, that you need them.
00:19:58.600 --> 00:20:06.840
It seems like, you know, early 2000s, XML was supposed to be the answer to all the questions that involved any form of connectivity, right?
00:20:06.840 --> 00:20:10.720
Like we have all these fancy things with XML.
00:20:10.720 --> 00:20:13.940
We had all the hype around soap services.
00:20:14.200 --> 00:20:18.940
You have XSLT going wild being like the way to generate all sorts of stuff.
00:20:18.940 --> 00:20:23.380
And I feel like we've kind of moved on, but there's still plenty of XML processing around.
00:20:23.380 --> 00:20:24.800
XML has its place.
00:20:24.800 --> 00:20:29.360
It's a great metadata standard with a lot of bells and whistles attached.
00:20:29.360 --> 00:20:34.720
The problem is 90% of people don't need those bells and whistles, but it is what it is.
00:20:34.720 --> 00:20:36.280
Yeah, I guess I should knock XML.
00:20:36.280 --> 00:20:41.200
I mean, it is the main bit of traffic on some of my websites with the podcast RSS feed.
00:20:41.200 --> 00:20:42.800
That thing gets hammered.
00:20:43.460 --> 00:20:46.940
So I guess I should love XML, but that's the simple version.
00:20:46.940 --> 00:20:58.200
So another thing that you put in here that I thought was really interesting is people relying on assert to actually do runtime control.
00:20:58.200 --> 00:21:02.360
This one is pretty obscure, actually, and not that well known.
00:21:02.360 --> 00:21:06.200
And that is that there's effectively an optimizer.
00:21:06.200 --> 00:21:09.020
Well, there's a series of optimizations you can do in Python.
00:21:09.460 --> 00:21:13.200
And you can run Python in optimized mode, which does.
00:21:13.200 --> 00:21:22.240
I mean, if you look at the history of Python, basically what it tries to do is traverse the syntax tree and kind of make assumptions about how it should be executed.
00:21:22.240 --> 00:21:30.480
So that if you're doing it in production, it almost removes commands out of your code and skips them or looks at them differently.
00:21:30.940 --> 00:21:35.360
So this is things like constant crushing constants together, loop on folding.
00:21:35.840 --> 00:21:37.420
And there's a whole bunch of optimizations.
00:21:37.420 --> 00:21:43.580
One of those optimizations is to ignore assert statements because really they should be used for debugging.
00:21:43.580 --> 00:21:53.840
So if you're used to any other programming languages, so sometimes you can basically create like a debug assembly or a runtime assembly where they have debug symbols in one.
00:21:53.960 --> 00:22:01.980
And it's designed for production and another Python basically has that, but it's by adding an extra flag when you execute the Python file.
00:22:01.980 --> 00:22:06.720
So it skips certain commands depending on whether it's running an optimized mode or not.
00:22:06.720 --> 00:22:24.480
So if you use an assert statement to do things like checking that the password is right or checking that the user has the right amount of privileges or whatever, then basically it all runs fine in unit tests and integration tests because you never use optimized mode because you always want the assert statements.
00:22:24.800 --> 00:22:32.820
And then when you actually deploy it to production, someone says, oh, Python is quicker, like 10%, 20% quicker if we run it in optimized mode.
00:22:32.820 --> 00:22:39.000
They switch the flag on and all of your security catches and everything like that just disappear.
00:22:39.000 --> 00:22:39.600
Yeah.
00:22:39.600 --> 00:22:42.380
I mean, they could be totally sort of silent as well, right?
00:22:42.380 --> 00:22:47.240
If you were doing like containers, you could depend upon a Docker container and the base image could change in a way.
00:22:47.240 --> 00:22:48.680
They're like, yeah, we made it a little bit better.
00:22:48.680 --> 00:22:49.460
It's faster.
00:22:49.460 --> 00:22:50.500
Oh, great.
00:22:50.500 --> 00:22:51.120
I love faster.
00:22:51.120 --> 00:22:51.780
Let's do that.
00:22:51.780 --> 00:22:54.540
Wait, why can people be on this page again?
00:22:54.540 --> 00:22:55.240
This is terrible.
00:22:55.240 --> 00:22:56.580
Yeah, that's pretty scary.
00:22:56.580 --> 00:22:59.440
So the fix here is don't do that.
00:22:59.440 --> 00:23:01.520
It's like, doctor, it hurts when I raise my arm.
00:23:01.520 --> 00:23:02.380
Well, don't do that.
00:23:02.380 --> 00:23:04.700
Keep your arm down, basically.
00:23:04.700 --> 00:23:10.560
Like just use a if, you know, not admin, raise exception, permission error, or something like that, right?
00:23:10.560 --> 00:23:11.820
Yeah, typed exceptions.
00:23:11.820 --> 00:23:13.060
Yeah, exactly.
00:23:13.060 --> 00:23:14.860
Which is how it's supposed to be done anyway.
00:23:14.860 --> 00:23:15.380
Okay.
00:23:15.380 --> 00:23:23.900
Another one that's pretty interesting is not as common for the web because of the latency, but it's pretty interesting.
00:23:24.280 --> 00:23:24.840
Timing attacks.
00:23:24.840 --> 00:23:25.680
Tell us about those.
00:23:25.680 --> 00:23:26.960
Anthony, do you want to explain this one?
00:23:26.960 --> 00:23:31.420
So timing attacks, there's two really, two little buckets this falls into.
00:23:31.420 --> 00:23:38.280
One, if you're doing any form of security sensitive operation, like let's say, for example, you're checking a password is valid.
00:23:38.280 --> 00:23:49.540
The way a lot of code works is it might say, well, it will say, well, if the password is too short or too long, then don't bother checking the password, just fail out straight away.
00:23:49.840 --> 00:23:51.860
And an attacker can use this to work out.
00:23:51.860 --> 00:23:55.640
Well, what is a valid password to decrease the passwords it needs to check?
00:23:55.640 --> 00:23:56.080
I see.
00:23:56.080 --> 00:24:04.480
So if you're going to do like a dictionary attack and you realize, well, it's zero milliseconds for anything under seven characters, we'll start there.
00:24:04.680 --> 00:24:05.200
Exactly.
00:24:05.200 --> 00:24:05.320
Exactly.
00:24:05.320 --> 00:24:05.680
Exactly.
00:24:05.680 --> 00:24:05.680
Exactly.
00:24:05.680 --> 00:24:06.000
Exactly.
00:24:06.000 --> 00:24:16.080
So if you're doing particularly some cryptography, the idea is it's meant to have an approximately equal amount of time, irrespective of what input you give it.
00:24:16.560 --> 00:24:20.760
There's also another set of attacks around time of check, time of update.
00:24:20.760 --> 00:24:32.240
So if you're doing certain checks and then doing stuff that depends on those checks, make sure those checks are around the same time in code as they are that you're doing it.
00:24:32.240 --> 00:24:42.760
Because otherwise there is a gap between when you do that check, that security check, for example, and when you do that task or that operation that requires a result of that check, that can be exploited too.
00:24:43.020 --> 00:24:45.340
So there's kind of two areas here.
00:24:45.340 --> 00:24:46.580
That's pretty interesting.
00:24:46.580 --> 00:24:51.280
I hadn't really thought of the sort of information leakage around that.
00:24:51.280 --> 00:24:55.680
So I want to give a shout out to a Python package that I think just is really amazing.
00:24:55.680 --> 00:24:58.680
He talked about password checking and stuff called Passlib.
00:24:58.680 --> 00:25:00.340
Are either of you familiar with Passlib?
00:25:00.340 --> 00:25:00.920
No, I'm not.
00:25:00.920 --> 00:25:01.220
Yeah.
00:25:01.220 --> 00:25:11.260
So Passlib is really awesome because, you know, one of the bits of advice is to get a random salt and mix that in when you generate the password, right?
00:25:11.460 --> 00:25:13.240
Or when you hash and store the password.
00:25:13.240 --> 00:25:15.900
And then also make this computationally expensive to guess.
00:25:15.900 --> 00:25:21.580
So Passlib is like, there's like one function of like encrypt and one function like verify.
00:25:21.580 --> 00:25:30.660
And it will, you give it a plain text password and it will take that and it will fold it like 150,000 times with custom salt for that particular user.
00:25:31.060 --> 00:25:32.540
And then it can check it.
00:25:32.540 --> 00:25:37.680
But it takes like, you know, 0.2 seconds to determine whether it's right or wrong.
00:25:37.680 --> 00:25:39.500
It doesn't even just check the length.
00:25:39.500 --> 00:25:42.960
So it's a really nice way to sort of add a few more layers there.
00:25:42.960 --> 00:25:43.380
Yeah.
00:25:43.380 --> 00:25:48.500
So the other one I recommended was part of the standard library, but it was only added in 3.5.
00:25:48.960 --> 00:25:50.580
And that's a module called Secrets.
00:25:50.580 --> 00:25:57.780
And it has a method called Compare Digest where you can basically give it two values and it says, are they equal or not?
00:25:57.780 --> 00:26:03.100
So that's where you would say if the actual password equals equals the password the user entered.
00:26:03.620 --> 00:26:07.260
And statements like that are the type that can be left open to timing attacks.
00:26:07.260 --> 00:26:10.600
So Compare Digest basically makes it impossible to do that.
00:26:10.600 --> 00:26:11.460
Yeah, that's cool.
00:26:11.460 --> 00:26:20.220
So one piece of advice that I have around if you're doing anything like password management or any cryptography stuff, generally speaking, don't write it yourself.
00:26:20.220 --> 00:26:31.960
Use a library off the shelf that other people have used and vouched for because it's very easy to, if you do crypto wrong, it can be worse than having no crypto.
00:26:32.340 --> 00:26:36.240
Because for all the false assurances it will give you.
00:26:36.240 --> 00:26:36.500
Right.
00:26:36.500 --> 00:26:38.780
You think it's fine, but, you know, I don't understand.
00:26:38.780 --> 00:26:40.900
I base 64 encoded the password.
00:26:40.900 --> 00:26:42.620
They can't get that back out of the database.
00:26:42.620 --> 00:26:43.020
Come on.
00:26:43.020 --> 00:26:44.700
Of course not.
00:26:44.700 --> 00:26:45.160
Of course.
00:26:45.160 --> 00:26:46.040
Yeah.
00:26:46.040 --> 00:26:51.000
That pass level one that I talked about, by the way, they have like a list of all the support algorithms and the ones they recommend.
00:26:51.000 --> 00:26:52.720
And they're constantly checking them.
00:26:52.720 --> 00:26:55.540
So I think it's bcrypt and SHA-512 right now that they're using.
00:26:55.540 --> 00:26:58.080
It'll be bcrypt and probably the PBK-DF2.
00:26:58.080 --> 00:27:00.860
They're the two ones that people tend to recommend these days.
00:27:00.860 --> 00:27:01.340
So, yes.
00:27:01.340 --> 00:27:01.840
Yeah, nice.
00:27:02.080 --> 00:27:12.640
So one that I think is kind of scary because it's an exact opposite or in contrast to what makes Python awesome, right?
00:27:12.640 --> 00:27:15.220
Like, you know, import anti-gravity.
00:27:15.220 --> 00:27:20.980
It sort of captures the joy of Python where you just import anything and it's just there and it just works.
00:27:21.600 --> 00:27:26.480
But it's possible that you could have installed something bad, right?
00:27:26.480 --> 00:27:27.300
Yeah, absolutely.
00:27:27.300 --> 00:27:32.520
And I think not just install something bad, but the way that Python imports work.
00:27:33.160 --> 00:27:33.780
They're really flexible.
00:27:33.780 --> 00:27:34.540
They're really flexible.
00:27:34.540 --> 00:27:40.620
You can override all sorts of things, including system like almost language keywords.
00:27:40.620 --> 00:27:47.340
So you can override the print function or the assert statement or you can do all sorts of crazy things in imports.
00:27:47.500 --> 00:27:58.960
So I think one of the challenges with Python is that if you have a package somewhere in your site packages, basically an import path that does something malicious, it can be very difficult to detect that.
00:27:59.060 --> 00:28:03.100
And because your site packages is almost like a tier.
00:28:03.380 --> 00:28:07.560
So you've got like a system level one and then you might have a virtual environment one.
00:28:07.560 --> 00:28:13.180
And then maybe there's another one that you use as well where you might import stuff from somewhere else in your Python path.
00:28:13.180 --> 00:28:18.860
Then when you import something, you never actually know unless you go and check what it's imported.
00:28:18.860 --> 00:28:19.360
Yeah.
00:28:19.360 --> 00:28:24.460
And it could do really bad stuff like, you know, just while you're talking, I was thinking, OK, so I write a package.
00:28:24.460 --> 00:28:29.000
The import statement is effectively execute __init__.py.
00:28:29.660 --> 00:28:35.400
Maybe in that section, I'll see if I could go and find SQLAlchemy or some database connection.
00:28:35.400 --> 00:28:41.040
And then I'll monkey patch that over for the connect so I can grab your connection string and then pass it along.
00:28:41.040 --> 00:28:45.080
So you think your app is still working or, I mean, there's all sorts of nefarious stuff you could do, right?
00:28:45.080 --> 00:28:45.700
Yeah, exactly.
00:28:45.700 --> 00:28:55.980
And I think it's just people put a lot of trust in a pip install statement in terms of not only what package they installed, but what dependencies that package had.
00:28:56.340 --> 00:29:03.980
And what dependencies their dependencies had and what ended up getting installed and whether any of those have actually polluted your site packages.
00:29:03.980 --> 00:29:11.020
So basically, if you're importing even a standard library module, like, is that has something else overloaded that?
00:29:11.020 --> 00:29:14.620
And is that import basically changing your global namespace?
00:29:17.820 --> 00:29:21.120
This portion of Talk Python To Me is brought to you by us.
00:29:21.120 --> 00:29:27.060
Over at Talk Python Training, we're building out our library courses, and that library is growing each month.
00:29:27.060 --> 00:29:30.560
That's why I want to take a moment and tell you about a special offer we have.
00:29:30.560 --> 00:29:32.280
It's called the Everything Bundle.
00:29:32.280 --> 00:29:34.460
With it, you get, well, everything.
00:29:34.460 --> 00:29:38.940
Every course we have in our library, including the ones yet to be published this calendar year.
00:29:38.940 --> 00:29:43.620
Many online training companies have subscriptions and discounts if you buy them a year at a time.
00:29:43.620 --> 00:29:47.120
Our Everything Bundle is like a subscription, but it's way better.
00:29:47.440 --> 00:29:51.460
With subscriptions, the moment you stop paying, you lose access to everything.
00:29:51.460 --> 00:29:55.360
With our Everything Bundle, you keep access to our courses forever.
00:29:55.360 --> 00:30:01.380
Any course published the year you bought the bundle or sooner is indefinitely yours, even if you never renew.
00:30:01.380 --> 00:30:04.940
Check out what's available at training.talkpython.fm.
00:30:04.940 --> 00:30:11.320
And if you're looking for a way to support the podcast, taking or recommending one of our courses is the very best way to do this.
00:30:11.760 --> 00:30:12.260
Thank you.
00:30:12.260 --> 00:30:25.160
That sort of hints at a really scary scenario because I'm pretty careful what I install, but I don't go and check the dependencies of everything that it depends upon before I use it.
00:30:25.220 --> 00:30:27.060
I'm like, yeah, this looks like a reputable package.
00:30:27.060 --> 00:30:28.580
I'll go ahead and use it.
00:30:29.160 --> 00:30:34.380
But it hints at almost like a supply chain challenge in that.
00:30:34.540 --> 00:30:40.560
Imagine I find some not very popular package that something popular is based upon.
00:30:40.560 --> 00:30:46.280
And then I go do a PR that sneaks in some extra sneaky dependency.
00:30:46.280 --> 00:30:48.720
That is actually the problem that people don't realize.
00:30:48.720 --> 00:30:52.060
And so when that gets pushed out to be updated, you update your thing.
00:30:52.640 --> 00:30:57.460
All of a sudden, you're indirectly pulling in this thing because some guy was like, yeah, it looks like a good PR.
00:30:57.460 --> 00:30:59.320
I'm busy, but we'll take it anyway.
00:30:59.320 --> 00:30:59.680
Go ahead.
00:30:59.680 --> 00:31:00.640
Yeah, it certainly can be.
00:31:00.640 --> 00:31:02.960
So, well, there isn't really one.
00:31:02.960 --> 00:31:04.640
Again, like the doctor.
00:31:04.640 --> 00:31:05.160
Don't do that.
00:31:05.160 --> 00:31:06.380
It hurts when I do this.
00:31:06.380 --> 00:31:06.920
Don't do that.
00:31:06.920 --> 00:31:11.240
Well, you do reference a service that I'm a fan of.
00:31:11.240 --> 00:31:12.180
So tell people about it.
00:31:12.180 --> 00:31:21.940
Yeah, so pyup.io basically has a sort of a database of packages and versions of those packages which have known vulnerabilities.
00:31:21.940 --> 00:31:34.260
So this links to one of the other things I put in the article, which was not patching your dependencies, which is a pretty common pattern where people say, okay, I'm going to get all my dependencies and then I'm going to do pip freeze or something.
00:31:34.260 --> 00:31:37.380
And I'm going to put that into my requirements.txt file.
00:31:37.560 --> 00:31:44.440
So I've basically pinned which versions do I know work and no one ever touched that file.
00:31:44.440 --> 00:31:48.820
So like that's probably one of the scariest things, as you said, here's all the versions.
00:31:48.820 --> 00:31:50.560
These are the ones we tested with.
00:31:50.560 --> 00:31:57.500
But no one goes and checks each packages or each dependencies website and sees the notification that says, oh, yeah, sorry.
00:31:57.500 --> 00:32:01.380
There's a massive security hole in version 2.9.6.
00:32:01.380 --> 00:32:03.640
Please update to 2.9.7.
00:32:03.640 --> 00:32:07.160
And it's the dependency, maybe the dependency of your dependencies thing.
00:32:07.300 --> 00:32:12.160
Like even if you were crazy diligent and you went and checked all the stuff you installed, that's not even enough.
00:32:12.160 --> 00:32:13.180
Yeah, exactly.
00:32:13.180 --> 00:32:22.780
So pyup.io basically has a database, a freely available database where you can look up bad versions of packages that exist on PyPI.
00:32:22.780 --> 00:32:29.820
And they have a service where they can actually go and scan your requirements.txt if it's on a GitHub repository.
00:32:29.820 --> 00:32:33.400
Or they have hooks where you can use it with other services like GitLab.
00:32:33.880 --> 00:32:39.760
And if they basically say that there are newer versions available or this is a bad version, then they'll give you a notification.
00:32:39.760 --> 00:32:43.040
So I guess that's one of the better ways of approaching the problem.
00:32:43.040 --> 00:32:48.600
And this is probably the point in my article that got the most negative feedback from people.
00:32:48.600 --> 00:32:50.800
They said, oh, of course, you have to pin dependencies.
00:32:50.800 --> 00:32:54.980
Like, you know, you can't just willy nilly install the latest version.
00:32:55.640 --> 00:32:58.180
But pyup does it does have version ranges.
00:32:58.180 --> 00:33:00.020
There's a there's a PEP for that.
00:33:00.020 --> 00:33:03.100
So you can say, you know, I want this minor version.
00:33:03.100 --> 00:33:06.980
So I want version 2.8 up to 2.9.
00:33:07.220 --> 00:33:12.920
And then if they release a 2.8.1 or 2.8.2, then you'll automatically install the right version.
00:33:12.920 --> 00:33:18.440
And if you hope that people use semantic versioning, the API itself and the functionality shouldn't have changed.
00:33:18.440 --> 00:33:20.880
And of course, you've got good test coverage anyway.
00:33:20.880 --> 00:33:21.860
So you'll catch it.
00:33:21.860 --> 00:33:22.840
That's a really good point.
00:33:22.840 --> 00:33:25.540
The problem is pip freeze doesn't do that.
00:33:25.540 --> 00:33:26.200
Right.
00:33:26.240 --> 00:33:28.600
And that becomes a ton of work on your side of things.
00:33:28.600 --> 00:33:30.100
I use pyup for my stuff.
00:33:30.100 --> 00:33:33.360
Like so the training website, the various podcast websites and a few other things.
00:33:33.360 --> 00:33:37.660
I have it hooked up and I will get weekly pull requests.
00:33:37.660 --> 00:33:42.100
These three packages have changed and they could be like deep dependencies.
00:33:42.100 --> 00:33:43.540
Here's their change log.
00:33:43.540 --> 00:33:44.640
Here's here's the new version.
00:33:44.640 --> 00:33:49.440
And there's just a PR which patches the frozen packages in my requirements at TXT.
00:33:49.440 --> 00:33:50.740
It's really nice.
00:33:50.740 --> 00:33:52.520
Anthony, how do you think about this?
00:33:52.520 --> 00:33:52.740
Yeah.
00:33:52.820 --> 00:33:59.380
So one thing I was going to add is that you can never predict when a package that you thought was good may turn bad.
00:33:59.380 --> 00:34:02.720
People might write a package and think, yeah, this version is great.
00:34:02.720 --> 00:34:04.960
And then someone somewhere finds an issue with it.
00:34:04.960 --> 00:34:10.380
So the key here is a regular monitoring of what you're doing and a regular patch cycle.
00:34:10.380 --> 00:34:13.020
Because you said you never know when something's going to happen.
00:34:13.020 --> 00:34:14.740
So you need to make sure you're looking for it.
00:34:14.740 --> 00:34:17.660
And that turnaround time is as short as possible.
00:34:17.660 --> 00:34:20.340
So the focus here is more on your operations.
00:34:20.580 --> 00:34:23.880
How do you manage your system as opposed to necessarily how you program it?
00:34:23.880 --> 00:34:25.340
But nevertheless, that's important.
00:34:25.340 --> 00:34:25.660
Yeah.
00:34:25.660 --> 00:34:31.200
I think another step there is you have to proactively be applying these changes.
00:34:31.200 --> 00:34:33.280
It's one thing to notice there's a problem.
00:34:33.280 --> 00:34:41.060
It's another to notice that PyUp sent me a PR that says, oh, you're depending on this version of, you know, a JSON parser or something.
00:34:41.060 --> 00:34:42.240
And it has this vulnerability.
00:34:42.240 --> 00:34:43.080
You need to fix it.
00:34:43.640 --> 00:34:47.040
It's another to go, yeah, and now I'm patching the server.
00:34:47.040 --> 00:34:50.400
You think, look at, what was it, Experian?
00:34:50.400 --> 00:34:51.180
Right?
00:34:51.180 --> 00:34:54.120
They were hacked with a known vulnerability.
00:34:54.120 --> 00:34:56.400
It was, everybody said, this is ultra bad.
00:34:56.400 --> 00:34:59.760
You need to drop what you're doing, skip lunch and go fix it.
00:34:59.760 --> 00:35:02.060
And it's just, well, we work at this big company.
00:35:02.540 --> 00:35:06.600
We can't be bothered to change this because if it breaks, this is not my site.
00:35:06.600 --> 00:35:09.440
But if I break it trying to fix it, I'm losing my weekend.
00:35:09.440 --> 00:35:11.780
So I'll let someone else deal with that on Monday when they get in.
00:35:11.780 --> 00:35:17.240
And then, you know, 143 million people lose all their credit and personal banking details, me included.
00:35:17.240 --> 00:35:18.600
Ouch.
00:35:18.860 --> 00:35:19.000
Yeah.
00:35:19.000 --> 00:35:20.300
But I mean, what are you going to do, right?
00:35:20.300 --> 00:35:23.660
I think there's like another layer that goes on top of this.
00:35:23.660 --> 00:35:24.520
Like you have to act.
00:35:24.520 --> 00:35:24.900
Yes.
00:35:24.900 --> 00:35:25.240
Yes.
00:35:25.240 --> 00:35:30.360
I mean, it's a patch management aspect of your server maintenance or system maintenance.
00:35:30.360 --> 00:35:36.420
I mean, as Ant said, there's tools inside Python, but you need to use them and you need to be using them regularly.
00:35:36.420 --> 00:35:39.900
You need to have that, you know, I do need to fix it now.
00:35:39.900 --> 00:35:43.980
So how do I, how do I decrease that turnaround time to as small as possible?
00:35:43.980 --> 00:35:44.440
Yeah.
00:35:44.440 --> 00:35:44.880
Yeah.
00:35:44.880 --> 00:35:45.000
Yeah.
00:35:45.000 --> 00:35:48.600
And what do you think about speed to actually deploying the fix?
00:35:48.780 --> 00:35:54.600
Like, are there like continuous delivery bits of magic that you people would be willing to rely upon?
00:35:54.600 --> 00:35:56.780
Like it says massive security vulnerability.
00:35:56.780 --> 00:36:00.000
We will let it automatically publish this if the test pass.
00:36:00.000 --> 00:36:00.800
I'm not sure.
00:36:00.800 --> 00:36:04.980
I mean, if your test passed, it still needs to go through some sort of UAT.
00:36:04.980 --> 00:36:08.780
It depends, I guess, on the, it depends on the project and depends on what it's for.
00:36:08.780 --> 00:36:17.740
Like if it's a, if it's an internal web application, then, you know, it's unlikely, but you also want to make sure that thing gets patched and updated as quickly as possible.
00:36:18.700 --> 00:36:24.820
The cost of, the cost of, the cost of downtime is one thing, probably smaller than the cost of attack or the cost of compromise.
00:36:25.220 --> 00:36:28.300
So I guess it's a, it's a, it's a kind of looking at it from the angle.
00:36:28.300 --> 00:36:39.680
Another thing I guess I want to talk about is that the way that you as a developer talk to operations, assuming you, you have an operations team that you're talking to, and that's not just another hat you have to wear.
00:36:40.540 --> 00:36:47.800
And the way you talk about what versions of the dependencies your, your package depends on and how brittle that is.
00:36:47.900 --> 00:36:51.820
Cause something I've heard a lot is people say, never know, don't touch my dependencies.
00:36:51.820 --> 00:36:54.500
Cause I know that they work and it was probably going to break the code.
00:36:54.740 --> 00:37:00.260
So from an ops, you know, angle, they're like, well, we're going to look after all the system.
00:37:01.260 --> 00:37:06.880
And then we're going to look after all the stuff that's, you know, dev have told us not to touch that and to leave it alone.
00:37:06.880 --> 00:37:08.360
Otherwise it's all going to go really bad.
00:37:08.820 --> 00:37:17.780
And if, if they touch it and they try and patch something, then the dev team's going to be like, oh, well, you know, you've, you've been changing the code and you've changed the dependencies and we didn't ask you to do that.
00:37:17.780 --> 00:37:18.900
And that's why it's breaking.
00:37:18.900 --> 00:37:26.820
So I guess it's, it's a conversation between the two teams or if you've got DevOps and then having a conversation about how you try and automate some of that stuff.
00:37:26.820 --> 00:37:27.120
Yeah.
00:37:27.120 --> 00:37:28.300
The more automation, the better.
00:37:28.300 --> 00:37:31.540
So the next one that you have on your article was surprising to me.
00:37:31.540 --> 00:37:34.020
I didn't really think about it, but I guess it makes sense.
00:37:34.020 --> 00:37:35.160
Is it temporary files?
00:37:35.160 --> 00:37:35.880
Yeah.
00:37:36.220 --> 00:37:43.280
I'm lucky enough not to have to use those very much in most of the stuff I write these days, but they're actually very common vulnerabilities.
00:37:43.280 --> 00:37:46.940
So apparently there's a MK temp function that'll generate a temp file.
00:37:46.940 --> 00:37:47.920
I didn't even know about this.
00:37:47.920 --> 00:37:49.940
I don't use temp files very much either, I guess.
00:37:49.940 --> 00:37:50.300
Yeah.
00:37:50.300 --> 00:37:51.520
It's a, it's an old one.
00:37:51.520 --> 00:37:56.360
And I came across this when I was doing building the course for moving from Python two to Python three.
00:37:56.360 --> 00:38:04.360
Cause one of the recommendations is that you don't use the Python two functions for creating temporary files because they have known security issues in them.
00:38:04.660 --> 00:38:06.620
So kind of digging into that a bit deeper.
00:38:06.620 --> 00:38:10.220
So there's a temp file module, which is the one that you should use.
00:38:10.220 --> 00:38:15.820
And there's a function called MKSTemp, which you should use to generate temporary files.
00:38:15.820 --> 00:38:16.600
Is that for secure?
00:38:16.600 --> 00:38:18.320
I'm pretty sure S stands for secure.
00:38:18.320 --> 00:38:18.580
Yeah.
00:38:18.580 --> 00:38:20.080
Nice.
00:38:20.080 --> 00:38:20.460
Okay.
00:38:20.640 --> 00:38:30.280
So the problem is there could be timing attacks or if you hit the time, just right, like you could create the temp file and then you could swap out the data before they read it or other bad things like that.
00:38:30.280 --> 00:38:30.500
Right?
00:38:30.500 --> 00:38:31.080
Exactly.
00:38:31.080 --> 00:38:37.980
So the reason the old one is bad is because it will create the file first and then it will open and load the file.
00:38:38.520 --> 00:38:44.220
So what can happen is someone can sit there scanning the file directory, the temporary file directory.
00:38:44.220 --> 00:38:47.620
An attacker can basically sit there looking at it constantly.
00:38:47.620 --> 00:38:54.940
And as soon as they see a file pop up, so the file handle is being created, then they can go and dump a load of data in there.
00:38:55.040 --> 00:38:58.080
And then you open it and then it's all changed.
00:38:58.080 --> 00:39:01.160
Like basically it's a way of them injecting data into your application.
00:39:01.160 --> 00:39:01.620
Yeah.
00:39:01.620 --> 00:39:02.440
That sounds bad.
00:39:02.440 --> 00:39:09.220
So another one, you kind of touched on this before is parsing other file types can be really bad.
00:39:09.220 --> 00:39:16.480
And I kind of riffed on XML being bad because it was old and complicated, but YAML is kind of new and awesome.
00:39:16.480 --> 00:39:17.900
That probably is bad, right?
00:39:17.900 --> 00:39:28.140
You know, this YAML one is so really hardly anybody knows that you can do this because when you look at the example, you think, why would they allow that to happen?
00:39:28.140 --> 00:39:29.140
Wait, hold on, hold on.
00:39:29.140 --> 00:39:36.740
I think exactly like maybe you shouldn't tell anybody about this because you're going to tell people they could do it as much as to protect themselves against it.
00:39:36.740 --> 00:39:37.180
Exactly.
00:39:37.180 --> 00:39:38.440
No, I'm just kidding.
00:39:38.440 --> 00:39:38.740
Go ahead.
00:39:38.740 --> 00:39:39.120
Tell everyone.
00:39:39.120 --> 00:39:50.520
So I guess the most popular package for reading and writing YAML files is called PyYAML and it has a method called YAML.load or YAML.loads.
00:39:50.520 --> 00:40:05.160
And if you actually read the documentation, it says in big letters, warning, YAML.load is not safe, essentially, because you can run any Python function by putting special characters in the YAML file.
00:40:05.160 --> 00:40:17.160
Yeah, like exclamation, exclamation, Python object apply, OS.sys, you know, some form of like Python code or calling some sort of sub process or all sorts of bad things.
00:40:17.160 --> 00:40:22.860
Like that's incredible that you can do that, that you can just say, shall execute this in my YAML file.
00:40:22.860 --> 00:40:34.160
So you can basically put a special, it's like two exclamation points and then a special path and then the name of the function in the standard library that you want to execute and the parameters.
00:40:34.700 --> 00:40:43.900
And then if you call YAML.load and the YAML text or the YAML file has that basically the special syntax in it, it will just execute that locally.
00:40:43.900 --> 00:40:54.120
So you can imagine like if you had a web application where you were asking people to provide some simple YAML input to describe something or you were loading something to configure something.
00:40:54.500 --> 00:41:01.540
I mean, an example that I used in there was, you know, I use YAML a lot with Ansible, which is like a network automation tool.
00:41:01.540 --> 00:41:03.380
And they had a, they had the vulnerability.
00:41:03.380 --> 00:41:09.680
They had the same vulnerability because in that product called Ansible Vault, they were loading it using YAML.load.
00:41:09.680 --> 00:41:11.440
And people are like, oh, awesome.
00:41:11.440 --> 00:41:15.500
I can just like pop a shell on this box instead of providing a password.
00:41:16.500 --> 00:41:18.620
That seems amazing.
00:41:18.620 --> 00:41:22.700
Anthony, do you use Ansible or work with YAML and worry about these things?
00:41:22.700 --> 00:41:23.180
Yes.
00:41:23.180 --> 00:41:37.980
I mean, this is, this is a perfect example of something that really, it's like for those, if any of your listeners are familiar with JavaScript, you used to have the eval that used to run to load in JSON, but they changed that to parse because eval was inherently unsafe.
00:41:38.240 --> 00:41:45.400
And this is an example of a function, which is just, it just goes on the, on the, on the do not use list for anything that is serious, right?
00:41:45.400 --> 00:41:46.420
You just don't use it.
00:41:46.420 --> 00:41:54.680
If there's no equivalent on it, then, then we look at something, something else because there's an, unless we go and rewrite it, there's, there's no workaround.
00:41:54.680 --> 00:41:59.580
It's basically like giving people like just dollar prompt access, like type here.
00:41:59.580 --> 00:42:00.780
What do you want to do on the server?
00:42:00.780 --> 00:42:01.320
Exactly.
00:42:01.320 --> 00:42:01.800
Exactly.
00:42:01.800 --> 00:42:03.540
To be honest with you, this is one of those things.
00:42:03.540 --> 00:42:06.880
When I read something like this, the first thing in my head is what were they thinking?
00:42:07.820 --> 00:42:08.900
I am with you.
00:42:08.900 --> 00:42:09.400
So first.
00:42:09.400 --> 00:42:10.220
Yeah.
00:42:10.220 --> 00:42:11.500
So, and tell us the fix.
00:42:11.500 --> 00:42:12.400
What is your fix here?
00:42:12.400 --> 00:42:12.880
Okay.
00:42:12.880 --> 00:42:18.760
So there's two fixes and I only found out about the second one yesterday and I think it might have something to do with this article.
00:42:18.760 --> 00:42:24.960
The first fix is that you don't use load, use safe underscore load, which.
00:42:24.960 --> 00:42:25.740
Of course.
00:42:25.740 --> 00:42:26.340
Of course.
00:42:26.340 --> 00:42:36.880
So in the same way that you have to use MKSTemp instead of MKTemp, you should use, however, I guess, explicitly saying you want to do things safely is a bit of an anti-pattern.
00:42:37.400 --> 00:42:44.580
So I did see there was a pull request which has been merged into PyYAML to make the safe version the default.
00:42:44.580 --> 00:42:47.900
And you have to explicitly ask for the unsafe version.
00:42:47.900 --> 00:42:53.060
However, I think that's only been merged in the most recent version of 4.1.
00:42:53.280 --> 00:42:59.320
And then if you ignore all of our prior advice about updating your pip dependencies, then you're never going to see that anyway.
00:42:59.320 --> 00:43:01.520
These do interplay, don't they?
00:43:01.780 --> 00:43:10.940
So I was definitely thinking of that API design sort of experience and like, wait, load and then the safe unload is what you're really supposed to do some of the time.
00:43:10.940 --> 00:43:16.400
Like, this does not help people fall into the pit of success, right?
00:43:16.400 --> 00:43:24.360
Like, to me, it seems like if you don't know what you're doing, it should default or just lead you down the path of, well, do the safe one.
00:43:24.420 --> 00:43:29.040
And if they need the crazy, you know, run this shell thing, like, make them hunt for that.
00:43:29.040 --> 00:43:31.700
Don't make that the default until they know better, right?
00:43:31.700 --> 00:43:34.380
Sounds like at least they've gotten that working now.
00:43:34.380 --> 00:43:35.080
Let go.
00:43:35.240 --> 00:43:35.840
Yeah, exactly.
00:43:35.840 --> 00:43:41.640
And I mean, the advice that I would give to anybody who is designing their own APIs is security by default.
00:43:41.640 --> 00:43:47.660
What you do, the most obvious way of doing things, the standard way of doing things should be the secure way.
00:43:47.660 --> 00:43:59.760
If you have features that are potentially unsafe, by all means, expose them that make the developer or the user specifically ask for it so they can accept and manage the risk.
00:43:59.760 --> 00:44:00.820
Yeah, that's perfect.
00:44:01.380 --> 00:44:10.040
One of the ones that I felt is kind of obvious on this list is obvious because I've been around for a while, I guess, is this concept of pickling.
00:44:10.040 --> 00:44:21.100
And pickling is the act of taking more or less a binary version of a Python object graph, putting it on disk, and then rehydrating it back into objects, right?
00:44:21.100 --> 00:44:31.340
Yeah, and it's typically used in sort of inter-process or inter-Python version communication or dumping an object somewhere and then loading it again somewhere else.
00:44:31.340 --> 00:44:34.420
And so it's kind of built into a standard library.
00:44:34.420 --> 00:44:35.980
It's been around for a while.
00:44:36.520 --> 00:44:46.060
And before things like JSON kind of became really popular, I guess it's one of the preferred ways of communicating or sharing data between Python processes.
00:44:46.060 --> 00:44:51.160
The problem is that it has a number of fairly well-documented security vulnerabilities.
00:44:51.160 --> 00:45:00.400
I mean, if you're loading up a pickle file, you can basically put things in the pickle file, which cause it to run any Python process.
00:45:00.400 --> 00:45:16.660
Like, if you basically create a new class and then you declare something called dunderreduce, then the contents of the dunderreduce method, if you return back a tuple, you can basically, the tuple that you return can be the name of a standard library function and its arguments.
00:45:16.660 --> 00:45:23.440
So basically, that's, again, where you do os.system or subprocess.popen, and you basically pass it all the arguments.
00:45:23.440 --> 00:45:31.860
So instead of loading this nice pickle file and you continuing with your day, basically, you load a pickle file and it just runs commands on your local machine.
00:45:31.860 --> 00:45:33.460
Yeah, that's not amazing.
00:45:33.460 --> 00:45:37.280
So, again, one of these sort of don't do this.
00:45:37.280 --> 00:45:42.220
It's extra hard to check, too, because the thing you're delivered is a binary blob.
00:45:42.220 --> 00:45:44.100
So how do you know whether it's safe or not?
00:45:44.100 --> 00:45:45.540
You can't even look at it.
00:45:45.540 --> 00:45:50.980
It's not even like the YAML file where you're like, wait, wait, wait, what is that double, double, double exclamation mark Python thing?
00:45:50.980 --> 00:45:51.780
That doesn't look right.
00:45:51.780 --> 00:45:52.600
Right.
00:45:52.600 --> 00:45:54.960
This is just, you know, one, zero, one, zero, zero, one.
00:45:54.960 --> 00:45:55.760
Seems okay.
00:45:55.760 --> 00:45:56.320
Yeah.
00:45:56.320 --> 00:46:04.660
So there's not really a workaround for this other than don't use pickle or don't try and unpickle things from an untrusted source.
00:46:04.660 --> 00:46:13.360
But then I don't even like saying that because it's that kind of assumption which attackers use for using attacks, combining them together.
00:46:13.360 --> 00:46:15.220
But Anthony knows a lot more about that than I do.
00:46:15.220 --> 00:46:16.500
Yeah, it's chaining them, right?
00:46:16.500 --> 00:46:20.600
It's like you lose one to get one layer in and then another and then another.
00:46:20.600 --> 00:46:20.880
Yeah.
00:46:20.880 --> 00:46:22.440
Ant's got a very good point.
00:46:22.440 --> 00:46:30.880
The way a lot of attackers compromise systems is they won't go after the top tier, the most important, the most visible ones.
00:46:30.880 --> 00:46:40.260
They'll try to look at maybe the second or third tier systems, ones that people may not have paid as much attention to or made as much effort securing.
00:46:40.260 --> 00:46:47.960
And if they can compromise those, they will use those as a foothold to go after things that people perceive as important.
00:46:48.600 --> 00:46:56.980
So if I compromise an app and it's communicating via pickles to other apps, for example, that can be how the exploit occurs.
00:46:57.340 --> 00:47:06.080
So it's good to keep in mind that every system you write has to consider security, as Ant is saying, and follow Ant's advice on looking at these 10 topics.
00:47:06.280 --> 00:47:18.080
Yeah, I mean, maybe this is some wimpy little app that's just like some reporting thing, but you could use it to get behind the firewall or maybe you could pickle some bad stuff into a shared Redis cache that then the other system might read.
00:47:18.080 --> 00:47:21.040
And then, you know, you just level up step by step, right?
00:47:21.040 --> 00:47:22.280
The so-called lateral movement.
00:47:22.280 --> 00:47:23.640
It is being recorded, you're right.
00:47:23.800 --> 00:47:24.740
Exactly, exactly.
00:47:24.740 --> 00:47:28.700
And look, three, four, five hops for the compromises is not unusual.
00:47:28.700 --> 00:47:33.700
And when you see it going, you realize how good some of these attackers actually are.
00:47:33.700 --> 00:47:34.600
But I digress.
00:47:34.600 --> 00:47:36.340
That's right.
00:47:36.340 --> 00:47:36.740
That's right.
00:47:36.740 --> 00:47:51.180
So I guess the last two kind of blend together a little bit in about not patching your Python runtime, sort of the main one, what you get if you just go to the open a shell and just type Python 3 or something, or your dependencies as well.
00:47:51.320 --> 00:47:58.440
And I heard that you don't really need to patch your Python runtime because there's zero days that sometimes appear in like your OS.
00:47:58.440 --> 00:48:00.520
So you can just like, this is not worth bothering with, right?
00:48:00.520 --> 00:48:04.280
What was that crazy comment was about?
00:48:04.280 --> 00:48:04.880
I can't remember.
00:48:04.880 --> 00:48:07.500
There was a comment on those lines.
00:48:07.500 --> 00:48:09.000
They were like, oh, but why do we bother?
00:48:09.000 --> 00:48:10.400
Why do we have to patch Python?
00:48:10.400 --> 00:48:11.940
Because they're probably just going to hack us anyway.
00:48:11.940 --> 00:48:12.700
So what's the point?
00:48:12.700 --> 00:48:13.300
If only.
00:48:13.300 --> 00:48:14.500
If only it worked that way.
00:48:14.500 --> 00:48:17.140
I think that's, I mean, we touched on that at the beginning a little bit.
00:48:17.140 --> 00:48:20.240
And that is sort of a sense of despair that people have.
00:48:20.240 --> 00:48:23.620
You're like, look, I could do all these things that I'm supposed to do.
00:48:23.620 --> 00:48:28.760
But soon as there's some sort of zero day or O day in my system, you know, all bets are off.
00:48:28.760 --> 00:48:31.120
I'm not going to be able to defend against that.
00:48:31.120 --> 00:48:35.900
I don't know what zero day there is in, you know, NGINX unit.
00:48:36.280 --> 00:48:37.500
And so forget it.
00:48:37.500 --> 00:48:39.000
I'm just not going to worry about security.
00:48:39.000 --> 00:48:41.320
And I can totally understand how people feel that way.
00:48:41.320 --> 00:48:53.960
But there was some interesting analysis and reports saying that even state sponsored actors of hackers and stuff primarily use super boring stuff, like all the things we've already been talking about, right?
00:48:54.000 --> 00:48:57.620
Like SQL injection and other boring unpatched things.
00:48:57.620 --> 00:48:59.540
I mean, zero days, yes, they happen.
00:48:59.540 --> 00:49:11.100
But as a proportion of total security incidents, they're actually relatively small, particularly for the well-known, well-trusted packages and products that are out there.
00:49:11.540 --> 00:49:17.740
I think this is one of those cases where people need to get their own house in order before they throw stones, if you know what I mean.
00:49:17.740 --> 00:49:18.980
Yeah, yeah.
00:49:19.120 --> 00:49:25.160
But I mean, once again, I mean, most of this stuff is relatively simple once you understand what you need to do.
00:49:25.160 --> 00:49:28.420
So it's just a question of putting time and effort into it.
00:49:28.420 --> 00:49:28.880
That's all.
00:49:28.880 --> 00:49:39.920
I think there's a difference between the NSA or some other country is trying to literally get into your thing or I'm on the Internet and people are rattling the doors to see if they're open.
00:49:39.920 --> 00:49:47.700
And they're not going to spend a full week trying to get into my system because they know there's thousands that just have SQL injection or some other random thing, right?
00:49:47.820 --> 00:49:56.480
Yeah, and look, to be honest with you, if the NSA really, really wants to get into your network, the version of the Python package you're using is probably the least of your problems at the moment.
00:49:56.480 --> 00:49:58.740
So...
00:49:58.740 --> 00:49:59.640
Yes, exactly.
00:49:59.640 --> 00:50:00.360
Exactly.
00:50:00.360 --> 00:50:03.380
Plenty scary, but we're not going to think too much about that, I guess.
00:50:03.380 --> 00:50:08.560
So what you're telling me is I need to install Python 3.7 because it just came out.
00:50:08.560 --> 00:50:09.140
Things like that.
00:50:09.140 --> 00:50:17.320
Yeah, I'd actually say, this is probably controversial, but I wouldn't install Python 3.7 until 3.7.0.1 comes out.
00:50:17.720 --> 00:50:19.340
Generally, I'd...
00:50:19.340 --> 00:50:19.980
Yeah, yeah, sure.
00:50:19.980 --> 00:50:26.040
But maybe, Pat, like if there were like 3.6.6 or 3.6.7, whatever the next one there is.
00:50:26.040 --> 00:50:27.100
3.6.6, yeah.
00:50:27.100 --> 00:50:28.460
I'd go with 3.6.6.
00:50:28.460 --> 00:50:30.600
But it's part of that staying on top of things.
00:50:30.600 --> 00:50:38.460
I wish PyUp actually had a check to say your Python version is 3.6.6 and it should be 3.6.7 or something like that.
00:50:38.460 --> 00:50:41.860
There is another tool, which is open source as well, called InSpec.
00:50:41.860 --> 00:50:45.580
And it's made by the same people that brought you Chef.
00:50:46.040 --> 00:50:51.780
So it's built in Ruby, but it does actually have a bunch of hooks for Python applications.
00:50:51.780 --> 00:50:58.320
And I know that it does do virtual environments and also checking versions of packages in production.
00:50:58.320 --> 00:51:02.800
So you can say, make sure that none of our servers in production have this version of Python.
00:51:03.660 --> 00:51:06.480
Make sure that they don't have these versions of these packages as well.
00:51:06.480 --> 00:51:11.900
And you can do that in InSpec and basically declaratively saying, here's our security rules.
00:51:11.900 --> 00:51:17.840
And it will go and scan through your installations for you or your service for you and actually give you back a report.
00:51:17.840 --> 00:51:21.740
So InSpec, I guess, would be the way to do it or a tool like that.
00:51:21.860 --> 00:51:22.720
Yeah, that makes a lot of sense.
00:51:22.720 --> 00:51:23.960
All right.
00:51:23.960 --> 00:51:28.140
Well, I think hopefully people learned a lot from those 10 items.
00:51:28.140 --> 00:51:32.260
I mean, there's certainly a couple of them that I had heard of, but others were new to me.
00:51:32.260 --> 00:51:34.540
And it's always good to be aware of these things.
00:51:34.540 --> 00:51:37.080
So thanks for putting that together and both of you for sharing it here.
00:51:37.080 --> 00:51:42.980
So Anthony, how do I sell this to my, you know, I work at a startup.
00:51:42.980 --> 00:51:45.580
The management just got VC funding.
00:51:45.580 --> 00:51:47.320
We're supposed to do growth, growth, growth.
00:51:47.320 --> 00:51:51.580
We're trying to figure out new features so that we get this thing to get out.
00:51:51.580 --> 00:51:53.660
How do we get ourselves to worry about this?
00:51:53.660 --> 00:51:58.800
So, well, the first thing is to understand any legal or contractual obligations that you have.
00:51:58.800 --> 00:52:04.440
So if you're in Europe, for example, you have to follow the GDPR, the new general data protection
00:52:04.440 --> 00:52:05.660
regulation that's there.
00:52:05.660 --> 00:52:11.460
If you're handling credit cards, for example, you've got PCI DSS, the payment card industry
00:52:11.460 --> 00:52:12.940
data security standard.
00:52:12.940 --> 00:52:15.800
These are the non-negotiable things you have to do.
00:52:15.800 --> 00:52:21.200
The second thing is if you have any security executives or leaders in your organization,
00:52:21.200 --> 00:52:25.720
a CISO or if they have corporate policy, security policies need to follow.
00:52:25.720 --> 00:52:27.240
They're two things.
00:52:27.240 --> 00:52:29.660
But beyond that, one is just look at the newspaper.
00:52:29.660 --> 00:52:33.260
Reputational and financial damage is real.
00:52:33.260 --> 00:52:34.260
It happens.
00:52:34.260 --> 00:52:39.920
We've all seen or heard of companies that have been hacked and thinking, gee, I wish I weren't
00:52:39.920 --> 00:52:40.240
them.
00:52:40.240 --> 00:52:41.340
I wish I was not them.
00:52:41.340 --> 00:52:42.800
So don't.
00:52:42.800 --> 00:52:44.040
Don't be them.
00:52:44.040 --> 00:52:45.980
Exactly.
00:52:46.640 --> 00:52:49.420
Well, and also I think it comes to do with culture a little bit, right?
00:52:49.420 --> 00:52:56.100
Like if the culture is do not change this application, do not touch it, because if you break it, you're
00:52:56.100 --> 00:53:00.660
going to take it down some part of our business and we're going, it's going to be so bad that
00:53:00.660 --> 00:53:01.840
that thing ossifies.
00:53:01.840 --> 00:53:04.600
And it's basically like, no, it's kryptonite.
00:53:04.600 --> 00:53:05.500
Nobody wants to touch it.
00:53:05.500 --> 00:53:06.480
I'm going to stay away from that.
00:53:06.560 --> 00:53:10.420
Yeah, it probably is got some security issues, but I'm not touching it because I will be
00:53:10.420 --> 00:53:12.560
punished to no end if I'm the one who breaks it.
00:53:12.560 --> 00:53:14.300
I can see that happening a lot.
00:53:14.300 --> 00:53:14.740
Yeah, it is.
00:53:14.740 --> 00:53:20.400
And this comes down to your general culture around, as Ant said, test coverage, refactoring.
00:53:20.400 --> 00:53:25.060
If you have stuff that you can't touch, it's going to cause you security problems.
00:53:25.060 --> 00:53:28.940
If it's stuff that you can touch, you have a fighting chance of solving them.
00:53:29.220 --> 00:53:33.920
So that comes down to, once again, to the term that uses risk management here.
00:53:33.920 --> 00:53:37.640
Is your management happy to accept the risk that you're going to have an app that will
00:53:37.640 --> 00:53:38.720
eventually cause you a problem?
00:53:38.720 --> 00:53:39.100
Right.
00:53:39.100 --> 00:53:40.880
It's sort of the consequence of failure there.
00:53:40.880 --> 00:53:45.960
I mean, look at WannaCry and Windows XP on a lot of these things.
00:53:45.960 --> 00:53:48.140
There's so much damage from that, right?
00:53:48.140 --> 00:53:48.500
Yes.
00:53:48.500 --> 00:53:54.780
And particularly if you're in a small shop, if you're in a startup, reputation is big early
00:53:54.780 --> 00:53:55.040
on.
00:53:55.560 --> 00:53:59.740
So you need to make sure that you can maintain that trust that you're going to need from your
00:53:59.740 --> 00:54:00.660
first few customers.
00:54:00.660 --> 00:54:01.320
Yeah.
00:54:01.320 --> 00:54:06.160
And you probably have an advantage in the sense that you don't have big data centers with legacy
00:54:06.160 --> 00:54:07.100
machines laying around.
00:54:07.100 --> 00:54:10.540
You're probably on the cloud using modern tools because you just started.
00:54:10.540 --> 00:54:11.180
All right.
00:54:11.180 --> 00:54:14.620
Chances of keeping that upgrade train running is probably easier.
00:54:14.620 --> 00:54:15.220
Exactly.
00:54:15.220 --> 00:54:15.820
Exactly.
00:54:15.820 --> 00:54:16.940
It's all greenfield.
00:54:16.940 --> 00:54:18.940
You don't have to keep older stuff running.
00:54:18.940 --> 00:54:19.500
Exactly.
00:54:19.500 --> 00:54:20.060
Exactly.
00:54:20.060 --> 00:54:20.500
Yeah.
00:54:20.500 --> 00:54:21.600
All right.
00:54:21.600 --> 00:54:25.540
We're getting pretty short on time and I'll be respectful of both of your times, but maybe
00:54:25.540 --> 00:54:28.480
you could tell us really quick some places to learn more about security.
00:54:28.480 --> 00:54:29.020
Yeah.
00:54:29.020 --> 00:54:31.980
I guess one, two projects I want to call out.
00:54:31.980 --> 00:54:36.140
So there's a number of projects with the same kind of name that's related to goats.
00:54:36.140 --> 00:54:41.600
I'm not sure where the goat name came from originally, but basically there's a project called
00:54:41.600 --> 00:54:47.960
Web Goat, which was originally done as a how not to do things, open source project to basically
00:54:47.960 --> 00:54:51.780
include all of the top 10 most common vulnerabilities.
00:54:52.680 --> 00:54:56.800
And I can't remember what language it was written in, probably Pearl, but there's a Python version
00:54:56.800 --> 00:55:02.860
called PyGoat and there's a Django specific one called Djangoat, which I guess we'll have
00:55:02.860 --> 00:55:05.660
in the show notes.
00:55:05.660 --> 00:55:09.360
But if you actually look at that, it's got all the Djangoat ones really cool.
00:55:09.360 --> 00:55:13.640
It's got all the stuff you should never do with Django projects like leaving debug enabled,
00:55:13.640 --> 00:55:14.120
for example.
00:55:14.680 --> 00:55:19.160
But basically how to do the, all the kind of vulnerabilities we've talked about as well
00:55:19.160 --> 00:55:21.440
as the other ones in a project.
00:55:21.440 --> 00:55:23.600
So it's kind of like a how not to do things project.
00:55:23.600 --> 00:55:27.120
And I think it's good if you want to learn how things are done.
00:55:27.120 --> 00:55:30.860
And also it has instructions about how to break it, how to use those vulnerabilities.
00:55:31.360 --> 00:55:33.440
So I would start there.
00:55:33.440 --> 00:55:39.260
And then if you know them, then you can start doing things like doing scans through your source
00:55:39.260 --> 00:55:44.480
code for those particular types of vulnerabilities or those functions and seeing if you can find
00:55:44.480 --> 00:55:45.520
bugs in other places.
00:55:45.520 --> 00:55:46.820
Yeah, that makes a lot of sense.
00:55:46.820 --> 00:55:49.140
I really like this goat series.
00:55:49.140 --> 00:55:50.200
That's pretty interesting.
00:55:50.200 --> 00:55:55.100
One thing I want to give a quick shout out to that's in your neighborhood and is a podcast
00:55:55.100 --> 00:55:56.180
called Risky Business.
00:55:56.180 --> 00:55:56.740
Have you heard of it?
00:55:56.740 --> 00:55:57.640
I listen every week.
00:55:57.640 --> 00:55:58.180
Yeah, I love it.
00:55:58.180 --> 00:55:59.220
It's fabulous, man.
00:55:59.220 --> 00:56:00.840
Those guys do such a good job.
00:56:00.840 --> 00:56:05.820
It's like headline news in security and tech programming security.
00:56:05.820 --> 00:56:06.700
It's really great.
00:56:06.700 --> 00:56:10.660
And just listening to that, you learn a lot sort of by osmosis, I think.
00:56:10.660 --> 00:56:11.160
All right.
00:56:11.160 --> 00:56:13.340
Well, I think just we're out of time.
00:56:13.340 --> 00:56:16.400
We could go on and on and maybe we'll have to do another episode on this.
00:56:16.400 --> 00:56:18.960
But that was really helpful and insightful.
00:56:18.960 --> 00:56:19.880
So thank you both.
00:56:19.880 --> 00:56:23.280
Since there's two of you, I'm going to ask two questions at the end, but the same one.
00:56:23.280 --> 00:56:26.220
We'll just do the notable PyPI package.
00:56:26.220 --> 00:56:30.340
So is there a package, maybe related to security that people maybe haven't heard of,
00:56:30.340 --> 00:56:33.240
but you want to throw out there to let people know about it?
00:56:33.240 --> 00:56:34.300
Anthony, you want to go first?
00:56:34.300 --> 00:56:48.400
I had a couple, but if one of those things that I think rather than a package, I think people need to take a step back and realize that security is a mindset here in that there's no package that's going to make your app secure.
00:56:48.400 --> 00:56:51.360
So I'm going to twist the question a little bit here.
00:56:51.360 --> 00:56:57.420
It's about keeping abreast of what's going on and keeping current and continuing to learn.
00:56:57.420 --> 00:57:00.580
And it's an area that can be fascinating, can be really interesting.
00:57:00.580 --> 00:57:01.260
Yeah.
00:57:01.260 --> 00:57:01.660
Excellent.
00:57:01.660 --> 00:57:02.220
And?
00:57:02.440 --> 00:57:02.520
Yeah.
00:57:02.520 --> 00:57:08.000
This one hasn't actually been released yet, but Brian and I are working on a new pytest plugin called pytest Requests.
00:57:08.000 --> 00:57:12.420
And by the time this episode goes to air, it'll be out and it'll be wonderful.
00:57:12.420 --> 00:57:13.740
So I'd recommend you check it out.
00:57:13.740 --> 00:57:14.920
Oh, that sounds really fun.
00:57:14.920 --> 00:57:15.720
That's awesome.
00:57:15.720 --> 00:57:18.980
And also, I want to give a shout out to your Python 3.7 course.
00:57:18.980 --> 00:57:21.600
You just did a new course on Python 3.7.
00:57:21.600 --> 00:57:22.240
I thought it was great.
00:57:22.240 --> 00:57:22.620
Thanks.
00:57:22.820 --> 00:57:26.560
Yeah, that just came out just in time for the actual release of 3.7, which is good.
00:57:26.560 --> 00:57:29.340
Yeah, you beat the window by like a week or something.
00:57:29.340 --> 00:57:32.800
Maybe just tell people super quickly where they can get it and what it's about.
00:57:32.800 --> 00:57:34.240
So the course is on Pluralsight.
00:57:34.240 --> 00:57:38.720
If you have access to Pluralsight or you want to sign up for a trial, you should be able to watch the course.
00:57:38.720 --> 00:57:40.140
It's less than an hour.
00:57:40.140 --> 00:57:49.200
And I basically go through all the major new features in 3.7, how to use them, how they work, how to configure them, as well as some of the other benefits.
00:57:49.400 --> 00:57:54.460
So it'll take an hour of your time and you'll be a Python 3.7 expert by the end of it.
00:57:54.460 --> 00:57:58.320
But you should wait till Python 3.7.1 to actually get going, maybe?
00:57:58.320 --> 00:58:00.420
Probably, but that'll be weeks away, I reckon.
00:58:00.420 --> 00:58:01.300
I reckon, yeah.
00:58:01.300 --> 00:58:04.780
I already installed 3.7, but I have 3.6 on my machine just in case I need it.
00:58:04.780 --> 00:58:05.800
All right, awesome.
00:58:05.800 --> 00:58:06.640
Well, yeah, I enjoyed it.
00:58:06.640 --> 00:58:08.360
So good to let people know about that.
00:58:08.360 --> 00:58:10.400
All right, both of you, final call to action.
00:58:10.400 --> 00:58:13.500
People, maybe they're thinking about the software that they have.
00:58:13.500 --> 00:58:16.000
What's the first thing to do to start to address this?
00:58:16.000 --> 00:58:16.400
Anthony?
00:58:16.580 --> 00:58:22.440
The first thing is to take a step back and think, well, what is the most important things that my app is protecting?
00:58:22.440 --> 00:58:25.860
What are the most important business processes or data that's there?
00:58:25.860 --> 00:58:28.240
And to think, how can I protect it?
00:58:28.240 --> 00:58:29.540
How should I protect it?
00:58:29.540 --> 00:58:32.060
Is what I'm doing what I need to do?
00:58:32.060 --> 00:58:32.720
All right, excellent.
00:58:32.720 --> 00:58:34.360
Anthony, anything to throw in on that?
00:58:34.360 --> 00:58:46.840
Yeah, I'd say just don't be intimidated by security in general and just start simple and be willing to learn and also be willing to learn from people who have a lot more experience, of which there are plenty of people out there.
00:58:46.840 --> 00:58:50.500
Yeah, it's definitely a different way of thinking and it's pretty fascinating.
00:58:50.500 --> 00:58:53.360
All right, well, thank you both for being on the show and sharing all this stuff.
00:58:53.360 --> 00:58:53.760
It was great.
00:58:53.760 --> 00:58:54.300
Thanks, Mike.
00:58:54.300 --> 00:58:54.860
Thank you, Mike.
00:58:54.860 --> 00:58:55.400
Great to be here.
00:58:55.400 --> 00:58:55.960
Yeah, bye-bye.
00:58:55.960 --> 00:58:59.980
This has been another episode of Talk Python To Me.
00:58:59.980 --> 00:59:03.400
Our guests on this episode have been Anthony Shaw and Anthony Langsworth.
00:59:03.400 --> 00:59:08.780
And this episode has been brought to you by the Test and Code podcast as well as Talk Python Training.
00:59:09.460 --> 00:59:17.380
Keep up with the latest news and become a better developer by listening to Python Bytes at pythonbytes.fm and Test and Code at testandcode.com.
00:59:17.380 --> 00:59:19.160
Want to level up your Python?
00:59:19.160 --> 00:59:26.220
If you're just getting started, try my Python jumpstart by building 10 apps or our brand new 100 days of code in Python.
00:59:26.220 --> 00:59:30.020
And if you're interested in more than one course, be sure to check out the Everything Bundle.
00:59:30.020 --> 00:59:32.260
It's like a subscription that never expires.
00:59:32.260 --> 00:59:34.460
Be sure to subscribe to the show.
00:59:34.460 --> 00:59:36.660
Open your favorite podcatcher and search for Python.
00:59:36.660 --> 00:59:37.900
We should be right at the top.
00:59:37.900 --> 00:59:47.220
You can also find the iTunes feed at /itunes, Google Play feed at /play, and direct RSS feed at /rss on talkpython.fm.
00:59:47.220 --> 00:59:49.080
This is your host, Michael Kennedy.
00:59:49.080 --> 00:59:50.440
Thanks so much for listening.
00:59:50.440 --> 00:59:51.520
I really appreciate it.
00:59:51.520 --> 00:59:53.460
Now get out there and write some Python code.
00:59:53.460 --> 00:59:53.780
I'll see you next time.
00:59:53.780 --> 01:00:14.060
I'll see you next time.
00:00:00.001 --> 00:00:04.760
Do you write Python software that uses a network, opens files, or even accepts user input?
00:00:04.760 --> 00:00:10.280
Of course you do. That's what almost all software does. But these actions can let bad actors exploit
00:00:10.280 --> 00:00:14.980
mistakes and oversights we've made in our code that will allow them to compromise our systems.
00:00:14.980 --> 00:00:20.020
Python is safer than some languages, but there are plenty of issues to be careful of.
00:00:20.020 --> 00:00:25.760
That's why Anthony Shaw and Anthony Lingsworth are here to discuss Python security. This is
00:00:25.760 --> 00:00:30.340
Talk Python To Me, episode 168, recorded June 28th, 2018.
00:00:30.340 --> 00:00:49.380
Welcome to Talk Python To Me, a weekly podcast on Python, the language, the libraries, the ecosystem,
00:00:49.380 --> 00:00:54.140
and the personalities. This is your host, Michael Kennedy. Follow me on Twitter, where I'm at
00:00:54.140 --> 00:00:59.380
M. Kennedy. Keep up with the show and listen to past episodes at talkpython.fm, and follow the
00:00:59.380 --> 00:01:05.240
show on Twitter via at Talk Python. Anthony Shaw, Anthony Lingsworth, welcome to Talk Python.
00:01:05.240 --> 00:01:06.700
Hey, Michael. It's great to be back.
00:01:06.700 --> 00:01:08.600
Hey, Michael. Good to be my first time.
00:01:08.600 --> 00:01:14.760
Yeah, it's good to have you here. So we have a bit of a name conflict here. So Anthony Shaw's
00:01:14.760 --> 00:01:20.560
aunt, and Anthony Lingsworth is Anthony for the rest of the show. Hopefully that works for you all out
00:01:20.560 --> 00:01:25.780
there listening. And we're going to cover something that I think is often overlooked in Python,
00:01:25.780 --> 00:01:31.240
the whole security side of things, right? I mean, I feel like, well, there's no buffer overflow issues and
00:01:31.240 --> 00:01:34.020
things like that. So we must be just totally fine, right?
00:01:34.020 --> 00:01:38.260
No. If only that was the case. If only that was the case.
00:01:38.940 --> 00:01:44.860
Exactly. There's actually a ton of interesting vulnerabilities and things that are pretty common,
00:01:44.860 --> 00:01:49.600
I suspect, still in some circumstances that we're going to go through. But before we do,
00:01:49.600 --> 00:01:54.360
I'd like to hear your guys' story really quick. Anthony, how'd you get into programming in Python?
00:01:54.360 --> 00:01:58.580
I mainly got into programming Python through networking programming. One of my responsibilities
00:01:58.580 --> 00:02:04.160
here is interacting with a lot of Cisco and Juniper and other hardware, and Python is what they use.
00:02:04.160 --> 00:02:09.400
Right on. And Ant, you talked about getting started on Lib Cloud last time, right?
00:02:09.400 --> 00:02:14.740
Yeah, that was me. I was in Seattle and I got sick, and I was stuck in a hotel for the weekend,
00:02:14.740 --> 00:02:17.840
so I learned Python. I never looked back since then.
00:02:17.840 --> 00:02:23.960
Most people say, I got really sick, so I stayed in bed. Other people like you are like,
00:02:23.960 --> 00:02:26.780
oh, I learned a new programming language because I wasn't feeling well.
00:02:26.780 --> 00:02:27.580
I had nowhere to go.
00:02:27.580 --> 00:02:33.520
That's awesome. I totally get it. Let's start first talking about just security in general.
00:02:33.520 --> 00:02:38.620
Anthony, how do you think we should start thinking about security as software developers
00:02:38.620 --> 00:02:41.340
and people that run servers and stuff like that?
00:02:41.340 --> 00:02:46.700
What I tell people is when they start thinking about security, they have to invert how they think.
00:02:46.700 --> 00:02:52.980
Developers are very good at thinking, how do I build something quickly and that's designed well
00:02:52.980 --> 00:02:59.020
and that keeps my customers happy? Security is not like that. Security is how do I break something?
00:02:59.020 --> 00:03:03.120
How do I compromise something? How do I bend the rules?
00:03:03.120 --> 00:03:06.960
So you almost need a tester style thinking.
00:03:06.960 --> 00:03:12.640
So you look at what you've built and think, well, how do I make it do things it's not meant to do?
00:03:12.640 --> 00:03:15.920
I find there's just so much creativity in that.
00:03:15.920 --> 00:03:17.460
It's really hard to think about.
00:03:17.860 --> 00:03:23.700
And unless you see some examples of it in action, it's almost hard to conceptualize some of these things.
00:03:23.700 --> 00:03:30.380
Like I remember the first time I saw the actual code for a buffer overflow exploit.
00:03:30.380 --> 00:03:32.080
Here's how you overflow the buffer.
00:03:32.080 --> 00:03:34.660
Here's how you get it to execute those bits that you've dropped in.
00:03:34.660 --> 00:03:38.240
I'm just like, that is just, that's a different way of thinking, let's say.
00:03:38.240 --> 00:03:42.940
Yeah. I mean, as you say, some of the people who do this, they're really smart and they get really technical.
00:03:42.940 --> 00:03:47.680
But I also want to stress that a lot of this stuff is not rocket science.
00:03:47.680 --> 00:03:52.760
A lot of this is looking at what you do and just trying to keep that mindset.
00:03:52.760 --> 00:03:54.440
Yeah, I think that's a really good point.
00:03:54.440 --> 00:03:59.100
It's easy to get overwhelmed thinking, you know, this stuff is super advanced.
00:03:59.100 --> 00:04:07.640
But actually, 99% of the time, it's like, did you change the password from the default admin password on the database and stuff like that, right?
00:04:07.640 --> 00:04:10.540
That's where people usually start whacking on it, right?
00:04:10.540 --> 00:04:11.900
Exactly. Exactly.
00:04:11.900 --> 00:04:18.160
I mean, most people make a big deal about the super, super complex hacks out there.
00:04:18.160 --> 00:04:26.560
But if you talk to people like Kevin Mitnick and so on, a lot of the stuff they were doing is social engineering, which is just simple, as you say, password stuff or basic configurations.
00:04:26.980 --> 00:04:35.780
A lot of the times with security, if you get the basics right, the simple stuff right, the attackers will just go elsewhere because they're looking for the easiest exploit.
00:04:35.780 --> 00:04:38.120
Yeah, they're just rattling the door to see if it's open, right?
00:04:38.120 --> 00:04:38.740
Exactly.
00:04:38.740 --> 00:04:43.700
Yeah. And how about you? What are your thoughts on the sort of security thinking versus developer thinking?
00:04:43.700 --> 00:04:50.220
Yeah, I mean, I guess that probably the difference between Anthony and I, which is, I guess, confusing because we have the same name.
00:04:50.220 --> 00:04:55.380
Although we sound quite different, hopefully that'll be more obvious to the viewer if we have different accents.
00:04:55.860 --> 00:05:04.960
Is that Anthony spends a lot of his time, I guess, looking at things from the security angle, whereas most of my time has been spent from a development angle.
00:05:04.960 --> 00:05:10.500
And I've been curious about security, I guess, for a long time.
00:05:10.500 --> 00:05:18.560
My first job was doing sort of system support for servers and dealing with hacked servers was a pretty common occurrence.
00:05:18.560 --> 00:05:23.620
And I guess learning how people got into the systems, what they did once they got there.
00:05:24.060 --> 00:05:31.320
And it was kind of shown in the movies, like there's, you know, this person in a dark room with like a green screen and it's all like super technical.
00:05:31.320 --> 00:05:36.480
And they've always got a hoodie on and they're always playing some sort of like metal music in the background.
00:05:36.780 --> 00:05:46.820
But actually, when you're more familiar with, I guess, how systems get compromised, it's just people running scripts that just pinging server after server after server looking for known vulnerabilities.
00:05:47.380 --> 00:05:55.580
And if people haven't configured stuff properly or they've left bad usernames, bad passwords, then they just poke a hole in it and then have their fun, basically.
00:05:55.580 --> 00:05:59.580
I mean, that takes up a lot of people's time and a lot of the security challenges.
00:05:59.820 --> 00:06:07.880
So my kind of curiosity has been, how can I write code in a way that I'm not doing things which the attackers are going to be excited about?
00:06:07.880 --> 00:06:14.600
Like, what mistakes could I be making in my code that they're going to be like, ah, fool, he left this particular vulnerability.
00:06:14.600 --> 00:06:17.760
He didn't read this obscure documentation page.
00:06:17.760 --> 00:06:19.800
And it does come across like that to people.
00:06:19.800 --> 00:06:25.820
Like, it seems hard, which is, I guess, why I put the article together to point out some of the more obvious ones.
00:06:25.820 --> 00:06:28.040
And they're not that complicated.
00:06:28.040 --> 00:06:29.460
Yeah, that's a really good point.
00:06:29.580 --> 00:06:31.260
Most of it isn't that complicated.
00:06:31.260 --> 00:06:33.900
It's just knowing that what is out there.
00:06:33.900 --> 00:06:40.880
You know, me personally, I don't think about it the way that you do, Anthony, in terms of like, how can I break things?
00:06:40.880 --> 00:06:49.620
I think of it more as like a super paranoid, forgetful person, which I'm fairly forgetful in general life as it is, but not paranoid.
00:06:49.620 --> 00:06:52.600
But I'm always thinking like, oh my gosh, what have I forgotten?
00:06:52.600 --> 00:06:56.900
What is the thing that is just wide open that I forgot?
00:06:56.900 --> 00:07:00.400
Did I forget to turn on the firewall that blocks the database port publicly?
00:07:00.400 --> 00:07:04.760
Did I forget to, you know, validate this one thing?
00:07:04.760 --> 00:07:12.440
I think, you know, a while ago there was one admin page on my site that didn't check whether this person was an admin or not.
00:07:12.760 --> 00:07:15.060
And if you could come up with this random URL, you could have found it.
00:07:15.060 --> 00:07:17.180
I'm like, oh my gosh, I can't believe I forgot that.
00:07:17.400 --> 00:07:20.820
So that's sort of my feeling is like a constant uneasiness.
00:07:20.820 --> 00:07:27.120
I know there's thousands of people attacking this site constantly, but throughout, you know, they sort of continuously, I guess.
00:07:27.120 --> 00:07:30.660
And it's like, well, when will they find the thing I forgot?
00:07:30.660 --> 00:07:32.920
It's an ego driven security as it's called.
00:07:32.920 --> 00:07:33.860
But that's cool.
00:07:33.860 --> 00:07:34.500
That's cool.
00:07:34.500 --> 00:07:36.800
If it makes you more secure, then go for it, please.
00:07:37.060 --> 00:07:38.160
Yeah, I think it probably does.
00:07:38.160 --> 00:07:42.080
I mean, I'm always double checking stuff and I think it does really, really help.
00:07:42.080 --> 00:07:44.800
So there's a lot of these things you can address.
00:07:44.800 --> 00:07:48.080
And I think it's probably time to go through this list.
00:07:48.080 --> 00:07:55.880
So when Brian and I spoke about this on Python Bytes just yesterday, actually it came out today, but we recorded it yesterday.
00:07:56.880 --> 00:08:00.860
And he was like, well, the ones that were obvious, they're not even here.
00:08:00.860 --> 00:08:05.960
I mean, some of them are, but some of them are like Python, you know, there's the eval, eval user input.
00:08:05.960 --> 00:08:06.960
Like, don't do that, right?
00:08:06.960 --> 00:08:10.460
So I think you have a really interesting list that you put together here.
00:08:10.460 --> 00:08:13.880
Some of which will be people like, oh yeah, I've heard of that.
00:08:13.880 --> 00:08:14.860
Others like, really?
00:08:14.860 --> 00:08:16.400
I didn't know that was a problem.
00:08:16.400 --> 00:08:20.260
And then they'll frantically pause the podcast and they'll run away and go look at their systems.
00:08:20.260 --> 00:08:25.340
So you want to take us through the topics and we can sort of spend a little time on each one?
00:08:25.340 --> 00:08:26.160
Yeah, sure.
00:08:26.280 --> 00:08:30.080
So I guess I left out some really obvious ones.
00:08:30.080 --> 00:08:32.640
I mean, eval is probably the worst one.
00:08:32.640 --> 00:08:36.820
Like you wouldn't just accept input from the internet and pass it through eval, I'd hope.
00:08:36.820 --> 00:08:38.300
You say that.
00:08:38.300 --> 00:08:39.060
You say that.
00:08:39.060 --> 00:08:40.840
I'm sure it's happening all over the place.
00:08:40.840 --> 00:08:44.860
It's easier to sort that way when you just pass the lambda on the command line.
00:08:44.860 --> 00:08:51.560
Yeah, the PHP equivalent is the reason that you're getting all those entries in your logs looking for wp-admin.
00:08:51.560 --> 00:08:56.160
Anyway, so I guess the number one is
00:08:56.160 --> 00:09:00.180
input injection, which is just common across languages, across frameworks.
00:09:00.580 --> 00:09:05.900
It's nothing specific to Python.
00:09:05.900 --> 00:09:13.840
It's basically noticing that you're creating SQL queries and you're taking a parameter and you're injecting it into a string literal.
00:09:13.840 --> 00:09:20.720
And what they can do is they can escape the quotes you put around the argument or the filter or whatever it was.
00:09:20.840 --> 00:09:24.420
And they can basically run arbitrary SQL queries on your table.
00:09:24.420 --> 00:09:26.920
So SQL injection, I think, is pretty well known.
00:09:26.920 --> 00:09:28.960
It's pretty easy to avoid.
00:09:28.960 --> 00:09:32.200
There are libraries for doing sensible escaping.
00:09:32.200 --> 00:09:38.380
There are libraries for basically parameterizing your SQL queries, which is really the way it should be done.
00:09:38.640 --> 00:09:43.340
But time and time again, that's probably seen as one of the most common things in web applications.
00:09:43.340 --> 00:09:45.640
And it's just one of those things that won't die, right?
00:09:45.640 --> 00:09:52.680
Like it's just there's still popular blog posts that have examples of SQL injection attacks all over.
00:09:52.680 --> 00:09:54.200
And people just read until they get it to work.
00:09:54.200 --> 00:09:55.880
They don't go to the comments and say, don't do this.
00:09:55.880 --> 00:09:56.500
Don't do this.
00:09:56.740 --> 00:10:07.100
Yeah, because it's like when you learn SQL or if you learn how to create SQL queries, it doesn't like there are so many tutorials out there that actually show you the wrong way to do it.
00:10:07.100 --> 00:10:08.840
So this is why it keeps happening.
00:10:08.840 --> 00:10:12.360
Yeah, this is why it keeps happening because people are like, this is how you write a SQL query.
00:10:12.360 --> 00:10:17.240
And then, OK, you want to filter by a particular user or a particular ID or whatever.
00:10:17.240 --> 00:10:18.740
Here's how you write a where clause.
00:10:18.740 --> 00:10:20.300
And, oh, let's take that as a parameter.
00:10:20.300 --> 00:10:22.000
Yeah, yeah, because it's simpler, right?
00:10:22.000 --> 00:10:24.100
People are learning the wrong way to do it every day.
00:10:24.100 --> 00:10:26.900
And we're having to unteach them that kind of practice.
00:10:26.900 --> 00:10:29.240
Luckily, there's a cartoon to remind us.
00:10:29.240 --> 00:10:31.400
SKCD.
00:10:31.400 --> 00:10:32.020
Yeah.
00:10:32.020 --> 00:10:32.440
Yeah.
00:10:32.440 --> 00:10:34.060
Are you familiar with little Bobby tables?
00:10:34.060 --> 00:10:34.960
Yeah, absolutely.
00:10:34.960 --> 00:10:36.160
And I've seen the picture.
00:10:36.160 --> 00:10:40.820
There's a photograph as well as of a car where someone's put on their license plate.
00:10:40.820 --> 00:10:43.480
They've actually tried to put SQL injection on their license plate.
00:10:43.480 --> 00:10:45.740
Get all those license plate readers.
00:10:45.740 --> 00:10:47.040
That was brilliant.
00:10:47.040 --> 00:10:47.560
Yeah.
00:10:47.560 --> 00:10:49.320
So the license plate readers would crash.
00:10:49.320 --> 00:10:50.380
That's the intention anyway.
00:10:50.380 --> 00:10:53.420
And then I guess the other version of that is command injection,
00:10:53.660 --> 00:10:58.140
where you have a script which needs to call a local process on the machine,
00:10:58.140 --> 00:11:03.240
like an encoder or a specific executable or something like that.
00:11:03.240 --> 00:11:07.500
I mean, Python has a few ways of doing that in the standard library.
00:11:07.500 --> 00:11:08.880
There's subprocess.
00:11:08.880 --> 00:11:10.280
There's popen.
00:11:10.280 --> 00:11:14.260
There's in the OS module.
00:11:14.260 --> 00:11:15.000
There's another way.
00:11:15.700 --> 00:11:25.500
And there's many ways that similar to SQL injection, you can take an argument from somewhere and people can escape that argument and use it to run arbitrary commands on the server.
00:11:25.860 --> 00:11:28.320
So that's command injection or shell injection is called.
00:11:28.320 --> 00:11:29.920
That sounds a little bit bad.
00:11:29.920 --> 00:11:31.180
And that one actually was surprising to me.
00:11:31.180 --> 00:11:32.520
I wasn't super familiar with that.
00:11:32.520 --> 00:11:43.240
But if you're going to do popen and pass a string as the command to run, you could easily do dollar sign, dollar sign, next command or semicolon or whatever the separator your shell uses.
00:11:43.340 --> 00:11:49.940
Because you can issue commands that have multiple operations one after another in a single line, right?
00:11:50.060 --> 00:11:56.260
Yeah, so the most common example is somebody writing a, basically calling an executable and then giving it an argument.
00:11:56.260 --> 00:12:00.840
Let's say you want to create a thumbnail or encode an MP4 or something.
00:12:00.840 --> 00:12:07.380
Then you'd call a local process which does the encoding and you'd give it an argument which is the name of the file you want to encode.
00:12:07.380 --> 00:12:18.120
So that's straightforward, except that if instead of a file name, they close the quote and then they do a semicolon or an amphosand, amphosand, and then they can put in any other command they like.
00:12:18.120 --> 00:12:19.440
How could that be wrong?
00:12:19.440 --> 00:12:20.340
How could it go wrong?
00:12:20.340 --> 00:12:27.120
And it's funny because I shared this post and I saw some of the discussion forums, people arguing back saying, oh no, that's not a problem.
00:12:27.120 --> 00:12:29.720
Why, how could that possibly be a vulnerability?
00:12:29.720 --> 00:12:35.740
And even if you kind of like make it really obvious, people don't look at it like an attacker would look at it.
00:12:35.740 --> 00:12:38.160
They look at it like, oh, who would misuse that?
00:12:38.160 --> 00:12:38.780
How could that happen?
00:12:38.780 --> 00:12:39.180
Exactly.
00:12:39.180 --> 00:12:39.820
That's flexibility.
00:12:39.820 --> 00:12:40.420
It's good.
00:12:40.420 --> 00:12:41.320
It means good things.
00:12:41.320 --> 00:12:45.840
Yeah, and I think it's really interesting to have these two contrasts, not just SQL injection.
00:12:45.840 --> 00:12:54.920
And I was going to add too that there's, in addition to the escaping and stuff that Ant is talking about, there's additional things you can do here to protect yourself.
00:12:55.120 --> 00:13:00.500
So, for example, if you can run as the least privileged account you can.
00:13:00.500 --> 00:13:03.600
So, don't run as root or administrator, for example.
00:13:03.600 --> 00:13:11.440
So, if you do happen to have a bug in your application where someone can do command injection, you're going to minimize what it can do.
00:13:11.620 --> 00:13:15.740
So, there's multiple levels of ways you can protect yourself here as well.
00:13:15.740 --> 00:13:18.520
I think that's a really good point for a lot of this stuff, right?
00:13:18.520 --> 00:13:23.120
It's sort of security as layers, not the one big silver bullet, right?
00:13:23.120 --> 00:13:24.200
Yes, very much so.
00:13:24.200 --> 00:13:24.540
Yeah.
00:13:24.540 --> 00:13:29.360
The Python way around that is, well, first of all, avoid doing this if possible.
00:13:29.360 --> 00:13:35.040
I mean, there's many other ways of doing spawning processes and doing them correctly.
00:13:35.240 --> 00:13:45.280
But if you have to, if you need to escape the input, then use the shlex module, which is built into the standard library, and it has a utility function for escaping shell commands.
00:13:45.280 --> 00:13:45.680
Yeah.
00:13:45.680 --> 00:13:52.600
What I really like about your article, which I don't know if we've said it explicitly, it's 10 common security gotchas in Python and how to avoid them.
00:13:52.600 --> 00:13:54.440
And we'll put that in the show notes, of course.
00:13:54.640 --> 00:14:02.200
And for many of these, you have these, oh, did you know there's this other module you can just use that fixes this problem?
00:14:02.200 --> 00:14:08.480
So, that's, it's really nice that you have sort of some way to deal with this, not just like to put paranoia into people.
00:14:08.480 --> 00:14:15.360
This episode of Talk Python To Me is brought to you by Test and Code and the Python Bytes podcasts.
00:14:15.360 --> 00:14:19.380
If you love podcasts in Python, and you're listening to mine, so you must, right?
00:14:19.380 --> 00:14:22.840
Well, don't miss out on these two other great podcasts.
00:14:23.240 --> 00:14:30.980
If you're in a hurry and just want the headlines, get the rapid fire Python Bytes podcast that I co-host with Brian Okken over at pythonbytes.fm.
00:14:30.980 --> 00:14:47.440
Brian also hosts his own show, Test and Code, at testandcode.com, where he explores topics like test-driven development, continuous integration, code coverage, and pytest, of course, as well as agile development, mentoring, public speaking, and lots more in an opinionated mix of interviews and solo episodes.
00:14:47.440 --> 00:14:52.280
Keep up with the latest news and become a better developer by listening to Python Bytes and Test and Code.
00:14:52.840 --> 00:15:00.100
The next group of attacks are all related to deserializing or serializing data.
00:15:00.580 --> 00:15:08.040
And this is a pretty common vector where, let's say you're writing an application that reads configuration from somewhere.
00:15:08.040 --> 00:15:18.640
And that could be in YAML or JSON or XML, or it's receiving a message from somewhere, or you're basically using it as a way of communicating between different processes.
00:15:19.100 --> 00:15:20.520
There's different ways you can do that in Python.
00:15:20.520 --> 00:15:25.420
You could use XML, you could use JSON, you could use YAML, or you could use pickle files.
00:15:25.420 --> 00:15:30.560
So all four of those have massive gaping holes in them, which you could drive a bus through.
00:15:30.560 --> 00:15:34.960
So I kind of explained how you could abuse each one of them.
00:15:35.360 --> 00:15:39.140
I guess people might assume that XML is the safest.
00:15:39.140 --> 00:15:50.960
Yeah, it seems sort of old school, but XML can get complicated on the edges, you know, like weird namespaces and referring back to itself and other sorts of bizarre things that nobody ever does.
00:15:50.960 --> 00:15:51.280
Yeah.
00:15:51.280 --> 00:15:56.940
So the one I kind of explained was the billion, what's called the billion laughs exploit.
00:15:58.100 --> 00:15:58.720
It's funny.
00:15:58.720 --> 00:16:04.340
And it's, you know, look, if you're going to get like taken down, at least it should be a funny sort of hack, right?
00:16:04.340 --> 00:16:04.760
Come on.
00:16:04.760 --> 00:16:06.120
Got to appreciate it.
00:16:06.120 --> 00:16:19.600
So this is if you wanted to, if you received an XML payload from somewhere and an attacker has access to put their own XML in there, then basically XML has this thing called entity expansion.
00:16:19.600 --> 00:16:23.680
I guess the most similar way to think of it is a zip file.
00:16:24.520 --> 00:16:34.560
And what you could do, imagine you created a text file and it just contained spaces, lots and lots and lots of spaces, like let's say a million spaces.
00:16:34.560 --> 00:16:40.400
Now, if you compress that into zip, it compresses down to nothing because the way compression algorithms work.
00:16:40.400 --> 00:16:43.380
But when you extract it, it's like, oh, it's one character.
00:16:43.380 --> 00:16:44.320
Yeah, exactly.
00:16:44.320 --> 00:16:47.200
So it can condense down to pretty much nothing.
00:16:47.200 --> 00:16:53.600
Let's say you compress that into a zip file and then you made 10 of those, you copied it and you pasted it 10 times.
00:16:53.780 --> 00:16:58.980
And then you copied those 10 zip files and then added them to a zip file and then did that again and again and again.
00:16:58.980 --> 00:17:06.420
Now, what happens is if you extracted that zip file, it will go and sort of recursively extract the zips.
00:17:06.420 --> 00:17:13.420
And it can go from something like a one kilobyte zip file to gigabytes or potentially even worse.
00:17:13.900 --> 00:17:16.780
So the XML version, that's called a zip bomb.
00:17:17.020 --> 00:17:24.600
The XML version is a similar idea where in XML, you can have basically you can sort of reference things.
00:17:24.600 --> 00:17:29.900
And so in entity expansion, it can kind of reference something which references something.
00:17:29.900 --> 00:17:34.700
So it's similar to the zip bomb where you kind of create this tree and then it basically exponentially expands.
00:17:35.080 --> 00:17:40.940
So when you're trying to deserialize this special message in XML, it can take up gigabytes of RAM.
00:17:40.940 --> 00:17:44.420
So that is basically the exploit is that it just takes your server offline.
00:17:44.420 --> 00:17:48.400
And here it is fitting on one screen with word wrapping.
00:17:48.400 --> 00:17:48.760
Yeah.
00:17:48.760 --> 00:17:50.000
And it's like eight lines of XML.
00:17:50.000 --> 00:17:50.420
Yeah.
00:17:50.420 --> 00:17:54.100
It sort of teaches you that exponential stuff and like factorial type things.
00:17:54.100 --> 00:17:55.560
They get big fast.
00:17:55.680 --> 00:17:56.160
Yeah, exactly.
00:17:56.160 --> 00:17:57.900
So the XML one's pretty bad.
00:17:57.900 --> 00:18:01.640
There's some other pretty well-known ones with XML.
00:18:01.640 --> 00:18:06.440
So if you actually look at the standard library documentation for Python, and this is how I came across this.
00:18:06.440 --> 00:18:10.840
It does say in a big red box that there are known security challenges with XML.
00:18:10.840 --> 00:18:15.020
And you shouldn't deserialize arbitrary XML documents.
00:18:15.020 --> 00:18:18.100
Unless you do like soap web services, then what could go wrong?
00:18:18.100 --> 00:18:18.500
Exactly.
00:18:18.900 --> 00:18:26.300
So I guess the alternative is you can use a package called defused XML, which is a third party package.
00:18:26.300 --> 00:18:30.800
But it was actually written by Christian Himes, who's one of the core developers on Python.
00:18:30.800 --> 00:18:32.680
He's a security expert at Red Hat.
00:18:32.680 --> 00:18:37.340
So he kind of put together, I guess, a safer version of the XML standard library module.
00:18:37.340 --> 00:18:38.860
And it's a drop-in replacement.
00:18:38.860 --> 00:18:39.420
That's awesome.
00:18:39.420 --> 00:18:44.620
Does it just like not support these self-referential things and some of the other dangerous bits?
00:18:44.620 --> 00:18:46.000
It's like a limited XML?
00:18:46.000 --> 00:18:48.620
Stuff that it would be really unlikely you'd have to use anyway.
00:18:48.760 --> 00:18:48.920
Yeah.
00:18:48.920 --> 00:18:52.080
Anthony, as a network person, how do you think about these issues?
00:18:52.080 --> 00:18:55.260
Like, do you scan for these sorts of things?
00:18:55.260 --> 00:18:57.540
They keep me up at night?
00:18:57.540 --> 00:19:00.380
Look, there's a whole class of exploits with XML.
00:19:00.380 --> 00:19:06.260
There's exploits where you can embed schema information into there and do weird stuff with schema.
00:19:06.260 --> 00:19:12.740
I generally think that if you are going to handle XML, you generally whitelist what you accept.
00:19:12.740 --> 00:19:18.300
You define your own schema and say, if it doesn't match that schema first, I'm not going to parse it.
00:19:18.360 --> 00:19:20.460
I'm only going to parse minimal pieces of it.
00:19:20.460 --> 00:19:29.500
There's also, you can use what's called an XML external entity attack where you reference to a schema or an inclusion from somewhere else.
00:19:29.500 --> 00:19:31.720
And that somewhere else is relative to your server.
00:19:32.400 --> 00:19:41.580
So by getting you to upload a piece of XML, they can try to get your server to load something from your internal network and potentially display it back to the attacker.
00:19:41.580 --> 00:19:45.160
So XML can be used as a reconnaissance tool as well.
00:19:45.500 --> 00:19:52.360
It's not to say that XML is bad, but you have to follow the advice that is giving you now to use it properly and use it well.
00:19:52.360 --> 00:19:52.660
Yeah.
00:19:52.660 --> 00:19:55.460
Stay away from the dangerous bits unless you really need them.
00:19:55.460 --> 00:19:58.520
And it's rare these days, I think, that you need them.
00:19:58.600 --> 00:20:06.840
It seems like, you know, early 2000s, XML was supposed to be the answer to all the questions that involved any form of connectivity, right?
00:20:06.840 --> 00:20:10.720
Like we have all these fancy things with XML.
00:20:10.720 --> 00:20:13.940
We had all the hype around soap services.
00:20:14.200 --> 00:20:18.940
You have XSLT going wild being like the way to generate all sorts of stuff.
00:20:18.940 --> 00:20:23.380
And I feel like we've kind of moved on, but there's still plenty of XML processing around.
00:20:23.380 --> 00:20:24.800
XML has its place.
00:20:24.800 --> 00:20:29.360
It's a great metadata standard with a lot of bells and whistles attached.
00:20:29.360 --> 00:20:34.720
The problem is 90% of people don't need those bells and whistles, but it is what it is.
00:20:34.720 --> 00:20:36.280
Yeah, I guess I should knock XML.
00:20:36.280 --> 00:20:41.200
I mean, it is the main bit of traffic on some of my websites with the podcast RSS feed.
00:20:41.200 --> 00:20:42.800
That thing gets hammered.
00:20:43.460 --> 00:20:46.940
So I guess I should love XML, but that's the simple version.
00:20:46.940 --> 00:20:58.200
So another thing that you put in here that I thought was really interesting is people relying on assert to actually do runtime control.
00:20:58.200 --> 00:21:02.360
This one is pretty obscure, actually, and not that well known.
00:21:02.360 --> 00:21:06.200
And that is that there's effectively an optimizer.
00:21:06.200 --> 00:21:09.020
Well, there's a series of optimizations you can do in Python.
00:21:09.460 --> 00:21:13.200
And you can run Python in optimized mode, which does.
00:21:13.200 --> 00:21:22.240
I mean, if you look at the history of Python, basically what it tries to do is traverse the syntax tree and kind of make assumptions about how it should be executed.
00:21:22.240 --> 00:21:30.480
So that if you're doing it in production, it almost removes commands out of your code and skips them or looks at them differently.
00:21:30.940 --> 00:21:35.360
So this is things like constant crushing constants together, loop on folding.
00:21:35.840 --> 00:21:37.420
And there's a whole bunch of optimizations.
00:21:37.420 --> 00:21:43.580
One of those optimizations is to ignore assert statements because really they should be used for debugging.
00:21:43.580 --> 00:21:53.840
So if you're used to any other programming languages, so sometimes you can basically create like a debug assembly or a runtime assembly where they have debug symbols in one.
00:21:53.960 --> 00:22:01.980
And it's designed for production and another Python basically has that, but it's by adding an extra flag when you execute the Python file.
00:22:01.980 --> 00:22:06.720
So it skips certain commands depending on whether it's running an optimized mode or not.
00:22:06.720 --> 00:22:24.480
So if you use an assert statement to do things like checking that the password is right or checking that the user has the right amount of privileges or whatever, then basically it all runs fine in unit tests and integration tests because you never use optimized mode because you always want the assert statements.
00:22:24.800 --> 00:22:32.820
And then when you actually deploy it to production, someone says, oh, Python is quicker, like 10%, 20% quicker if we run it in optimized mode.
00:22:32.820 --> 00:22:39.000
They switch the flag on and all of your security catches and everything like that just disappear.
00:22:39.000 --> 00:22:39.600
Yeah.
00:22:39.600 --> 00:22:42.380
I mean, they could be totally sort of silent as well, right?
00:22:42.380 --> 00:22:47.240
If you were doing like containers, you could depend upon a Docker container and the base image could change in a way.
00:22:47.240 --> 00:22:48.680
They're like, yeah, we made it a little bit better.
00:22:48.680 --> 00:22:49.460
It's faster.
00:22:49.460 --> 00:22:50.500
Oh, great.
00:22:50.500 --> 00:22:51.120
I love faster.
00:22:51.120 --> 00:22:51.780
Let's do that.
00:22:51.780 --> 00:22:54.540
Wait, why can people be on this page again?
00:22:54.540 --> 00:22:55.240
This is terrible.
00:22:55.240 --> 00:22:56.580
Yeah, that's pretty scary.
00:22:56.580 --> 00:22:59.440
So the fix here is don't do that.
00:22:59.440 --> 00:23:01.520
It's like, doctor, it hurts when I raise my arm.
00:23:01.520 --> 00:23:02.380
Well, don't do that.
00:23:02.380 --> 00:23:04.700
Keep your arm down, basically.
00:23:04.700 --> 00:23:10.560
Like just use a if, you know, not admin, raise exception, permission error, or something like that, right?
00:23:10.560 --> 00:23:11.820
Yeah, typed exceptions.
00:23:11.820 --> 00:23:13.060
Yeah, exactly.
00:23:13.060 --> 00:23:14.860
Which is how it's supposed to be done anyway.
00:23:14.860 --> 00:23:15.380
Okay.
00:23:15.380 --> 00:23:23.900
Another one that's pretty interesting is not as common for the web because of the latency, but it's pretty interesting.
00:23:24.280 --> 00:23:24.840
Timing attacks.
00:23:24.840 --> 00:23:25.680
Tell us about those.
00:23:25.680 --> 00:23:26.960
Anthony, do you want to explain this one?
00:23:26.960 --> 00:23:31.420
So timing attacks, there's two really, two little buckets this falls into.
00:23:31.420 --> 00:23:38.280
One, if you're doing any form of security sensitive operation, like let's say, for example, you're checking a password is valid.
00:23:38.280 --> 00:23:49.540
The way a lot of code works is it might say, well, it will say, well, if the password is too short or too long, then don't bother checking the password, just fail out straight away.
00:23:49.840 --> 00:23:51.860
And an attacker can use this to work out.
00:23:51.860 --> 00:23:55.640
Well, what is a valid password to decrease the passwords it needs to check?
00:23:55.640 --> 00:23:56.080
I see.
00:23:56.080 --> 00:24:04.480
So if you're going to do like a dictionary attack and you realize, well, it's zero milliseconds for anything under seven characters, we'll start there.
00:24:04.680 --> 00:24:05.200
Exactly.
00:24:05.200 --> 00:24:05.320
Exactly.
00:24:05.320 --> 00:24:05.680
Exactly.
00:24:05.680 --> 00:24:05.680
Exactly.
00:24:05.680 --> 00:24:06.000
Exactly.
00:24:06.000 --> 00:24:16.080
So if you're doing particularly some cryptography, the idea is it's meant to have an approximately equal amount of time, irrespective of what input you give it.
00:24:16.560 --> 00:24:20.760
There's also another set of attacks around time of check, time of update.
00:24:20.760 --> 00:24:32.240
So if you're doing certain checks and then doing stuff that depends on those checks, make sure those checks are around the same time in code as they are that you're doing it.
00:24:32.240 --> 00:24:42.760
Because otherwise there is a gap between when you do that check, that security check, for example, and when you do that task or that operation that requires a result of that check, that can be exploited too.
00:24:43.020 --> 00:24:45.340
So there's kind of two areas here.
00:24:45.340 --> 00:24:46.580
That's pretty interesting.
00:24:46.580 --> 00:24:51.280
I hadn't really thought of the sort of information leakage around that.
00:24:51.280 --> 00:24:55.680
So I want to give a shout out to a Python package that I think just is really amazing.
00:24:55.680 --> 00:24:58.680
He talked about password checking and stuff called Passlib.
00:24:58.680 --> 00:25:00.340
Are either of you familiar with Passlib?
00:25:00.340 --> 00:25:00.920
No, I'm not.
00:25:00.920 --> 00:25:01.220
Yeah.
00:25:01.220 --> 00:25:11.260
So Passlib is really awesome because, you know, one of the bits of advice is to get a random salt and mix that in when you generate the password, right?
00:25:11.460 --> 00:25:13.240
Or when you hash and store the password.
00:25:13.240 --> 00:25:15.900
And then also make this computationally expensive to guess.
00:25:15.900 --> 00:25:21.580
So Passlib is like, there's like one function of like encrypt and one function like verify.
00:25:21.580 --> 00:25:30.660
And it will, you give it a plain text password and it will take that and it will fold it like 150,000 times with custom salt for that particular user.
00:25:31.060 --> 00:25:32.540
And then it can check it.
00:25:32.540 --> 00:25:37.680
But it takes like, you know, 0.2 seconds to determine whether it's right or wrong.
00:25:37.680 --> 00:25:39.500
It doesn't even just check the length.
00:25:39.500 --> 00:25:42.960
So it's a really nice way to sort of add a few more layers there.
00:25:42.960 --> 00:25:43.380
Yeah.
00:25:43.380 --> 00:25:48.500
So the other one I recommended was part of the standard library, but it was only added in 3.5.
00:25:48.960 --> 00:25:50.580
And that's a module called Secrets.
00:25:50.580 --> 00:25:57.780
And it has a method called Compare Digest where you can basically give it two values and it says, are they equal or not?
00:25:57.780 --> 00:26:03.100
So that's where you would say if the actual password equals equals the password the user entered.
00:26:03.620 --> 00:26:07.260
And statements like that are the type that can be left open to timing attacks.
00:26:07.260 --> 00:26:10.600
So Compare Digest basically makes it impossible to do that.
00:26:10.600 --> 00:26:11.460
Yeah, that's cool.
00:26:11.460 --> 00:26:20.220
So one piece of advice that I have around if you're doing anything like password management or any cryptography stuff, generally speaking, don't write it yourself.
00:26:20.220 --> 00:26:31.960
Use a library off the shelf that other people have used and vouched for because it's very easy to, if you do crypto wrong, it can be worse than having no crypto.
00:26:32.340 --> 00:26:36.240
Because for all the false assurances it will give you.
00:26:36.240 --> 00:26:36.500
Right.
00:26:36.500 --> 00:26:38.780
You think it's fine, but, you know, I don't understand.
00:26:38.780 --> 00:26:40.900
I base 64 encoded the password.
00:26:40.900 --> 00:26:42.620
They can't get that back out of the database.
00:26:42.620 --> 00:26:43.020
Come on.
00:26:43.020 --> 00:26:44.700
Of course not.
00:26:44.700 --> 00:26:45.160
Of course.
00:26:45.160 --> 00:26:46.040
Yeah.
00:26:46.040 --> 00:26:51.000
That pass level one that I talked about, by the way, they have like a list of all the support algorithms and the ones they recommend.
00:26:51.000 --> 00:26:52.720
And they're constantly checking them.
00:26:52.720 --> 00:26:55.540
So I think it's bcrypt and SHA-512 right now that they're using.
00:26:55.540 --> 00:26:58.080
It'll be bcrypt and probably the PBK-DF2.
00:26:58.080 --> 00:27:00.860
They're the two ones that people tend to recommend these days.
00:27:00.860 --> 00:27:01.340
So, yes.
00:27:01.340 --> 00:27:01.840
Yeah, nice.
00:27:02.080 --> 00:27:12.640
So one that I think is kind of scary because it's an exact opposite or in contrast to what makes Python awesome, right?
00:27:12.640 --> 00:27:15.220
Like, you know, import anti-gravity.
00:27:15.220 --> 00:27:20.980
It sort of captures the joy of Python where you just import anything and it's just there and it just works.
00:27:21.600 --> 00:27:26.480
But it's possible that you could have installed something bad, right?
00:27:26.480 --> 00:27:27.300
Yeah, absolutely.
00:27:27.300 --> 00:27:32.520
And I think not just install something bad, but the way that Python imports work.
00:27:33.160 --> 00:27:33.780
They're really flexible.
00:27:33.780 --> 00:27:34.540
They're really flexible.
00:27:34.540 --> 00:27:40.620
You can override all sorts of things, including system like almost language keywords.
00:27:40.620 --> 00:27:47.340
So you can override the print function or the assert statement or you can do all sorts of crazy things in imports.
00:27:47.500 --> 00:27:58.960
So I think one of the challenges with Python is that if you have a package somewhere in your site packages, basically an import path that does something malicious, it can be very difficult to detect that.
00:27:59.060 --> 00:28:03.100
And because your site packages is almost like a tier.
00:28:03.380 --> 00:28:07.560
So you've got like a system level one and then you might have a virtual environment one.
00:28:07.560 --> 00:28:13.180
And then maybe there's another one that you use as well where you might import stuff from somewhere else in your Python path.
00:28:13.180 --> 00:28:18.860
Then when you import something, you never actually know unless you go and check what it's imported.
00:28:18.860 --> 00:28:19.360
Yeah.
00:28:19.360 --> 00:28:24.460
And it could do really bad stuff like, you know, just while you're talking, I was thinking, OK, so I write a package.
00:28:24.460 --> 00:28:29.000
The import statement is effectively execute __init__.py.
00:28:29.660 --> 00:28:35.400
Maybe in that section, I'll see if I could go and find SQLAlchemy or some database connection.
00:28:35.400 --> 00:28:41.040
And then I'll monkey patch that over for the connect so I can grab your connection string and then pass it along.
00:28:41.040 --> 00:28:45.080
So you think your app is still working or, I mean, there's all sorts of nefarious stuff you could do, right?
00:28:45.080 --> 00:28:45.700
Yeah, exactly.
00:28:45.700 --> 00:28:55.980
And I think it's just people put a lot of trust in a pip install statement in terms of not only what package they installed, but what dependencies that package had.
00:28:56.340 --> 00:29:03.980
And what dependencies their dependencies had and what ended up getting installed and whether any of those have actually polluted your site packages.
00:29:03.980 --> 00:29:11.020
So basically, if you're importing even a standard library module, like, is that has something else overloaded that?
00:29:11.020 --> 00:29:14.620
And is that import basically changing your global namespace?
00:29:17.820 --> 00:29:21.120
This portion of Talk Python To Me is brought to you by us.
00:29:21.120 --> 00:29:27.060
Over at Talk Python Training, we're building out our library courses, and that library is growing each month.
00:29:27.060 --> 00:29:30.560
That's why I want to take a moment and tell you about a special offer we have.
00:29:30.560 --> 00:29:32.280
It's called the Everything Bundle.
00:29:32.280 --> 00:29:34.460
With it, you get, well, everything.
00:29:34.460 --> 00:29:38.940
Every course we have in our library, including the ones yet to be published this calendar year.
00:29:38.940 --> 00:29:43.620
Many online training companies have subscriptions and discounts if you buy them a year at a time.
00:29:43.620 --> 00:29:47.120
Our Everything Bundle is like a subscription, but it's way better.
00:29:47.440 --> 00:29:51.460
With subscriptions, the moment you stop paying, you lose access to everything.
00:29:51.460 --> 00:29:55.360
With our Everything Bundle, you keep access to our courses forever.
00:29:55.360 --> 00:30:01.380
Any course published the year you bought the bundle or sooner is indefinitely yours, even if you never renew.
00:30:01.380 --> 00:30:04.940
Check out what's available at training.talkpython.fm.
00:30:04.940 --> 00:30:11.320
And if you're looking for a way to support the podcast, taking or recommending one of our courses is the very best way to do this.
00:30:11.760 --> 00:30:12.260
Thank you.
00:30:12.260 --> 00:30:25.160
That sort of hints at a really scary scenario because I'm pretty careful what I install, but I don't go and check the dependencies of everything that it depends upon before I use it.
00:30:25.220 --> 00:30:27.060
I'm like, yeah, this looks like a reputable package.
00:30:27.060 --> 00:30:28.580
I'll go ahead and use it.
00:30:29.160 --> 00:30:34.380
But it hints at almost like a supply chain challenge in that.
00:30:34.540 --> 00:30:40.560
Imagine I find some not very popular package that something popular is based upon.
00:30:40.560 --> 00:30:46.280
And then I go do a PR that sneaks in some extra sneaky dependency.
00:30:46.280 --> 00:30:48.720
That is actually the problem that people don't realize.
00:30:48.720 --> 00:30:52.060
And so when that gets pushed out to be updated, you update your thing.
00:30:52.640 --> 00:30:57.460
All of a sudden, you're indirectly pulling in this thing because some guy was like, yeah, it looks like a good PR.
00:30:57.460 --> 00:30:59.320
I'm busy, but we'll take it anyway.
00:30:59.320 --> 00:30:59.680
Go ahead.
00:30:59.680 --> 00:31:00.640
Yeah, it certainly can be.
00:31:00.640 --> 00:31:02.960
So, well, there isn't really one.
00:31:02.960 --> 00:31:04.640
Again, like the doctor.
00:31:04.640 --> 00:31:05.160
Don't do that.
00:31:05.160 --> 00:31:06.380
It hurts when I do this.
00:31:06.380 --> 00:31:06.920
Don't do that.
00:31:06.920 --> 00:31:11.240
Well, you do reference a service that I'm a fan of.
00:31:11.240 --> 00:31:12.180
So tell people about it.
00:31:12.180 --> 00:31:21.940
Yeah, so pyup.io basically has a sort of a database of packages and versions of those packages which have known vulnerabilities.
00:31:21.940 --> 00:31:34.260
So this links to one of the other things I put in the article, which was not patching your dependencies, which is a pretty common pattern where people say, okay, I'm going to get all my dependencies and then I'm going to do pip freeze or something.
00:31:34.260 --> 00:31:37.380
And I'm going to put that into my requirements.txt file.
00:31:37.560 --> 00:31:44.440
So I've basically pinned which versions do I know work and no one ever touched that file.
00:31:44.440 --> 00:31:48.820
So like that's probably one of the scariest things, as you said, here's all the versions.
00:31:48.820 --> 00:31:50.560
These are the ones we tested with.
00:31:50.560 --> 00:31:57.500
But no one goes and checks each packages or each dependencies website and sees the notification that says, oh, yeah, sorry.
00:31:57.500 --> 00:32:01.380
There's a massive security hole in version 2.9.6.
00:32:01.380 --> 00:32:03.640
Please update to 2.9.7.
00:32:03.640 --> 00:32:07.160
And it's the dependency, maybe the dependency of your dependencies thing.
00:32:07.300 --> 00:32:12.160
Like even if you were crazy diligent and you went and checked all the stuff you installed, that's not even enough.
00:32:12.160 --> 00:32:13.180
Yeah, exactly.
00:32:13.180 --> 00:32:22.780
So pyup.io basically has a database, a freely available database where you can look up bad versions of packages that exist on PyPI.
00:32:22.780 --> 00:32:29.820
And they have a service where they can actually go and scan your requirements.txt if it's on a GitHub repository.
00:32:29.820 --> 00:32:33.400
Or they have hooks where you can use it with other services like GitLab.
00:32:33.880 --> 00:32:39.760
And if they basically say that there are newer versions available or this is a bad version, then they'll give you a notification.
00:32:39.760 --> 00:32:43.040
So I guess that's one of the better ways of approaching the problem.
00:32:43.040 --> 00:32:48.600
And this is probably the point in my article that got the most negative feedback from people.
00:32:48.600 --> 00:32:50.800
They said, oh, of course, you have to pin dependencies.
00:32:50.800 --> 00:32:54.980
Like, you know, you can't just willy nilly install the latest version.
00:32:55.640 --> 00:32:58.180
But pyup does it does have version ranges.
00:32:58.180 --> 00:33:00.020
There's a there's a PEP for that.
00:33:00.020 --> 00:33:03.100
So you can say, you know, I want this minor version.
00:33:03.100 --> 00:33:06.980
So I want version 2.8 up to 2.9.
00:33:07.220 --> 00:33:12.920
And then if they release a 2.8.1 or 2.8.2, then you'll automatically install the right version.
00:33:12.920 --> 00:33:18.440
And if you hope that people use semantic versioning, the API itself and the functionality shouldn't have changed.
00:33:18.440 --> 00:33:20.880
And of course, you've got good test coverage anyway.
00:33:20.880 --> 00:33:21.860
So you'll catch it.
00:33:21.860 --> 00:33:22.840
That's a really good point.
00:33:22.840 --> 00:33:25.540
The problem is pip freeze doesn't do that.
00:33:25.540 --> 00:33:26.200
Right.
00:33:26.240 --> 00:33:28.600
And that becomes a ton of work on your side of things.
00:33:28.600 --> 00:33:30.100
I use pyup for my stuff.
00:33:30.100 --> 00:33:33.360
Like so the training website, the various podcast websites and a few other things.
00:33:33.360 --> 00:33:37.660
I have it hooked up and I will get weekly pull requests.
00:33:37.660 --> 00:33:42.100
These three packages have changed and they could be like deep dependencies.
00:33:42.100 --> 00:33:43.540
Here's their change log.
00:33:43.540 --> 00:33:44.640
Here's here's the new version.
00:33:44.640 --> 00:33:49.440
And there's just a PR which patches the frozen packages in my requirements at TXT.
00:33:49.440 --> 00:33:50.740
It's really nice.
00:33:50.740 --> 00:33:52.520
Anthony, how do you think about this?
00:33:52.520 --> 00:33:52.740
Yeah.
00:33:52.820 --> 00:33:59.380
So one thing I was going to add is that you can never predict when a package that you thought was good may turn bad.
00:33:59.380 --> 00:34:02.720
People might write a package and think, yeah, this version is great.
00:34:02.720 --> 00:34:04.960
And then someone somewhere finds an issue with it.
00:34:04.960 --> 00:34:10.380
So the key here is a regular monitoring of what you're doing and a regular patch cycle.
00:34:10.380 --> 00:34:13.020
Because you said you never know when something's going to happen.
00:34:13.020 --> 00:34:14.740
So you need to make sure you're looking for it.
00:34:14.740 --> 00:34:17.660
And that turnaround time is as short as possible.
00:34:17.660 --> 00:34:20.340
So the focus here is more on your operations.
00:34:20.580 --> 00:34:23.880
How do you manage your system as opposed to necessarily how you program it?
00:34:23.880 --> 00:34:25.340
But nevertheless, that's important.
00:34:25.340 --> 00:34:25.660
Yeah.
00:34:25.660 --> 00:34:31.200
I think another step there is you have to proactively be applying these changes.
00:34:31.200 --> 00:34:33.280
It's one thing to notice there's a problem.
00:34:33.280 --> 00:34:41.060
It's another to notice that PyUp sent me a PR that says, oh, you're depending on this version of, you know, a JSON parser or something.
00:34:41.060 --> 00:34:42.240
And it has this vulnerability.
00:34:42.240 --> 00:34:43.080
You need to fix it.
00:34:43.640 --> 00:34:47.040
It's another to go, yeah, and now I'm patching the server.
00:34:47.040 --> 00:34:50.400
You think, look at, what was it, Experian?
00:34:50.400 --> 00:34:51.180
Right?
00:34:51.180 --> 00:34:54.120
They were hacked with a known vulnerability.
00:34:54.120 --> 00:34:56.400
It was, everybody said, this is ultra bad.
00:34:56.400 --> 00:34:59.760
You need to drop what you're doing, skip lunch and go fix it.
00:34:59.760 --> 00:35:02.060
And it's just, well, we work at this big company.
00:35:02.540 --> 00:35:06.600
We can't be bothered to change this because if it breaks, this is not my site.
00:35:06.600 --> 00:35:09.440
But if I break it trying to fix it, I'm losing my weekend.
00:35:09.440 --> 00:35:11.780
So I'll let someone else deal with that on Monday when they get in.
00:35:11.780 --> 00:35:17.240
And then, you know, 143 million people lose all their credit and personal banking details, me included.
00:35:17.240 --> 00:35:18.600
Ouch.
00:35:18.860 --> 00:35:19.000
Yeah.
00:35:19.000 --> 00:35:20.300
But I mean, what are you going to do, right?
00:35:20.300 --> 00:35:23.660
I think there's like another layer that goes on top of this.
00:35:23.660 --> 00:35:24.520
Like you have to act.
00:35:24.520 --> 00:35:24.900
Yes.
00:35:24.900 --> 00:35:25.240
Yes.
00:35:25.240 --> 00:35:30.360
I mean, it's a patch management aspect of your server maintenance or system maintenance.
00:35:30.360 --> 00:35:36.420
I mean, as Ant said, there's tools inside Python, but you need to use them and you need to be using them regularly.
00:35:36.420 --> 00:35:39.900
You need to have that, you know, I do need to fix it now.
00:35:39.900 --> 00:35:43.980
So how do I, how do I decrease that turnaround time to as small as possible?
00:35:43.980 --> 00:35:44.440
Yeah.
00:35:44.440 --> 00:35:44.880
Yeah.
00:35:44.880 --> 00:35:45.000
Yeah.
00:35:45.000 --> 00:35:48.600
And what do you think about speed to actually deploying the fix?
00:35:48.780 --> 00:35:54.600
Like, are there like continuous delivery bits of magic that you people would be willing to rely upon?
00:35:54.600 --> 00:35:56.780
Like it says massive security vulnerability.
00:35:56.780 --> 00:36:00.000
We will let it automatically publish this if the test pass.
00:36:00.000 --> 00:36:00.800
I'm not sure.
00:36:00.800 --> 00:36:04.980
I mean, if your test passed, it still needs to go through some sort of UAT.
00:36:04.980 --> 00:36:08.780
It depends, I guess, on the, it depends on the project and depends on what it's for.
00:36:08.780 --> 00:36:17.740
Like if it's a, if it's an internal web application, then, you know, it's unlikely, but you also want to make sure that thing gets patched and updated as quickly as possible.
00:36:18.700 --> 00:36:24.820
The cost of, the cost of, the cost of downtime is one thing, probably smaller than the cost of attack or the cost of compromise.
00:36:25.220 --> 00:36:28.300
So I guess it's a, it's a, it's a kind of looking at it from the angle.
00:36:28.300 --> 00:36:39.680
Another thing I guess I want to talk about is that the way that you as a developer talk to operations, assuming you, you have an operations team that you're talking to, and that's not just another hat you have to wear.
00:36:40.540 --> 00:36:47.800
And the way you talk about what versions of the dependencies your, your package depends on and how brittle that is.
00:36:47.900 --> 00:36:51.820
Cause something I've heard a lot is people say, never know, don't touch my dependencies.
00:36:51.820 --> 00:36:54.500
Cause I know that they work and it was probably going to break the code.
00:36:54.740 --> 00:37:00.260
So from an ops, you know, angle, they're like, well, we're going to look after all the system.
00:37:01.260 --> 00:37:06.880
And then we're going to look after all the stuff that's, you know, dev have told us not to touch that and to leave it alone.
00:37:06.880 --> 00:37:08.360
Otherwise it's all going to go really bad.
00:37:08.820 --> 00:37:17.780
And if, if they touch it and they try and patch something, then the dev team's going to be like, oh, well, you know, you've, you've been changing the code and you've changed the dependencies and we didn't ask you to do that.
00:37:17.780 --> 00:37:18.900
And that's why it's breaking.
00:37:18.900 --> 00:37:26.820
So I guess it's, it's a conversation between the two teams or if you've got DevOps and then having a conversation about how you try and automate some of that stuff.
00:37:26.820 --> 00:37:27.120
Yeah.
00:37:27.120 --> 00:37:28.300
The more automation, the better.
00:37:28.300 --> 00:37:31.540
So the next one that you have on your article was surprising to me.
00:37:31.540 --> 00:37:34.020
I didn't really think about it, but I guess it makes sense.
00:37:34.020 --> 00:37:35.160
Is it temporary files?
00:37:35.160 --> 00:37:35.880
Yeah.
00:37:36.220 --> 00:37:43.280
I'm lucky enough not to have to use those very much in most of the stuff I write these days, but they're actually very common vulnerabilities.
00:37:43.280 --> 00:37:46.940
So apparently there's a MK temp function that'll generate a temp file.
00:37:46.940 --> 00:37:47.920
I didn't even know about this.
00:37:47.920 --> 00:37:49.940
I don't use temp files very much either, I guess.
00:37:49.940 --> 00:37:50.300
Yeah.
00:37:50.300 --> 00:37:51.520
It's a, it's an old one.
00:37:51.520 --> 00:37:56.360
And I came across this when I was doing building the course for moving from Python two to Python three.
00:37:56.360 --> 00:38:04.360
Cause one of the recommendations is that you don't use the Python two functions for creating temporary files because they have known security issues in them.
00:38:04.660 --> 00:38:06.620
So kind of digging into that a bit deeper.
00:38:06.620 --> 00:38:10.220
So there's a temp file module, which is the one that you should use.
00:38:10.220 --> 00:38:15.820
And there's a function called MKSTemp, which you should use to generate temporary files.
00:38:15.820 --> 00:38:16.600
Is that for secure?
00:38:16.600 --> 00:38:18.320
I'm pretty sure S stands for secure.
00:38:18.320 --> 00:38:18.580
Yeah.
00:38:18.580 --> 00:38:20.080
Nice.
00:38:20.080 --> 00:38:20.460
Okay.
00:38:20.640 --> 00:38:30.280
So the problem is there could be timing attacks or if you hit the time, just right, like you could create the temp file and then you could swap out the data before they read it or other bad things like that.
00:38:30.280 --> 00:38:30.500
Right?
00:38:30.500 --> 00:38:31.080
Exactly.
00:38:31.080 --> 00:38:37.980
So the reason the old one is bad is because it will create the file first and then it will open and load the file.
00:38:38.520 --> 00:38:44.220
So what can happen is someone can sit there scanning the file directory, the temporary file directory.
00:38:44.220 --> 00:38:47.620
An attacker can basically sit there looking at it constantly.
00:38:47.620 --> 00:38:54.940
And as soon as they see a file pop up, so the file handle is being created, then they can go and dump a load of data in there.
00:38:55.040 --> 00:38:58.080
And then you open it and then it's all changed.
00:38:58.080 --> 00:39:01.160
Like basically it's a way of them injecting data into your application.
00:39:01.160 --> 00:39:01.620
Yeah.
00:39:01.620 --> 00:39:02.440
That sounds bad.
00:39:02.440 --> 00:39:09.220
So another one, you kind of touched on this before is parsing other file types can be really bad.
00:39:09.220 --> 00:39:16.480
And I kind of riffed on XML being bad because it was old and complicated, but YAML is kind of new and awesome.
00:39:16.480 --> 00:39:17.900
That probably is bad, right?
00:39:17.900 --> 00:39:28.140
You know, this YAML one is so really hardly anybody knows that you can do this because when you look at the example, you think, why would they allow that to happen?
00:39:28.140 --> 00:39:29.140
Wait, hold on, hold on.
00:39:29.140 --> 00:39:36.740
I think exactly like maybe you shouldn't tell anybody about this because you're going to tell people they could do it as much as to protect themselves against it.
00:39:36.740 --> 00:39:37.180
Exactly.
00:39:37.180 --> 00:39:38.440
No, I'm just kidding.
00:39:38.440 --> 00:39:38.740
Go ahead.
00:39:38.740 --> 00:39:39.120
Tell everyone.
00:39:39.120 --> 00:39:50.520
So I guess the most popular package for reading and writing YAML files is called PyYAML and it has a method called YAML.load or YAML.loads.
00:39:50.520 --> 00:40:05.160
And if you actually read the documentation, it says in big letters, warning, YAML.load is not safe, essentially, because you can run any Python function by putting special characters in the YAML file.
00:40:05.160 --> 00:40:17.160
Yeah, like exclamation, exclamation, Python object apply, OS.sys, you know, some form of like Python code or calling some sort of sub process or all sorts of bad things.
00:40:17.160 --> 00:40:22.860
Like that's incredible that you can do that, that you can just say, shall execute this in my YAML file.
00:40:22.860 --> 00:40:34.160
So you can basically put a special, it's like two exclamation points and then a special path and then the name of the function in the standard library that you want to execute and the parameters.
00:40:34.700 --> 00:40:43.900
And then if you call YAML.load and the YAML text or the YAML file has that basically the special syntax in it, it will just execute that locally.
00:40:43.900 --> 00:40:54.120
So you can imagine like if you had a web application where you were asking people to provide some simple YAML input to describe something or you were loading something to configure something.
00:40:54.500 --> 00:41:01.540
I mean, an example that I used in there was, you know, I use YAML a lot with Ansible, which is like a network automation tool.
00:41:01.540 --> 00:41:03.380
And they had a, they had the vulnerability.
00:41:03.380 --> 00:41:09.680
They had the same vulnerability because in that product called Ansible Vault, they were loading it using YAML.load.
00:41:09.680 --> 00:41:11.440
And people are like, oh, awesome.
00:41:11.440 --> 00:41:15.500
I can just like pop a shell on this box instead of providing a password.
00:41:16.500 --> 00:41:18.620
That seems amazing.
00:41:18.620 --> 00:41:22.700
Anthony, do you use Ansible or work with YAML and worry about these things?
00:41:22.700 --> 00:41:23.180
Yes.
00:41:23.180 --> 00:41:37.980
I mean, this is, this is a perfect example of something that really, it's like for those, if any of your listeners are familiar with JavaScript, you used to have the eval that used to run to load in JSON, but they changed that to parse because eval was inherently unsafe.
00:41:38.240 --> 00:41:45.400
And this is an example of a function, which is just, it just goes on the, on the, on the do not use list for anything that is serious, right?
00:41:45.400 --> 00:41:46.420
You just don't use it.
00:41:46.420 --> 00:41:54.680
If there's no equivalent on it, then, then we look at something, something else because there's an, unless we go and rewrite it, there's, there's no workaround.
00:41:54.680 --> 00:41:59.580
It's basically like giving people like just dollar prompt access, like type here.
00:41:59.580 --> 00:42:00.780
What do you want to do on the server?
00:42:00.780 --> 00:42:01.320
Exactly.
00:42:01.320 --> 00:42:01.800
Exactly.
00:42:01.800 --> 00:42:03.540
To be honest with you, this is one of those things.
00:42:03.540 --> 00:42:06.880
When I read something like this, the first thing in my head is what were they thinking?
00:42:07.820 --> 00:42:08.900
I am with you.
00:42:08.900 --> 00:42:09.400
So first.
00:42:09.400 --> 00:42:10.220
Yeah.
00:42:10.220 --> 00:42:11.500
So, and tell us the fix.
00:42:11.500 --> 00:42:12.400
What is your fix here?
00:42:12.400 --> 00:42:12.880
Okay.
00:42:12.880 --> 00:42:18.760
So there's two fixes and I only found out about the second one yesterday and I think it might have something to do with this article.
00:42:18.760 --> 00:42:24.960
The first fix is that you don't use load, use safe underscore load, which.
00:42:24.960 --> 00:42:25.740
Of course.
00:42:25.740 --> 00:42:26.340
Of course.
00:42:26.340 --> 00:42:36.880
So in the same way that you have to use MKSTemp instead of MKTemp, you should use, however, I guess, explicitly saying you want to do things safely is a bit of an anti-pattern.
00:42:37.400 --> 00:42:44.580
So I did see there was a pull request which has been merged into PyYAML to make the safe version the default.
00:42:44.580 --> 00:42:47.900
And you have to explicitly ask for the unsafe version.
00:42:47.900 --> 00:42:53.060
However, I think that's only been merged in the most recent version of 4.1.
00:42:53.280 --> 00:42:59.320
And then if you ignore all of our prior advice about updating your pip dependencies, then you're never going to see that anyway.
00:42:59.320 --> 00:43:01.520
These do interplay, don't they?
00:43:01.780 --> 00:43:10.940
So I was definitely thinking of that API design sort of experience and like, wait, load and then the safe unload is what you're really supposed to do some of the time.
00:43:10.940 --> 00:43:16.400
Like, this does not help people fall into the pit of success, right?
00:43:16.400 --> 00:43:24.360
Like, to me, it seems like if you don't know what you're doing, it should default or just lead you down the path of, well, do the safe one.
00:43:24.420 --> 00:43:29.040
And if they need the crazy, you know, run this shell thing, like, make them hunt for that.
00:43:29.040 --> 00:43:31.700
Don't make that the default until they know better, right?
00:43:31.700 --> 00:43:34.380
Sounds like at least they've gotten that working now.
00:43:34.380 --> 00:43:35.080
Let go.
00:43:35.240 --> 00:43:35.840
Yeah, exactly.
00:43:35.840 --> 00:43:41.640
And I mean, the advice that I would give to anybody who is designing their own APIs is security by default.
00:43:41.640 --> 00:43:47.660
What you do, the most obvious way of doing things, the standard way of doing things should be the secure way.
00:43:47.660 --> 00:43:59.760
If you have features that are potentially unsafe, by all means, expose them that make the developer or the user specifically ask for it so they can accept and manage the risk.
00:43:59.760 --> 00:44:00.820
Yeah, that's perfect.
00:44:01.380 --> 00:44:10.040
One of the ones that I felt is kind of obvious on this list is obvious because I've been around for a while, I guess, is this concept of pickling.
00:44:10.040 --> 00:44:21.100
And pickling is the act of taking more or less a binary version of a Python object graph, putting it on disk, and then rehydrating it back into objects, right?
00:44:21.100 --> 00:44:31.340
Yeah, and it's typically used in sort of inter-process or inter-Python version communication or dumping an object somewhere and then loading it again somewhere else.
00:44:31.340 --> 00:44:34.420
And so it's kind of built into a standard library.
00:44:34.420 --> 00:44:35.980
It's been around for a while.
00:44:36.520 --> 00:44:46.060
And before things like JSON kind of became really popular, I guess it's one of the preferred ways of communicating or sharing data between Python processes.
00:44:46.060 --> 00:44:51.160
The problem is that it has a number of fairly well-documented security vulnerabilities.
00:44:51.160 --> 00:45:00.400
I mean, if you're loading up a pickle file, you can basically put things in the pickle file, which cause it to run any Python process.
00:45:00.400 --> 00:45:16.660
Like, if you basically create a new class and then you declare something called dunderreduce, then the contents of the dunderreduce method, if you return back a tuple, you can basically, the tuple that you return can be the name of a standard library function and its arguments.
00:45:16.660 --> 00:45:23.440
So basically, that's, again, where you do os.system or subprocess.popen, and you basically pass it all the arguments.
00:45:23.440 --> 00:45:31.860
So instead of loading this nice pickle file and you continuing with your day, basically, you load a pickle file and it just runs commands on your local machine.
00:45:31.860 --> 00:45:33.460
Yeah, that's not amazing.
00:45:33.460 --> 00:45:37.280
So, again, one of these sort of don't do this.
00:45:37.280 --> 00:45:42.220
It's extra hard to check, too, because the thing you're delivered is a binary blob.
00:45:42.220 --> 00:45:44.100
So how do you know whether it's safe or not?
00:45:44.100 --> 00:45:45.540
You can't even look at it.
00:45:45.540 --> 00:45:50.980
It's not even like the YAML file where you're like, wait, wait, wait, what is that double, double, double exclamation mark Python thing?
00:45:50.980 --> 00:45:51.780
That doesn't look right.
00:45:51.780 --> 00:45:52.600
Right.
00:45:52.600 --> 00:45:54.960
This is just, you know, one, zero, one, zero, zero, one.
00:45:54.960 --> 00:45:55.760
Seems okay.
00:45:55.760 --> 00:45:56.320
Yeah.
00:45:56.320 --> 00:46:04.660
So there's not really a workaround for this other than don't use pickle or don't try and unpickle things from an untrusted source.
00:46:04.660 --> 00:46:13.360
But then I don't even like saying that because it's that kind of assumption which attackers use for using attacks, combining them together.
00:46:13.360 --> 00:46:15.220
But Anthony knows a lot more about that than I do.
00:46:15.220 --> 00:46:16.500
Yeah, it's chaining them, right?
00:46:16.500 --> 00:46:20.600
It's like you lose one to get one layer in and then another and then another.
00:46:20.600 --> 00:46:20.880
Yeah.
00:46:20.880 --> 00:46:22.440
Ant's got a very good point.
00:46:22.440 --> 00:46:30.880
The way a lot of attackers compromise systems is they won't go after the top tier, the most important, the most visible ones.
00:46:30.880 --> 00:46:40.260
They'll try to look at maybe the second or third tier systems, ones that people may not have paid as much attention to or made as much effort securing.
00:46:40.260 --> 00:46:47.960
And if they can compromise those, they will use those as a foothold to go after things that people perceive as important.
00:46:48.600 --> 00:46:56.980
So if I compromise an app and it's communicating via pickles to other apps, for example, that can be how the exploit occurs.
00:46:57.340 --> 00:47:06.080
So it's good to keep in mind that every system you write has to consider security, as Ant is saying, and follow Ant's advice on looking at these 10 topics.
00:47:06.280 --> 00:47:18.080
Yeah, I mean, maybe this is some wimpy little app that's just like some reporting thing, but you could use it to get behind the firewall or maybe you could pickle some bad stuff into a shared Redis cache that then the other system might read.
00:47:18.080 --> 00:47:21.040
And then, you know, you just level up step by step, right?
00:47:21.040 --> 00:47:22.280
The so-called lateral movement.
00:47:22.280 --> 00:47:23.640
It is being recorded, you're right.
00:47:23.800 --> 00:47:24.740
Exactly, exactly.
00:47:24.740 --> 00:47:28.700
And look, three, four, five hops for the compromises is not unusual.
00:47:28.700 --> 00:47:33.700
And when you see it going, you realize how good some of these attackers actually are.
00:47:33.700 --> 00:47:34.600
But I digress.
00:47:34.600 --> 00:47:36.340
That's right.
00:47:36.340 --> 00:47:36.740
That's right.
00:47:36.740 --> 00:47:51.180
So I guess the last two kind of blend together a little bit in about not patching your Python runtime, sort of the main one, what you get if you just go to the open a shell and just type Python 3 or something, or your dependencies as well.
00:47:51.320 --> 00:47:58.440
And I heard that you don't really need to patch your Python runtime because there's zero days that sometimes appear in like your OS.
00:47:58.440 --> 00:48:00.520
So you can just like, this is not worth bothering with, right?
00:48:00.520 --> 00:48:04.280
What was that crazy comment was about?
00:48:04.280 --> 00:48:04.880
I can't remember.
00:48:04.880 --> 00:48:07.500
There was a comment on those lines.
00:48:07.500 --> 00:48:09.000
They were like, oh, but why do we bother?
00:48:09.000 --> 00:48:10.400
Why do we have to patch Python?
00:48:10.400 --> 00:48:11.940
Because they're probably just going to hack us anyway.
00:48:11.940 --> 00:48:12.700
So what's the point?
00:48:12.700 --> 00:48:13.300
If only.
00:48:13.300 --> 00:48:14.500
If only it worked that way.
00:48:14.500 --> 00:48:17.140
I think that's, I mean, we touched on that at the beginning a little bit.
00:48:17.140 --> 00:48:20.240
And that is sort of a sense of despair that people have.
00:48:20.240 --> 00:48:23.620
You're like, look, I could do all these things that I'm supposed to do.
00:48:23.620 --> 00:48:28.760
But soon as there's some sort of zero day or O day in my system, you know, all bets are off.
00:48:28.760 --> 00:48:31.120
I'm not going to be able to defend against that.
00:48:31.120 --> 00:48:35.900
I don't know what zero day there is in, you know, NGINX unit.
00:48:36.280 --> 00:48:37.500
And so forget it.
00:48:37.500 --> 00:48:39.000
I'm just not going to worry about security.
00:48:39.000 --> 00:48:41.320
And I can totally understand how people feel that way.
00:48:41.320 --> 00:48:53.960
But there was some interesting analysis and reports saying that even state sponsored actors of hackers and stuff primarily use super boring stuff, like all the things we've already been talking about, right?
00:48:54.000 --> 00:48:57.620
Like SQL injection and other boring unpatched things.
00:48:57.620 --> 00:48:59.540
I mean, zero days, yes, they happen.
00:48:59.540 --> 00:49:11.100
But as a proportion of total security incidents, they're actually relatively small, particularly for the well-known, well-trusted packages and products that are out there.
00:49:11.540 --> 00:49:17.740
I think this is one of those cases where people need to get their own house in order before they throw stones, if you know what I mean.
00:49:17.740 --> 00:49:18.980
Yeah, yeah.
00:49:19.120 --> 00:49:25.160
But I mean, once again, I mean, most of this stuff is relatively simple once you understand what you need to do.
00:49:25.160 --> 00:49:28.420
So it's just a question of putting time and effort into it.
00:49:28.420 --> 00:49:28.880
That's all.
00:49:28.880 --> 00:49:39.920
I think there's a difference between the NSA or some other country is trying to literally get into your thing or I'm on the Internet and people are rattling the doors to see if they're open.
00:49:39.920 --> 00:49:47.700
And they're not going to spend a full week trying to get into my system because they know there's thousands that just have SQL injection or some other random thing, right?
00:49:47.820 --> 00:49:56.480
Yeah, and look, to be honest with you, if the NSA really, really wants to get into your network, the version of the Python package you're using is probably the least of your problems at the moment.
00:49:56.480 --> 00:49:58.740
So...
00:49:58.740 --> 00:49:59.640
Yes, exactly.
00:49:59.640 --> 00:50:00.360
Exactly.
00:50:00.360 --> 00:50:03.380
Plenty scary, but we're not going to think too much about that, I guess.
00:50:03.380 --> 00:50:08.560
So what you're telling me is I need to install Python 3.7 because it just came out.
00:50:08.560 --> 00:50:09.140
Things like that.
00:50:09.140 --> 00:50:17.320
Yeah, I'd actually say, this is probably controversial, but I wouldn't install Python 3.7 until 3.7.0.1 comes out.
00:50:17.720 --> 00:50:19.340
Generally, I'd...
00:50:19.340 --> 00:50:19.980
Yeah, yeah, sure.
00:50:19.980 --> 00:50:26.040
But maybe, Pat, like if there were like 3.6.6 or 3.6.7, whatever the next one there is.
00:50:26.040 --> 00:50:27.100
3.6.6, yeah.
00:50:27.100 --> 00:50:28.460
I'd go with 3.6.6.
00:50:28.460 --> 00:50:30.600
But it's part of that staying on top of things.
00:50:30.600 --> 00:50:38.460
I wish PyUp actually had a check to say your Python version is 3.6.6 and it should be 3.6.7 or something like that.
00:50:38.460 --> 00:50:41.860
There is another tool, which is open source as well, called InSpec.
00:50:41.860 --> 00:50:45.580
And it's made by the same people that brought you Chef.
00:50:46.040 --> 00:50:51.780
So it's built in Ruby, but it does actually have a bunch of hooks for Python applications.
00:50:51.780 --> 00:50:58.320
And I know that it does do virtual environments and also checking versions of packages in production.
00:50:58.320 --> 00:51:02.800
So you can say, make sure that none of our servers in production have this version of Python.
00:51:03.660 --> 00:51:06.480
Make sure that they don't have these versions of these packages as well.
00:51:06.480 --> 00:51:11.900
And you can do that in InSpec and basically declaratively saying, here's our security rules.
00:51:11.900 --> 00:51:17.840
And it will go and scan through your installations for you or your service for you and actually give you back a report.
00:51:17.840 --> 00:51:21.740
So InSpec, I guess, would be the way to do it or a tool like that.
00:51:21.860 --> 00:51:22.720
Yeah, that makes a lot of sense.
00:51:22.720 --> 00:51:23.960
All right.
00:51:23.960 --> 00:51:28.140
Well, I think hopefully people learned a lot from those 10 items.
00:51:28.140 --> 00:51:32.260
I mean, there's certainly a couple of them that I had heard of, but others were new to me.
00:51:32.260 --> 00:51:34.540
And it's always good to be aware of these things.
00:51:34.540 --> 00:51:37.080
So thanks for putting that together and both of you for sharing it here.
00:51:37.080 --> 00:51:42.980
So Anthony, how do I sell this to my, you know, I work at a startup.
00:51:42.980 --> 00:51:45.580
The management just got VC funding.
00:51:45.580 --> 00:51:47.320
We're supposed to do growth, growth, growth.
00:51:47.320 --> 00:51:51.580
We're trying to figure out new features so that we get this thing to get out.
00:51:51.580 --> 00:51:53.660
How do we get ourselves to worry about this?
00:51:53.660 --> 00:51:58.800
So, well, the first thing is to understand any legal or contractual obligations that you have.
00:51:58.800 --> 00:52:04.440
So if you're in Europe, for example, you have to follow the GDPR, the new general data protection
00:52:04.440 --> 00:52:05.660
regulation that's there.
00:52:05.660 --> 00:52:11.460
If you're handling credit cards, for example, you've got PCI DSS, the payment card industry
00:52:11.460 --> 00:52:12.940
data security standard.
00:52:12.940 --> 00:52:15.800
These are the non-negotiable things you have to do.
00:52:15.800 --> 00:52:21.200
The second thing is if you have any security executives or leaders in your organization,
00:52:21.200 --> 00:52:25.720
a CISO or if they have corporate policy, security policies need to follow.
00:52:25.720 --> 00:52:27.240
They're two things.
00:52:27.240 --> 00:52:29.660
But beyond that, one is just look at the newspaper.
00:52:29.660 --> 00:52:33.260
Reputational and financial damage is real.
00:52:33.260 --> 00:52:34.260
It happens.
00:52:34.260 --> 00:52:39.920
We've all seen or heard of companies that have been hacked and thinking, gee, I wish I weren't
00:52:39.920 --> 00:52:40.240
them.
00:52:40.240 --> 00:52:41.340
I wish I was not them.
00:52:41.340 --> 00:52:42.800
So don't.
00:52:42.800 --> 00:52:44.040
Don't be them.
00:52:44.040 --> 00:52:45.980
Exactly.
00:52:46.640 --> 00:52:49.420
Well, and also I think it comes to do with culture a little bit, right?
00:52:49.420 --> 00:52:56.100
Like if the culture is do not change this application, do not touch it, because if you break it, you're
00:52:56.100 --> 00:53:00.660
going to take it down some part of our business and we're going, it's going to be so bad that
00:53:00.660 --> 00:53:01.840
that thing ossifies.
00:53:01.840 --> 00:53:04.600
And it's basically like, no, it's kryptonite.
00:53:04.600 --> 00:53:05.500
Nobody wants to touch it.
00:53:05.500 --> 00:53:06.480
I'm going to stay away from that.
00:53:06.560 --> 00:53:10.420
Yeah, it probably is got some security issues, but I'm not touching it because I will be
00:53:10.420 --> 00:53:12.560
punished to no end if I'm the one who breaks it.
00:53:12.560 --> 00:53:14.300
I can see that happening a lot.
00:53:14.300 --> 00:53:14.740
Yeah, it is.
00:53:14.740 --> 00:53:20.400
And this comes down to your general culture around, as Ant said, test coverage, refactoring.
00:53:20.400 --> 00:53:25.060
If you have stuff that you can't touch, it's going to cause you security problems.
00:53:25.060 --> 00:53:28.940
If it's stuff that you can touch, you have a fighting chance of solving them.
00:53:29.220 --> 00:53:33.920
So that comes down to, once again, to the term that uses risk management here.
00:53:33.920 --> 00:53:37.640
Is your management happy to accept the risk that you're going to have an app that will
00:53:37.640 --> 00:53:38.720
eventually cause you a problem?
00:53:38.720 --> 00:53:39.100
Right.
00:53:39.100 --> 00:53:40.880
It's sort of the consequence of failure there.
00:53:40.880 --> 00:53:45.960
I mean, look at WannaCry and Windows XP on a lot of these things.
00:53:45.960 --> 00:53:48.140
There's so much damage from that, right?
00:53:48.140 --> 00:53:48.500
Yes.
00:53:48.500 --> 00:53:54.780
And particularly if you're in a small shop, if you're in a startup, reputation is big early
00:53:54.780 --> 00:53:55.040
on.
00:53:55.560 --> 00:53:59.740
So you need to make sure that you can maintain that trust that you're going to need from your
00:53:59.740 --> 00:54:00.660
first few customers.
00:54:00.660 --> 00:54:01.320
Yeah.
00:54:01.320 --> 00:54:06.160
And you probably have an advantage in the sense that you don't have big data centers with legacy
00:54:06.160 --> 00:54:07.100
machines laying around.
00:54:07.100 --> 00:54:10.540
You're probably on the cloud using modern tools because you just started.
00:54:10.540 --> 00:54:11.180
All right.
00:54:11.180 --> 00:54:14.620
Chances of keeping that upgrade train running is probably easier.
00:54:14.620 --> 00:54:15.220
Exactly.
00:54:15.220 --> 00:54:15.820
Exactly.
00:54:15.820 --> 00:54:16.940
It's all greenfield.
00:54:16.940 --> 00:54:18.940
You don't have to keep older stuff running.
00:54:18.940 --> 00:54:19.500
Exactly.
00:54:19.500 --> 00:54:20.060
Exactly.
00:54:20.060 --> 00:54:20.500
Yeah.
00:54:20.500 --> 00:54:21.600
All right.
00:54:21.600 --> 00:54:25.540
We're getting pretty short on time and I'll be respectful of both of your times, but maybe
00:54:25.540 --> 00:54:28.480
you could tell us really quick some places to learn more about security.
00:54:28.480 --> 00:54:29.020
Yeah.
00:54:29.020 --> 00:54:31.980
I guess one, two projects I want to call out.
00:54:31.980 --> 00:54:36.140
So there's a number of projects with the same kind of name that's related to goats.
00:54:36.140 --> 00:54:41.600
I'm not sure where the goat name came from originally, but basically there's a project called
00:54:41.600 --> 00:54:47.960
Web Goat, which was originally done as a how not to do things, open source project to basically
00:54:47.960 --> 00:54:51.780
include all of the top 10 most common vulnerabilities.
00:54:52.680 --> 00:54:56.800
And I can't remember what language it was written in, probably Pearl, but there's a Python version
00:54:56.800 --> 00:55:02.860
called PyGoat and there's a Django specific one called Djangoat, which I guess we'll have
00:55:02.860 --> 00:55:05.660
in the show notes.
00:55:05.660 --> 00:55:09.360
But if you actually look at that, it's got all the Djangoat ones really cool.
00:55:09.360 --> 00:55:13.640
It's got all the stuff you should never do with Django projects like leaving debug enabled,
00:55:13.640 --> 00:55:14.120
for example.
00:55:14.680 --> 00:55:19.160
But basically how to do the, all the kind of vulnerabilities we've talked about as well
00:55:19.160 --> 00:55:21.440
as the other ones in a project.
00:55:21.440 --> 00:55:23.600
So it's kind of like a how not to do things project.
00:55:23.600 --> 00:55:27.120
And I think it's good if you want to learn how things are done.
00:55:27.120 --> 00:55:30.860
And also it has instructions about how to break it, how to use those vulnerabilities.
00:55:31.360 --> 00:55:33.440
So I would start there.
00:55:33.440 --> 00:55:39.260
And then if you know them, then you can start doing things like doing scans through your source
00:55:39.260 --> 00:55:44.480
code for those particular types of vulnerabilities or those functions and seeing if you can find
00:55:44.480 --> 00:55:45.520
bugs in other places.
00:55:45.520 --> 00:55:46.820
Yeah, that makes a lot of sense.
00:55:46.820 --> 00:55:49.140
I really like this goat series.
00:55:49.140 --> 00:55:50.200
That's pretty interesting.
00:55:50.200 --> 00:55:55.100
One thing I want to give a quick shout out to that's in your neighborhood and is a podcast
00:55:55.100 --> 00:55:56.180
called Risky Business.
00:55:56.180 --> 00:55:56.740
Have you heard of it?
00:55:56.740 --> 00:55:57.640
I listen every week.
00:55:57.640 --> 00:55:58.180
Yeah, I love it.
00:55:58.180 --> 00:55:59.220
It's fabulous, man.
00:55:59.220 --> 00:56:00.840
Those guys do such a good job.
00:56:00.840 --> 00:56:05.820
It's like headline news in security and tech programming security.
00:56:05.820 --> 00:56:06.700
It's really great.
00:56:06.700 --> 00:56:10.660
And just listening to that, you learn a lot sort of by osmosis, I think.
00:56:10.660 --> 00:56:11.160
All right.
00:56:11.160 --> 00:56:13.340
Well, I think just we're out of time.
00:56:13.340 --> 00:56:16.400
We could go on and on and maybe we'll have to do another episode on this.
00:56:16.400 --> 00:56:18.960
But that was really helpful and insightful.
00:56:18.960 --> 00:56:19.880
So thank you both.
00:56:19.880 --> 00:56:23.280
Since there's two of you, I'm going to ask two questions at the end, but the same one.
00:56:23.280 --> 00:56:26.220
We'll just do the notable PyPI package.
00:56:26.220 --> 00:56:30.340
So is there a package, maybe related to security that people maybe haven't heard of,
00:56:30.340 --> 00:56:33.240
but you want to throw out there to let people know about it?
00:56:33.240 --> 00:56:34.300
Anthony, you want to go first?
00:56:34.300 --> 00:56:48.400
I had a couple, but if one of those things that I think rather than a package, I think people need to take a step back and realize that security is a mindset here in that there's no package that's going to make your app secure.
00:56:48.400 --> 00:56:51.360
So I'm going to twist the question a little bit here.
00:56:51.360 --> 00:56:57.420
It's about keeping abreast of what's going on and keeping current and continuing to learn.
00:56:57.420 --> 00:57:00.580
And it's an area that can be fascinating, can be really interesting.
00:57:00.580 --> 00:57:01.260
Yeah.
00:57:01.260 --> 00:57:01.660
Excellent.
00:57:01.660 --> 00:57:02.220
And?
00:57:02.440 --> 00:57:02.520
Yeah.
00:57:02.520 --> 00:57:08.000
This one hasn't actually been released yet, but Brian and I are working on a new pytest plugin called pytest Requests.
00:57:08.000 --> 00:57:12.420
And by the time this episode goes to air, it'll be out and it'll be wonderful.
00:57:12.420 --> 00:57:13.740
So I'd recommend you check it out.
00:57:13.740 --> 00:57:14.920
Oh, that sounds really fun.
00:57:14.920 --> 00:57:15.720
That's awesome.
00:57:15.720 --> 00:57:18.980
And also, I want to give a shout out to your Python 3.7 course.
00:57:18.980 --> 00:57:21.600
You just did a new course on Python 3.7.
00:57:21.600 --> 00:57:22.240
I thought it was great.
00:57:22.240 --> 00:57:22.620
Thanks.
00:57:22.820 --> 00:57:26.560
Yeah, that just came out just in time for the actual release of 3.7, which is good.
00:57:26.560 --> 00:57:29.340
Yeah, you beat the window by like a week or something.
00:57:29.340 --> 00:57:32.800
Maybe just tell people super quickly where they can get it and what it's about.
00:57:32.800 --> 00:57:34.240
So the course is on Pluralsight.
00:57:34.240 --> 00:57:38.720
If you have access to Pluralsight or you want to sign up for a trial, you should be able to watch the course.
00:57:38.720 --> 00:57:40.140
It's less than an hour.
00:57:40.140 --> 00:57:49.200
And I basically go through all the major new features in 3.7, how to use them, how they work, how to configure them, as well as some of the other benefits.
00:57:49.400 --> 00:57:54.460
So it'll take an hour of your time and you'll be a Python 3.7 expert by the end of it.
00:57:54.460 --> 00:57:58.320
But you should wait till Python 3.7.1 to actually get going, maybe?
00:57:58.320 --> 00:58:00.420
Probably, but that'll be weeks away, I reckon.
00:58:00.420 --> 00:58:01.300
I reckon, yeah.
00:58:01.300 --> 00:58:04.780
I already installed 3.7, but I have 3.6 on my machine just in case I need it.
00:58:04.780 --> 00:58:05.800
All right, awesome.
00:58:05.800 --> 00:58:06.640
Well, yeah, I enjoyed it.
00:58:06.640 --> 00:58:08.360
So good to let people know about that.
00:58:08.360 --> 00:58:10.400
All right, both of you, final call to action.
00:58:10.400 --> 00:58:13.500
People, maybe they're thinking about the software that they have.
00:58:13.500 --> 00:58:16.000
What's the first thing to do to start to address this?
00:58:16.000 --> 00:58:16.400
Anthony?
00:58:16.580 --> 00:58:22.440
The first thing is to take a step back and think, well, what is the most important things that my app is protecting?
00:58:22.440 --> 00:58:25.860
What are the most important business processes or data that's there?
00:58:25.860 --> 00:58:28.240
And to think, how can I protect it?
00:58:28.240 --> 00:58:29.540
How should I protect it?
00:58:29.540 --> 00:58:32.060
Is what I'm doing what I need to do?
00:58:32.060 --> 00:58:32.720
All right, excellent.
00:58:32.720 --> 00:58:34.360
Anthony, anything to throw in on that?
00:58:34.360 --> 00:58:46.840
Yeah, I'd say just don't be intimidated by security in general and just start simple and be willing to learn and also be willing to learn from people who have a lot more experience, of which there are plenty of people out there.
00:58:46.840 --> 00:58:50.500
Yeah, it's definitely a different way of thinking and it's pretty fascinating.
00:58:50.500 --> 00:58:53.360
All right, well, thank you both for being on the show and sharing all this stuff.
00:58:53.360 --> 00:58:53.760
It was great.
00:58:53.760 --> 00:58:54.300
Thanks, Mike.
00:58:54.300 --> 00:58:54.860
Thank you, Mike.
00:58:54.860 --> 00:58:55.400
Great to be here.
00:58:55.400 --> 00:58:55.960
Yeah, bye-bye.
00:58:55.960 --> 00:58:59.980
This has been another episode of Talk Python To Me.
00:58:59.980 --> 00:59:03.400
Our guests on this episode have been Anthony Shaw and Anthony Langsworth.
00:59:03.400 --> 00:59:08.780
And this episode has been brought to you by the Test and Code podcast as well as Talk Python Training.
00:59:09.460 --> 00:59:17.380
Keep up with the latest news and become a better developer by listening to Python Bytes at pythonbytes.fm and Test and Code at testandcode.com.
00:59:17.380 --> 00:59:19.160
Want to level up your Python?
00:59:19.160 --> 00:59:26.220
If you're just getting started, try my Python jumpstart by building 10 apps or our brand new 100 days of code in Python.
00:59:26.220 --> 00:59:30.020
And if you're interested in more than one course, be sure to check out the Everything Bundle.
00:59:30.020 --> 00:59:32.260
It's like a subscription that never expires.
00:59:32.260 --> 00:59:34.460
Be sure to subscribe to the show.
00:59:34.460 --> 00:59:36.660
Open your favorite podcatcher and search for Python.
00:59:36.660 --> 00:59:37.900
We should be right at the top.
00:59:37.900 --> 00:59:47.220
You can also find the iTunes feed at /itunes, Google Play feed at /play, and direct RSS feed at /rss on talkpython.fm.
00:59:47.220 --> 00:59:49.080
This is your host, Michael Kennedy.
00:59:49.080 --> 00:59:50.440
Thanks so much for listening.
00:59:50.440 --> 00:59:51.520
I really appreciate it.
00:59:51.520 --> 00:59:53.460
Now get out there and write some Python code.
00:59:53.460 --> 00:59:53.780
I'll see you next time.
00:59:53.780 --> 01:00:14.060
I'll see you next time.