WEBVTT
00:00:00.020 --> 00:00:02.720
Security has always been the vegetables of software.
00:00:03.380 --> 00:00:06.740
Everyone agrees it matters, and somehow it never quite makes it onto the plate.
00:00:07.280 --> 00:00:09.600
At PyCon US this year, that changed.
00:00:09.960 --> 00:00:13.460
For the first time ever, security got its own dedicated day-long track,
00:00:13.860 --> 00:00:16.800
one of just two at the whole conference sitting right next to AI.
00:00:17.480 --> 00:00:19.440
And the room was packed to the back wall.
00:00:20.220 --> 00:00:22.820
On this episode, I'm joined by three people at the center of it.
00:00:23.080 --> 00:00:27.500
Seth Larson, security developer in residence at the Python Software Foundation,
00:00:27.940 --> 00:00:31.000
and very recently a CPython core developer,
00:00:31.420 --> 00:00:34.360
Juanita Gomez, a PhD researcher at UC Santa Cruz
00:00:34.700 --> 00:00:37.600
in open source security who co-chaired the track
00:00:37.920 --> 00:00:41.100
and Mike Fiedler, PyPI's safety and security engineer,
00:00:41.460 --> 00:00:43.400
one of the very few people paid full-time
00:00:43.440 --> 00:00:45.860
to keep the packages you install safe.
00:00:46.460 --> 00:00:48.100
We use the arc of the track's talks
00:00:48.300 --> 00:00:51.000
to take the temperature of Python security right now.
00:00:51.140 --> 00:00:53.220
Supply chain attacks, dependency cool-down,
00:00:53.500 --> 00:00:54.520
zero trust, S-bombs,
00:00:54.980 --> 00:00:57.060
and the push to bring Rust into CPython.
00:00:57.660 --> 00:01:01.300
and why not one of us think security is anywhere close to solved.
00:01:01.840 --> 00:01:03.620
And it turns out that's why the room was full.
00:01:04.440 --> 00:01:10.040
This is Talk Python To Me, episode 556, recorded July 6th, 2026.
00:01:11.579 --> 00:01:14.300
Talk Python To Me, yeah, we ready to roll.
00:01:14.760 --> 00:01:17.180
Upgrading the code, no fear of getting old.
00:01:17.300 --> 00:01:19.800
Async in the air, new frameworks in sight.
00:01:20.040 --> 00:01:20.980
Geeky rap on deck.
00:01:21.280 --> 00:01:22.880
Quarth crew, it's time to unite.
00:01:23.140 --> 00:01:26.020
We started in Pyramid, cruising old school lanes.
00:01:26.360 --> 00:01:27.840
Had that stable base, yes sir.
00:01:27.930 --> 00:01:28.920
Welcome to Talk Python To Me,
00:01:29.030 --> 00:01:32.220
the number one Python podcast for developers and data scientists.
00:01:32.800 --> 00:01:34.120
This is your host, Michael Kennedy.
00:01:34.500 --> 00:01:37.980
I'm a PSF fellow who's been coding for over 25 years.
00:01:38.700 --> 00:01:39.760
Let's connect on social media.
00:01:40.140 --> 00:01:43.280
You'll find me and Talk Python on Mastodon, Bluesky, and X.
00:01:43.520 --> 00:01:45.400
The social links are all in your show notes.
00:01:46.160 --> 00:01:49.680
You can find over 10 years of past episodes at talkpython.fm.
00:01:49.860 --> 00:01:53.060
And if you want to be part of the show, you can join our recording live streams.
00:01:53.420 --> 00:01:53.880
That's right.
00:01:54.100 --> 00:01:57.340
We live stream the raw uncut version of each episode on YouTube.
00:01:57.940 --> 00:02:02.360
Just visit talkpython.fm/youtube to see the schedule of upcoming events.
00:02:02.600 --> 00:02:06.220
Be sure to subscribe there and press the bell so you'll get notified anytime we're recording.
00:02:07.040 --> 00:02:08.720
This episode is brought to you by Sentry.
00:02:09.039 --> 00:02:10.280
Don't let those errors go unnoticed.
00:02:10.560 --> 00:02:12.080
Use Sentry like we do here at Talk Python.
00:02:12.580 --> 00:02:15.440
Sign up at talkpython.fm/sentry.
00:02:16.160 --> 00:02:19.400
Talk Python and Python Bytes both now have MCP servers.
00:02:20.080 --> 00:02:24.360
Point your AI at 10 plus years of Python episodes, transcripts, and show notes.
00:02:24.790 --> 00:02:24.920
Free.
00:02:25.470 --> 00:02:29.540
Click MCP in the nav at talkpython.fm and at pythonbytes.fm.
00:02:31.140 --> 00:02:35.120
Juanita, Mike, Seth, welcome all of you to Talk Python.
00:02:35.700 --> 00:02:36.120
Hi.
00:02:36.480 --> 00:02:36.660
Hello.
00:02:37.860 --> 00:02:41.240
Awesome to have some of you back, some of you here for the first time.
00:02:41.350 --> 00:02:42.080
Really, really great.
00:02:42.410 --> 00:02:45.540
So we're going to talk about Python security.
00:02:46.200 --> 00:02:57.800
And I believe, Seth, I saw that you wrote up a post article just thinking back on this kind of unique Python security track and this extra focus at PyCon US this year.
00:02:58.380 --> 00:03:08.180
I thought, hey, that'd be great to just get everyone involved together, at least everyone involved in the track, not all eight, seven or eight speakers, whatever that number adds up to be many, many speakers.
00:03:08.760 --> 00:03:19.360
And just kind of talk broadly about Python security and use this arc of the topics and talks covered at PyCon and the security track as maybe a backdrop.
00:03:19.740 --> 00:03:21.140
So welcome, welcome.
00:03:21.840 --> 00:03:29.820
Now, before we get into that exactly, let's just do quick introductions about who you are and how you're involved in stuff.
00:03:30.060 --> 00:03:31.160
Juanita, you want to kick us off?
00:03:31.360 --> 00:03:31.560
Sure.
00:03:32.300 --> 00:03:33.080
My name is Juanita.
00:03:33.600 --> 00:03:37.060
I am a PhD researcher right now at UC Santa Cruz.
00:03:37.500 --> 00:03:42.180
I work with the hospital at my university doing research in open source security and sustainability.
00:03:42.680 --> 00:03:46.100
And I've been involved in like the Python and the Sign2Pay Python community for a while.
00:03:46.320 --> 00:03:51.000
So, yeah, I got invited to coaching on the track and that was very exciting.
00:03:51.640 --> 00:03:55.600
Very cool. Where are you in your PhD? Are you past qualifying exams?
00:03:56.200 --> 00:03:57.380
I'm graduating in August.
00:03:58.420 --> 00:04:02.260
What? Oh, my God. That's awesome. Congratulations. You're far past it.
00:04:02.780 --> 00:04:04.680
So what's the plans after?
00:04:05.480 --> 00:04:17.880
I just got a job. I can't talk about it yet, but I just got a job. But I'm going to industry. I'm going to keep working on security and sustainability in open source mostly. But yeah, an industry.
00:04:18.320 --> 00:04:23.120
Cool. Congratulations on both finishing the PhD and getting a job straight away. That's super cool.
00:04:23.420 --> 00:04:23.760
Thank you.
00:04:24.160 --> 00:04:25.740
Yeah. Mike, welcome back.
00:04:25.940 --> 00:04:33.720
Hey, glad to be here. Mike Fiedler, PyPI Safety and Security Engineer, working for the Python
00:04:34.160 --> 00:04:40.700
Software Foundation based out of New York City. I'm coming up on my third year here at the PSF,
00:04:40.900 --> 00:04:47.000
which is a full milestone that I will be sharing with my compatriot here, Seth.
00:04:47.640 --> 00:04:53.139
Very cool. And I know thanks for all the work. It's been, I think, pretty impactful in three
00:04:53.160 --> 00:05:00.220
years already. Yeah, it's been kind of a wild ride of kind of incorporating this because I was a
00:05:00.460 --> 00:05:07.980
volunteer PyPI admin and contributor long before this job opened up. And having the ability to sit
00:05:08.080 --> 00:05:16.640
here and think about and work on security features and stuff for PyPI full-time has been a big eye
00:05:16.740 --> 00:05:23.780
opener as to kind of where the gaps were and kind of where they remain, but also kind of what are
00:05:23.900 --> 00:05:29.640
the very important things that we can do in the interim immediately while building up the kind of
00:05:29.780 --> 00:05:36.220
the piece by piece bits that we need to get to these longer term ideas, but being able to kind
00:05:36.220 --> 00:05:41.400
of still make progress while we're getting there. Again, it's that notion of like rebuilding the
00:05:41.400 --> 00:05:45.919
plane while you're flying it. Like, okay, well, we had the plane, but now we're like adding better
00:05:45.940 --> 00:05:51.920
sensors better kind of steering better throttles better better toggles while we're still flying
00:05:52.320 --> 00:05:58.040
and that flight is accelerating yeah 100 and seat belts i think seat belts belong in the security
00:05:58.500 --> 00:06:04.080
airplane analogy uh probably but again it's arguable sometimes seat belts are a problem
00:06:04.350 --> 00:06:10.379
so like yeah it becomes a very good discussion of trade-offs and balances and kind of what what
00:06:10.400 --> 00:06:16.740
actually will move a needle versus this is a nice to have uh you know ashtray yeah ashtrays oh my
00:06:16.740 --> 00:06:23.040
gosh i remember i remember when there are ashtrays on airplanes yeah that was crazy i'm like why is
00:06:23.040 --> 00:06:27.680
there still an ashtray on this airplane like i know they're not gonna let anyone use it fun fact
00:06:27.700 --> 00:06:33.140
they still have them in airplane bathrooms because while it is against the law they still want you to
00:06:33.240 --> 00:06:38.819
have a safe place to throw an ash your cigarette but if you're gonna violate the law so that way
00:06:38.680 --> 00:06:41.620
you don't throw it into the trash can and set something on fire.
00:06:41.880 --> 00:06:48.580
Seems reasonable. Seems reasonable. So as a way of a segue, Mike, I'll have you take this first,
00:06:48.640 --> 00:06:54.640
and then Seth, you can pick this up. You pointed out being full-time on this project versus a bunch
00:06:54.660 --> 00:06:59.560
of kind of contributors who get excited about part of it, but then there's this whole herding
00:06:59.720 --> 00:07:08.640
cats across thousands, hundreds of thousands of projects and users and contributors. And
00:07:08.660 --> 00:07:14.960
role to this versus just like a core dev type of situation, you know? Yeah, I think there's kind of
00:07:14.990 --> 00:07:20.960
two facets here, right? And there is very much a trade-off, right? When it's full-time volunteers,
00:07:21.390 --> 00:07:25.240
you get what you pay for, which is nothing, right? You haven't paid for anything. Volunteers are
00:07:25.240 --> 00:07:29.640
going to do what volunteers want to do, and they're going to do their best effort. When you hire
00:07:29.840 --> 00:07:36.400
somebody, then you set expectations and you try to make sure that you meet them, right? The double-edged
00:07:36.420 --> 00:07:42.580
sword there is that by hiring full-time employees, volunteers often will take a step off because it's
00:07:42.580 --> 00:07:48.060
like, okay, I don't need to volunteer as much as I used to because now someone's getting paid for
00:07:48.400 --> 00:07:54.720
to do it. So it's both a good thing because it highlights and focuses effort on areas that need
00:07:55.000 --> 00:08:02.340
kind of sanitization and focused effort to make progress, but it also gives volunteers a much
00:08:02.360 --> 00:08:08.560
needed break, which then in turn puts more pressure on the full-time employees to execute,
00:08:09.100 --> 00:08:16.560
which again, not enough capacity, not enough time. So we're doing our best here, but it's shown that
00:08:16.780 --> 00:08:23.200
if you do pay for a focused security effort, you do get good security outcome. And I think that's
00:08:23.300 --> 00:08:30.640
the takeaway for me and for anybody is if you pay for it, they will cut. Fair. Seth, welcome back.
00:08:30.920 --> 00:08:31.360
Hey, Michael.
00:08:32.000 --> 00:08:38.140
So quick intro for people who haven't listened to your episodes and then maybe your thoughts on this full-time thing.
00:08:38.340 --> 00:08:43.700
Yeah, so I, everyone, Seth Larson, a security developer in residence at the Python Software Foundation.
00:08:44.340 --> 00:08:49.120
I work primarily on kind of like everything that is not IPI backend.
00:08:49.420 --> 00:08:55.380
So that's the Python language, the runtime, the security response team for Python and pip,
00:08:56.080 --> 00:09:01.420
packaging tools and standards, and then kind of like how Curie World interacts with Python and vice versa.
00:09:01.570 --> 00:09:03.000
Right. So like CBE and all that.
00:09:03.890 --> 00:09:05.600
And recently a core developer, very recently.
00:09:06.740 --> 00:09:12.700
So to answer the how does this role and all that interacting with volunteers,
00:09:13.420 --> 00:09:20.660
My the way that I've tried to like because my space is like so large, my area of where I'm trying to focus.
00:09:21.050 --> 00:09:27.040
What I end up doing is I try to find projects that are obviously like high impact, all of that.
00:09:27.050 --> 00:09:31.420
Right. Like you don't want to be doing things. You don't want to be nibbling or what is the there's a snacking.
00:09:31.680 --> 00:09:38.880
That's the phrase for it. You don't want to be snacking, but you also don't want to be doing things that volunteers could technically do.
00:09:39.280 --> 00:09:50.940
Right. So if it's a job that is or a task or a project that a volunteer could do, maybe I will like pause and wait on that because I'll leave space for someone to potentially contribute there.
00:09:51.120 --> 00:10:08.780
And then the things that are less likely to get volunteer contributions, things like spinning up a CBE numbering authority for the Python Software Foundation or being an admin on the PSRT where or the Python security response team where you're doing things like, OK, we're going to like be monitoring for spam being sent to our email thread.
00:10:08.900 --> 00:10:19.140
Like volunteers maybe don't want to do that, but maybe they would want to be on the security response team contributing to coordinating vulnerability reports and then getting like acknowledged for their work.
00:10:19.340 --> 00:10:21.880
Right. Like in the in the NCD record and advisory.
00:10:22.520 --> 00:10:25.480
So that's kind of like how I think about it, because the area is so wide.
00:10:25.580 --> 00:10:32.680
I try to make sure that I leave space for other people to contribute just in case that people do get around to it before I end up getting to it.
00:10:32.820 --> 00:10:38.080
So we want to build the community volunteer muscle also, not just have it be on work.
00:10:38.100 --> 00:10:50.780
Yeah, that's really cool. How much do you focus on popular third party projects like Django? I mean, Django already has full time people above Flask or something like that versus just pure Python?
00:10:50.940 --> 00:11:01.780
Yeah, so I would say my time doesn't necessarily always like land directly on the project, but I do spend time responding to maintainers if they have questions.
00:11:02.270 --> 00:11:11.080
So like, for example, David from Flask, him and I have talked many times about how to do like a security response program or a threat model or, you know, hey, I'm seeing this.
00:11:11.360 --> 00:11:13.920
Like, can you help? Like, what what should I do in this situation?
00:11:14.100 --> 00:11:19.400
Like, we've talked about that and I've talked about it with many other maintainers, not just Flask, just to try to give them like advice.
00:11:19.740 --> 00:11:27.860
But then also whenever, like one of the nice things about this role being at like a nonprofit is that you can be super, super open.
00:11:28.170 --> 00:11:33.360
You don't have to like keep the secrets to yourself about like what you've done and like how you've seen success.
00:11:33.920 --> 00:11:45.460
So like we publish everything that we do and like where we see success and people in theory can just like take that copy paste it into their projects or their processes and have a better time than they were before.
00:11:45.710 --> 00:11:46.900
So people can learn from each other.
00:11:47.170 --> 00:11:48.680
I really do appreciate that part of the work.
00:11:49.020 --> 00:11:53.360
That is a bit of a unique aspect of doing an open source security thing as opposed to,
00:11:53.380 --> 00:11:54.220
I can't talk about it.
00:11:54.380 --> 00:11:56.000
This is, no, we don't talk about anything.
00:11:56.140 --> 00:11:57.160
So very interesting.
00:11:57.980 --> 00:11:59.320
Let's talk about this track.
00:11:59.860 --> 00:12:04.940
So there's this trailblazing Python security that talks about, for the first time ever,
00:12:05.140 --> 00:12:09.120
a day-long track devoted to the latest in Python security.
00:12:09.400 --> 00:12:14.460
And if you pull up the schedule of talks, I believe it was Saturday was the track.
00:12:15.080 --> 00:12:17.460
And that was, there was just a whole room.
00:12:17.640 --> 00:12:19.380
And what I also liked, it was a room, wasn't it?
00:12:19.660 --> 00:12:22.080
That was like a fixed place, so you didn't have to keep moving.
00:12:22.360 --> 00:12:22.500
Yeah.
00:12:22.760 --> 00:12:27.860
So Juanita, you want to kick us off and talking about why this, why do you guys focus on this
00:12:28.240 --> 00:12:28.680
this year?
00:12:28.840 --> 00:12:32.560
And, you know, why did you decide it's going to take a specific slot in?
00:12:32.940 --> 00:12:35.940
There's only two dedicated slots, security and AI.
00:12:36.180 --> 00:12:37.120
And I think that's very fitting.
00:12:37.380 --> 00:12:38.420
But tell us about this track.
00:12:38.800 --> 00:12:38.940
Okay.
00:12:39.160 --> 00:12:44.780
Well, I will let Seth talk about how did the idea come to place because I was not part
00:12:44.780 --> 00:12:45.040
of that.
00:12:45.240 --> 00:12:47.460
but I'm going to talk about why I think it's important
00:12:47.650 --> 00:12:48.860
and why it was important in the conference.
00:12:49.860 --> 00:12:53.640
I think security is something that's parallel to everything in Python.
00:12:53.970 --> 00:12:56.200
I think that if you're a maintainer for a package,
00:12:56.310 --> 00:12:59.880
I think having security somewhere on your mind should be a thing.
00:13:00.120 --> 00:13:02.700
You should be thinking about security when you're developing a thing.
00:13:03.410 --> 00:13:09.420
And I think there's a big gap in maybe the time that maintainers spend
00:13:09.660 --> 00:13:11.820
thinking about security or even the expertise.
00:13:13.140 --> 00:13:26.440
And so I think this track was like a big opportunity for people that work in PyVon as maintainers or as users to just learn about some important security things when thinking about like their development processes.
00:13:27.079 --> 00:13:32.660
I thought it was great that it was like a dedicated track because I think it highlights the importance of security.
00:13:33.030 --> 00:13:38.980
Like it's not a bunch of talks that are kind of like in the schedule that people just kind of like figure out they want to go to.
00:13:38.980 --> 00:13:42.380
But it's like we like made it a thing by making it like a full track.
00:13:42.980 --> 00:13:50.500
And I think that elevates the importance of security within Python, which I think it's not necessarily always the case.
00:13:50.780 --> 00:13:55.660
I think every time I talk to Mike, I'm like, why are you the only getting paid for doing Python security?
00:13:56.840 --> 00:14:02.680
I think increasing the awareness of the importance of security is very important.
00:14:02.720 --> 00:14:05.280
And I think that the track, I think, was meant to do that.
00:14:05.660 --> 00:14:13.300
How much do you think what were in those seven talks is representative of the broader security
00:14:13.420 --> 00:14:17.380
space, you know, getting your PhD, studying the stuff like you get maybe a little more
00:14:17.540 --> 00:14:18.900
than just Python view?
00:14:19.380 --> 00:14:21.000
Like, what did it capture?
00:14:21.120 --> 00:14:21.760
And what did it miss?
00:14:21.760 --> 00:14:22.000
I guess.
00:14:22.520 --> 00:14:27.960
I think, honestly, we made it a track that was diverse enough that we could capture like
00:14:28.300 --> 00:14:32.960
very different things within the security brother, like image.
00:14:33.500 --> 00:14:38.920
And I also think that a lot of the things that we talked about are not even necessarily Python specific.
00:14:39.460 --> 00:14:41.400
Like you should care about credentials.
00:14:41.690 --> 00:14:43.220
You should care about phishing.
00:14:43.220 --> 00:14:50.000
Like all of these things are things that you should care about, whether you do Python or C or any other like language development.
00:14:51.080 --> 00:14:59.540
I think that something that maybe I was missing a little bit after I like saw maybe after the conference,
00:14:59.820 --> 00:15:07.140
I was thinking about, I would have liked maybe like an intro version of security, something.
00:15:07.290 --> 00:15:12.160
I think something that I work with in my research is actually like security practices,
00:15:13.000 --> 00:15:15.100
mostly for like starting projects.
00:15:15.530 --> 00:15:18.240
I work with like literally university projects.
00:15:19.090 --> 00:15:23.140
And like the goal of my OSP is to improve the practices of the university projects.
00:15:23.580 --> 00:15:27.560
And some of them are maybe not as advanced to take on some of the,
00:15:27.880 --> 00:15:30.120
like I would say more advanced security practices.
00:15:30.640 --> 00:15:32.240
And so maybe something like that
00:15:32.420 --> 00:15:35.160
is something that maybe we did not capture as much,
00:15:35.360 --> 00:15:36.580
like basic things,
00:15:37.110 --> 00:15:38.640
like literally just going to GitHub
00:15:39.000 --> 00:15:41.440
and like switching some switches
00:15:41.800 --> 00:15:44.160
on the configurations of like your repository.
00:15:44.620 --> 00:15:46.320
Some of those things maybe were missing.
00:15:46.430 --> 00:15:48.460
And I think there's value on that for people
00:15:48.600 --> 00:15:51.940
that are like literally nowhere in the security like path.
00:15:52.540 --> 00:15:53.200
But apart from that,
00:15:53.200 --> 00:15:55.300
I think the diversity was really good on the track.
00:15:55.560 --> 00:15:56.500
I love it.
00:15:56.620 --> 00:16:00.140
I think that'd be a great talk to kick off the track and like security 101.
00:16:00.500 --> 00:16:03.420
Let's not get hacked the first week or something like that, you know?
00:16:04.020 --> 00:16:05.140
Maybe I'll do it next year.
00:16:05.680 --> 00:16:06.520
Yes, let's do it.
00:16:06.560 --> 00:16:07.640
I would love to see that.
00:16:08.880 --> 00:16:13.780
Like, for example, maybe just add a little bit of rate limiting and some logging.
00:16:13.890 --> 00:16:15.740
So if something does happen, you could actually tell.
00:16:15.910 --> 00:16:17.240
And, you know, these kinds of things, right?
00:16:17.240 --> 00:16:19.760
It would be, you know, there's a whole list of that stuff, right?
00:16:19.980 --> 00:16:25.000
Another idea that like came up in when we were thinking about how the track went and how the themes.
00:16:25.200 --> 00:16:30.560
this is this is funny to his idea so i you're gonna have to correct me but uh the idea of like
00:16:30.660 --> 00:16:36.140
having a little bit more interactivity uh to kind of shake things up as opposed to it being because
00:16:36.220 --> 00:16:40.400
i mean with security with these talks maybe you're expecting it to i mean it's obviously like more
00:16:40.660 --> 00:16:45.060
experts based but that ends up if you're in a talk format it's mostly talking to people but having
00:16:45.300 --> 00:16:49.120
something like a panel where you start off with like a few questions to kind of set the theme
00:16:49.460 --> 00:16:54.180
and then you kind of open it up to kind of get some vibes from the audience uh about like what
00:16:54.160 --> 00:16:59.600
questions they're having, make it more interactive in that way. That seemed really interesting to me
00:16:59.740 --> 00:17:02.640
as well. So we're going to see if we can experiment with that next year.
00:17:03.240 --> 00:17:05.800
So am I hearing you say there's going to be a one next year?
00:17:06.060 --> 00:17:07.780
We're hoping for it, for sure.
00:17:08.720 --> 00:17:11.640
We think that we should have another one next year. I mean,
00:17:11.980 --> 00:17:15.020
there was no indication that we shouldn't do this again, is what we saw.
00:17:16.079 --> 00:17:18.780
Honestly, I mean, security might be solved next year.
00:17:19.100 --> 00:17:19.800
Oh, yeah.
00:17:19.839 --> 00:17:20.480
That'd be great, wouldn't it?
00:17:20.760 --> 00:17:21.100
For sure.
00:17:21.240 --> 00:17:23.260
AI will solve all of our security problems.
00:17:23.360 --> 00:17:24.900
It's what I've been told, what I've read.
00:17:25.400 --> 00:17:28.060
Mike, you're trying to take us down a path that is a very different path.
00:17:28.940 --> 00:17:32.200
Well, I mean, it's been a few minutes and we haven't said AI yet.
00:17:32.300 --> 00:17:34.720
Well, no, you actually did because you introduced the other tracks.
00:17:35.600 --> 00:17:35.740
Yeah.
00:17:36.310 --> 00:17:39.560
Well, we only mentioned it in passing, but not with regard to this topic.
00:17:39.650 --> 00:17:42.420
I do think actually maybe if we get some time, I do want to talk to you about it.
00:17:43.680 --> 00:17:44.640
There's a lot to cover.
00:17:45.140 --> 00:17:45.960
There is so much.
00:17:46.160 --> 00:17:50.360
Maybe this could just be its own show that we could go into because there is a lot to cover.
00:17:50.580 --> 00:17:52.700
I think there's like positives and negatives,
00:17:53.000 --> 00:17:54.820
and that kind of sums up AI right there, doesn't it?
00:17:55.180 --> 00:17:56.460
It sums up everything, honestly.
00:17:56.740 --> 00:17:58.500
It sums up a lot of life, yes.
00:18:00.380 --> 00:18:00.960
Hey, one second.
00:18:01.779 --> 00:18:04.180
Normally, this would be an ad break from Sentry,
00:18:04.520 --> 00:18:05.220
but not this time.
00:18:05.580 --> 00:18:07.640
Let's just thank them for supporting the show
00:18:07.840 --> 00:18:09.140
and get right back to the conversation.
00:18:09.640 --> 00:18:13.020
Also, visit talkpython.fm/sentry after the show.
00:18:13.260 --> 00:18:13.820
Thanks, Sentry.
00:18:15.020 --> 00:18:16.000
It's a lot of gray.
00:18:16.580 --> 00:18:18.060
Yeah, not so much black and white, a lot of gray.
00:18:19.820 --> 00:18:21.480
So it was like standing room only?
00:18:21.960 --> 00:18:24.820
I mean, that sounds like that bodes well for our next year.
00:18:25.100 --> 00:18:26.180
Yeah, next year, hopefully.
00:18:26.580 --> 00:18:28.420
I mean, it'd be really great to even have a bigger room.
00:18:29.310 --> 00:18:32.720
Or, yeah, we were quite happy with the turnout.
00:18:32.830 --> 00:18:34.920
We had a few talks that basically it was standing room
00:18:35.320 --> 00:18:37.080
and there was nowhere else to come into the room.
00:18:37.400 --> 00:18:40.000
So that's always great to see as an organizer for a first-time event
00:18:40.300 --> 00:18:41.940
is when the room is too small.
00:18:42.380 --> 00:18:43.660
It means you're doing something right.
00:18:44.280 --> 00:18:44.620
Exactly.
00:18:45.960 --> 00:18:49.360
You've overachieved compared to what you were trying to work with or whatever.
00:18:49.780 --> 00:18:52.140
Yeah, I guess just one in the test,
00:18:52.840 --> 00:18:57.140
what was your experience just co-sharing a track and so on?
00:18:57.240 --> 00:18:59.000
What was it like being on that side of the conference?
00:19:00.080 --> 00:19:03.400
I think it was, I thought it was great because I think,
00:19:04.280 --> 00:19:07.740
so I've actually been organizing SyPyre also for a couple of years.
00:19:08.200 --> 00:19:09.280
And for the longest time,
00:19:09.440 --> 00:19:13.040
I've actually tried to bring security as a conversation at SyPyre.
00:19:13.360 --> 00:19:16.000
So I've learned a couple of like reds of a feather session,
00:19:16.460 --> 00:19:19.060
but having a security track seems a little impossible.
00:19:19.500 --> 00:19:31.380
I don't know, like it's so I don't know, like making making this happen at PyCon was it made me really, really happy because it gets you the opportunity to bring people to talk about the things that you really care about.
00:19:31.910 --> 00:19:35.300
Like security in Python is really like personal to me.
00:19:35.400 --> 00:19:36.760
I care a lot about it.
00:19:36.830 --> 00:19:42.800
And I think part of the problem is the lack of awareness of some of the things that we discussed at the shark.
00:19:42.980 --> 00:19:48.580
So I thought it was a great opportunity to just kind of bring that awareness into the table and making it happen.
00:19:48.660 --> 00:19:50.180
Just like being part of that conversation.
00:19:51.000 --> 00:19:53.120
I felt really proud of doing that.
00:19:53.320 --> 00:20:01.940
And I think also, I think like Seth and I and other couple of people we had, I mean, I had a lot of fun reviewing some of the talks that people submitted.
00:20:02.880 --> 00:20:06.500
We were unfortunately like limited to like eight slots.
00:20:06.880 --> 00:20:11.080
But there was a lot of things that I learned by just reading some of the talk proposals.
00:20:11.120 --> 00:20:15.740
So it was like, I think it was also like a learning experience for me to be part of the truck.
00:20:16.120 --> 00:20:29.480
Yeah, I was going to say, compared to Juanita, my experience with organizing sessions and talks and conferences, this is like the very first time that I've like really dipped my toe into organizing at this level for a conference.
00:20:30.320 --> 00:20:32.280
So it was a lot of learning for me.
00:20:32.680 --> 00:20:34.640
And I thought it was a great experience.
00:20:34.860 --> 00:20:38.340
I think other people could definitely like would enjoy doing this too.
00:20:39.060 --> 00:20:46.080
So now I'm like just understanding and learning all of these things that are about how a conference track or a talk schedule is put together.
00:20:46.680 --> 00:20:51.700
And for me, like the day of stuff was like so, so much.
00:20:52.280 --> 00:20:56.420
It's you're running around and it was like very on the fly.
00:20:56.980 --> 00:21:00.980
And, you know, they have all the recommendations that once the ball is rolling, it's like it's rolling.
00:21:01.040 --> 00:21:02.000
And it was really, really fun.
00:21:02.120 --> 00:21:03.660
I don't know. We had a lot of fun up there.
00:21:03.700 --> 00:21:05.280
I think that it was a great session.
00:21:05.660 --> 00:21:07.040
The energy was so positive.
00:21:07.480 --> 00:21:10.760
People are always coming up to you afterwards and saying, oh, that was amazing.
00:21:11.350 --> 00:21:12.760
Thank you for doing this, all of that.
00:21:12.870 --> 00:21:14.580
And it was a really great experience.
00:21:15.240 --> 00:21:15.380
Cool.
00:21:15.810 --> 00:21:17.380
Yeah, PyCon was really fun this year, too.
00:21:17.850 --> 00:21:19.660
I thought Long Beach was a pretty nice venue.
00:21:19.940 --> 00:21:22.580
There's some nice food carts and other things to do there.
00:21:22.760 --> 00:21:24.940
So that was really looking forward to back then.
00:21:25.660 --> 00:21:30.240
Yeah, now that we know the cool little bar open, you know, rooftop bars or outside bars,
00:21:30.460 --> 00:21:34.440
we can just go meet up and hang out with friends or the cool restaurant you want to go back to or whatever.
00:21:34.940 --> 00:21:35.000
Yeah.
00:21:35.740 --> 00:21:45.400
My first event there was to rent one of those like Lime or Bird scooters and just spend an hour riding around the town and the beach just to like get used to it and then going to check in.
00:21:45.720 --> 00:21:46.340
So very fun.
00:21:46.760 --> 00:21:56.080
Let's bring it over to the conference with the first of seven, I think we have seven, six or seven tracks that I put up for us to kind of riff on here.
00:21:56.660 --> 00:22:00.620
And that would be by none other than Mike Fiedler, an anatomy of a fishing campaign.
00:22:01.020 --> 00:22:01.440
What is this?
00:22:01.760 --> 00:22:02.320
Oh, boy.
00:22:02.640 --> 00:22:03.180
What is this?
00:22:03.660 --> 00:22:06.880
So this was the first track of the day, wasn't it?
00:22:07.720 --> 00:22:07.880
Yeah.
00:22:08.280 --> 00:22:09.040
I'll tell you what this is.
00:22:09.190 --> 00:22:10.940
This is why we can't have nice things, Mike.
00:22:11.060 --> 00:22:12.280
This is why we can't have nice things.
00:22:13.380 --> 00:22:14.960
It really is true, right?
00:22:15.120 --> 00:22:21.800
Like there's, for me, it was a good opportunity to kind of do a little storytelling education
00:22:22.760 --> 00:22:25.800
because these are cases that happen, right?
00:22:26.020 --> 00:22:32.019
And this was a novel enough one that I was like, this deserves some disambiguation because
00:22:32.040 --> 00:22:36.160
people hear phishing attack is like, oh yeah, yeah, yeah, yeah. This was different, right?
00:22:36.960 --> 00:22:45.080
And I was very kind of excited to speak and be selected for the spot. And you mentioned standing
00:22:45.160 --> 00:22:49.420
room only. Standing up there on the stage and looking out into a large room and seeing people
00:22:49.700 --> 00:22:56.220
standing at the back wall and not seeing little dotted seats available throughout the room was a
00:22:56.300 --> 00:23:00.720
little intimidating because it's like, you know, sometimes people don't sit in all the seats and
00:23:00.660 --> 00:23:15.520
That's fine. Or like the first two rows are empty. But no, Juanita and Seth had basically packed this room with people, not intentionally, but purely purely by curating the timeline and like setting the tone of like, yeah, this is this is going to be a story.
00:23:16.580 --> 00:23:33.060
And I was able to relate my personal firsthand experience of dealing with a phishing campaign that some of our users were tricked into visiting a website that was basically a proxy for PyPI.
00:23:34.000 --> 00:23:43.800
In previous phishing campaign attempts, a lot of folks talk about building a byte for byte or pixel perfect version of a different website and steering traffic to that.
00:23:44.080 --> 00:24:04.320
Here, they didn't even need to do that. They just threw up another proxy in front of it. And it was, you know, using email addresses that are like publicly available that maintainers put on their GitHub profiles and put in their, you know, Python package metadata. And they farmed out and emailed some unknowable number of maintainers.
00:24:04.560 --> 00:24:07.620
What an interesting security issue, right?
00:24:07.770 --> 00:24:14.840
Like you've got to be pretty sure that the login people use for their GitHub is probably the same email address that they've registered at PyPI.
00:24:15.360 --> 00:24:21.920
And the packages that you want to take over from PyPI linked to their GitHub repo, right?
00:24:22.020 --> 00:24:25.400
It's a really, it really does condense what you've got to do.
00:24:25.740 --> 00:24:26.560
A little bit, right?
00:24:26.680 --> 00:24:30.620
Like so in a lot of phishing campaigns, it's kind of a spray and pray, right?
00:24:30.720 --> 00:24:34.380
They're casting a very wide net and they're going to email 2 million people.
00:24:34.820 --> 00:24:37.440
And if they get two, that's a success for them, right?
00:24:37.960 --> 00:24:40.960
Because we have to defend 100% of the time.
00:24:41.260 --> 00:24:43.640
They only have to be right once or twice, right?
00:24:44.220 --> 00:24:46.100
And they were in this case.
00:24:47.700 --> 00:24:50.760
Again, PyPI is open source, right?
00:24:50.780 --> 00:24:52.220
You can read on the entire code base.
00:24:52.260 --> 00:24:54.220
You can see what our email templates look like.
00:24:55.020 --> 00:24:59.720
And you can see that, yeah, we do ask maintainers now and then to do an action.
00:25:00.240 --> 00:25:03.120
And they emailed maintainers and asked them to do an action.
00:25:03.640 --> 00:25:05.600
And these maintainers did an action.
00:25:05.940 --> 00:25:08.160
They did what they were asked to do.
00:25:08.760 --> 00:25:12.600
For example, you emailed people a couple of years ago and said, hey, you need to turn on 2FA.
00:25:12.880 --> 00:25:13.040
Yeah.
00:25:13.460 --> 00:25:15.920
And that's totally legitimate.
00:25:16.040 --> 00:25:19.680
And sometimes we will email people and say, hey, there's a problem with your metadata.
00:25:19.920 --> 00:25:20.720
Go in and fix it.
00:25:20.880 --> 00:25:23.640
We will occasionally tell people there's a problem.
00:25:24.300 --> 00:25:29.060
This one in particular would tell them it wasn't using our email infrastructure.
00:25:29.780 --> 00:25:34.400
You know, if you had anti-spam things, then like maybe it would have caught it.
00:25:34.550 --> 00:25:41.200
But it didn't because the mail was coming from the domain advertised for this hack.
00:25:41.500 --> 00:25:46.960
And it was basically showing instead of PyPI.org, PyPJ.org.
00:25:47.260 --> 00:25:58.560
And I would challenge you at, you know, looking at an email on your phone to hover on a link and see that difference between an I and a J in the lowercase Arial font on your phone.
00:25:58.720 --> 00:26:00.080
Like, you're not going to notice it, right?
00:26:00.320 --> 00:26:03.920
Humans, I have no qualms for the humans that fell for this, right?
00:26:04.100 --> 00:26:06.200
Like, they did what they were supposed to do.
00:26:06.520 --> 00:26:12.920
What was annoying about this attack is we've been talking about 2FA for a very long time now,
00:26:13.360 --> 00:26:16.160
and this is still phishing.
00:26:17.000 --> 00:26:21.280
You know, you can still get phished with certain forms of two-factor authentication,
00:26:21.800 --> 00:26:28.460
notably the time-based one-time password that were TOTP or what folks might think of your, like, QR code.
00:26:28.700 --> 00:26:30.280
or Google Authenticator app,
00:26:30.460 --> 00:26:32.120
all of those things are the same thing.
00:26:32.460 --> 00:26:34.020
Whereas if you used WebAuthn
00:26:34.240 --> 00:26:37.760
or the underlying technology for pass keys
00:26:38.180 --> 00:26:39.280
or like a YubiKey,
00:26:39.960 --> 00:26:43.280
that's requiring a different sort of 2FA
00:26:43.560 --> 00:26:44.860
that is more phishing resistant.
00:26:45.280 --> 00:26:47.560
So anybody who had the phishing resistant part
00:26:47.820 --> 00:26:49.280
was not subject to this attack.
00:26:50.120 --> 00:26:50.500
And then
00:26:50.500 --> 00:26:51.640
I think it might be worth
00:26:51.640 --> 00:26:55.480
maybe just a quick conversation on that
00:26:55.480 --> 00:26:57.379
because I totally agree
00:26:57.400 --> 00:26:59.720
because you could just proxy, they send over the thing,
00:26:59.840 --> 00:27:03.640
and you've got 30, 15, whatever seconds to then, you know,
00:27:03.940 --> 00:27:05.380
curry those credentials over,
00:27:05.540 --> 00:27:08.440
and you probably are fine to hack through with a proxy, right?
00:27:08.700 --> 00:27:12.120
I mean, I think it's, I think the TOTP ones are more,
00:27:12.500 --> 00:27:15.860
like if somebody gets a hold of your credentials and they're leaked, right,
00:27:15.960 --> 00:27:18.500
that's not enough to get in anymore, right?
00:27:19.120 --> 00:27:20.600
Or if they're trying to brute force something,
00:27:21.040 --> 00:27:23.720
that can be a big challenge to limit that.
00:27:23.860 --> 00:27:27.240
But for phishing, it really doesn't add a lot of safety, does it?
00:27:27.440 --> 00:27:36.560
So it doesn't because the session token that you get once you have completed your username password, then you do your TOTP.
00:27:36.940 --> 00:27:38.460
Now you have a session cookie, right?
00:27:38.620 --> 00:27:45.260
This is what your browser uses instead of asking you for your password and to FA every single page view, right?
00:27:45.500 --> 00:27:49.840
You have a session cookie that is good for, I don't know, eight hours or something like that.
00:27:50.460 --> 00:27:52.360
So you don't have to do that all the time.
00:27:52.760 --> 00:27:59.540
And this session cookie is something that they can use to then, they don't even need the TOTP within those 30 seconds.
00:27:59.750 --> 00:28:03.460
They now have a session cookie and use that to log in as you.
00:28:03.820 --> 00:28:08.260
And then the next part that they did was create an API token, publish.
00:28:08.600 --> 00:28:10.860
API tokens today do not have any expiry.
00:28:11.380 --> 00:28:14.380
So they were like, all right, I'm going to create a new API token.
00:28:14.450 --> 00:28:18.000
And now I don't need your username, your password, your TOTP, the session token.
00:28:18.250 --> 00:28:18.960
I don't need any of that.
00:28:19.010 --> 00:28:20.000
I have an API token.
00:28:20.140 --> 00:28:25.840
I can go ahead and do the things that I want to do on this website with this token.
00:28:26.240 --> 00:28:28.860
So I think there's layers of security.
00:28:29.380 --> 00:28:42.940
Something we added in the aftermath of this was if you now are using a session token and it was obtained via TOTP and it's coming from a different IP address, we're not going to accept that.
00:28:42.960 --> 00:28:48.840
We're going to ask you to recertify that you are who you said you were because something is different.
00:28:49.140 --> 00:28:52.240
But if you use WebOFN, then you're fine.
00:28:52.480 --> 00:28:54.780
The people who will get impacted by this
00:28:55.330 --> 00:28:58.180
are folks who are like bouncing between VPNs
00:28:58.360 --> 00:29:00.220
or if you're riding a train
00:29:00.310 --> 00:29:01.760
and you keep changing IP addresses
00:29:02.080 --> 00:29:04.200
as you kind of go to different cell towers,
00:29:04.420 --> 00:29:06.700
which I don't think happens very often, but it can.
00:29:07.540 --> 00:29:09.280
Those are the people who will get caught in that net.
00:29:09.620 --> 00:29:10.700
But it's like, yeah, you know,
00:29:10.820 --> 00:29:12.760
we can't tell that you are who you said you were
00:29:13.100 --> 00:29:14.260
based on those credentials.
00:29:14.380 --> 00:29:14.560
Yeah.
00:29:14.860 --> 00:29:16.020
Juanita, Seth, thoughts?
00:29:16.700 --> 00:29:21.960
I want to say that this was one of my favorite talks of the track because it was very relatable.
00:29:22.560 --> 00:29:26.940
Like a lot of the people that are sitting down in the room are maintainers who published their packages in YPI.
00:29:27.460 --> 00:29:31.340
And just having Mike's perspective on like, oh, this can happen to you.
00:29:31.760 --> 00:29:34.360
Like, you need to be aware of this.
00:29:34.750 --> 00:29:40.600
I think it makes it much more impactful because it's like you are directly affected by some of these things.
00:29:41.040 --> 00:29:49.040
And I think also Mike had a really, he not only told us a story about how all of these bad things happened, but also at the end, a call for action.
00:29:49.220 --> 00:29:53.300
This is the things that you need to do in order to avoid these things from happening to you.
00:29:53.610 --> 00:29:57.380
And so I thought that was really impactful for the people that were sitting down in that room.
00:29:58.220 --> 00:29:58.360
Nice.
00:29:58.630 --> 00:30:08.180
So one of the things I think is, I guess, I'm not sure if you mentioned it, but the result was there were some packages that got malicious code in them and then published a PyPI, right?
00:30:08.740 --> 00:30:10.460
Just one that we know of, right?
00:30:10.600 --> 00:30:14.280
We audited kind of a lot of the attacker signatures and kind of their behaviors.
00:30:14.840 --> 00:30:16.500
We're only able to turn up one.
00:30:16.970 --> 00:30:28.920
So only four of the user accounts of the, again, we have over a million user accounts on PyPI right now, but only four people fell for this phishing and like click through and actually logged in.
00:30:29.760 --> 00:30:34.320
And only one package was kind of harvested and republished.
00:30:35.080 --> 00:30:53.760
And again, that doesn't mean that others weren't created, you know, as a backup, but they went after one that is a dependency of a dependency of a dependency, right? They're working their way through the supply chain. They didn't go after anything that, you know, these other four, sorry, the other three maintainers had.
00:30:53.980 --> 00:30:57.980
They went after the one maintainer who kind of fell for the fish.
00:30:58.960 --> 00:31:03.980
And theirs was a dependency of Hugging Faces, Transformers library.
00:31:04.540 --> 00:31:12.560
And if you're doing anything at all in AI land, which a lot of people are doing a lot in AI land, Transformers is kind of key.
00:31:12.700 --> 00:31:15.160
It gets, I don't know, 30, 40 million downloads a day.
00:31:16.140 --> 00:31:20.600
And Numb to Words is a sub-dependency of Transformers.
00:31:20.680 --> 00:31:26.080
So by publishing a new version of Numb to Words, any Transformers user is going to get it.
00:31:26.380 --> 00:31:26.900
Scary.
00:31:27.520 --> 00:31:32.400
And it's, yeah, you know, and you maybe think I'm going to take on this dependency, so you'll review it.
00:31:32.450 --> 00:31:35.380
But how far down the dependency chain do you follow, right?
00:31:35.580 --> 00:31:38.260
I mean, the answer is like, you know, what was that TV show?
00:31:38.260 --> 00:31:39.160
You are the weakest link.
00:31:39.380 --> 00:31:39.940
Goodbye, right?
00:31:41.080 --> 00:31:43.740
You're only as strong as the weakest link in your chain.
00:31:44.080 --> 00:31:47.940
And we all depend on something and somebody else and somewhere, right?
00:31:48.340 --> 00:31:54.060
None of us are writing 100% everything by ourselves based on like a C standards library.
00:31:54.280 --> 00:31:56.280
Like you didn't write your compiler on your own.
00:31:56.580 --> 00:31:57.640
You used somebody else's.
00:31:57.780 --> 00:31:59.560
You didn't write the Python language on your own.
00:31:59.720 --> 00:32:00.520
You used somebody else's.
00:32:00.720 --> 00:32:05.240
And even if you are authoring Python, you're using tools that somebody else wrote, right?
00:32:05.340 --> 00:32:07.240
You didn't write your editor on your own.
00:32:07.600 --> 00:32:09.400
You didn't write your operating system on your own.
00:32:09.440 --> 00:32:12.740
And again, if you are the one person who has done all of this, I commend you.
00:32:12.840 --> 00:32:17.700
I also think you have put in a lot of effort that is commendable, but is unnecessary in
00:32:17.880 --> 00:32:18.180
today's world.
00:32:18.380 --> 00:32:21.840
but you are likely more secure as a result.
00:32:22.040 --> 00:32:22.180
Yes.
00:32:24.040 --> 00:32:25.380
This portion of Talk Python, I mean,
00:32:25.430 --> 00:32:27.340
is brought to you by our AI tools.
00:32:28.100 --> 00:32:30.120
You know that thing where you ask an AI
00:32:30.490 --> 00:32:31.200
something about Python
00:32:31.440 --> 00:32:33.860
and it confidently tells you about the library version
00:32:34.140 --> 00:32:35.080
from 18 months ago?
00:32:35.820 --> 00:32:37.800
Well, we fixed that, at least for our shows.
00:32:38.600 --> 00:32:42.000
Talk Python and Python Bytes both have MCP servers now.
00:32:42.420 --> 00:32:44.580
Connect Talk Python and your AI can search
00:32:44.920 --> 00:32:48.140
over 550 episodes, full transcripts,
00:32:48.220 --> 00:32:51.260
every guest in the entire course catalog of Talk Python courses,
00:32:52.100 --> 00:32:52.940
ConnectPython Bytes,
00:32:52.940 --> 00:32:57.480
and he gets almost 500 episodes of Python news going back to 2016,
00:32:58.220 --> 00:33:00.520
including every link we've ever put in the show notes.
00:33:00.920 --> 00:33:02.540
This means you can say things like,
00:33:03.060 --> 00:33:06.780
ask Talk Python what astral joining OpenAI means for uv,
00:33:07.620 --> 00:33:10.580
or what has Python Bytes said about Locust,
00:33:10.720 --> 00:33:14.420
and get a real answer with real links, not a hallucination.
00:33:15.040 --> 00:33:16.500
Name one of our shows in your prompt,
00:33:16.760 --> 00:33:18.740
and your AI knows exactly where to look.
00:33:19.200 --> 00:33:20.120
And if you live in the terminal,
00:33:20.480 --> 00:33:22.060
Talk Python now has a CLI too.
00:33:22.520 --> 00:33:26.860
One line, uvtoolinstalltalk-python-cli.
00:33:27.380 --> 00:33:30.620
Then search the episodes, transcripts, guests, and courses
00:33:30.850 --> 00:33:32.480
without ever even opening a browser.
00:33:32.860 --> 00:33:35.960
It's open source and it outputs text, JSON, or Markdown,
00:33:36.420 --> 00:33:39.720
so it also feeds AI tools that don't speak MCP.
00:33:40.260 --> 00:33:41.680
And here's the real reason I built it.
00:33:41.980 --> 00:33:44.560
Both shows cover around 10 years of Python history.
00:33:44.920 --> 00:33:49.360
the people, the decisions, the packages that took over, and the ones that quietly didn't.
00:33:50.020 --> 00:33:56.400
This enhanced access to all of our information is free. No account, no API keys, nothing to buy.
00:33:57.000 --> 00:34:02.320
That history contained in these shows should be there for all of us. So visit talkpython.fm
00:34:02.480 --> 00:34:07.280
and pythonbytes.fm and click the MCP link in the nav bar. Connect them right now to your agents
00:34:07.660 --> 00:34:12.080
so that they will be accessible anytime they're needed in the future. Hope you all enjoy the access.
00:34:13.679 --> 00:34:19.139
One thing that came to mind when I was looking at your talk is this whole concept of dependency
00:34:19.660 --> 00:34:23.020
cooldowns, which is making some waves.
00:34:23.100 --> 00:34:28.659
I think I noticed it pretty early in, put this up for everyone, pretty early, I guess
00:34:28.780 --> 00:34:33.480
with uv, and I think pip is getting it as well, but also some of the other package managers.
00:34:34.020 --> 00:34:38.639
But I've seen it sort of picking up steam in other areas unrelated to Python, other package
00:34:38.840 --> 00:34:39.040
managers.
00:34:39.600 --> 00:34:42.480
So I really like this idea.
00:34:42.740 --> 00:34:43.379
I really like it.
00:34:43.419 --> 00:35:09.840
I think cooldowns are a good idea for your average consumer. So in a different attack that Seth and I talk about later, we talk about how the people without using version pinning or deciding I want to use version 1.0.0 only, if you use unbounded versions, you're going to get the latest one that the registry has to offer.
00:35:09.880 --> 00:35:19.580
And when attackers are looking to exploit you, that's kind of one vector they're looking to exploit to say these people are not pinning their versions.
00:35:20.120 --> 00:35:22.700
Dumb to words was not pinned in Transformers.
00:35:23.520 --> 00:35:25.860
So they're going to get whatever the latest one is.
00:35:26.600 --> 00:35:31.060
Now, sub-dependency pinning and version bounds is a whole other set of conversations.
00:35:31.270 --> 00:35:39.460
But as an end consumer, cooldowns is the easiest way for you to say, I don't want what the latest the registry has.
00:35:39.580 --> 00:35:44.200
I want to wait three days or seven days because in the scope of those three to seven days,
00:35:44.720 --> 00:35:51.420
it is very likely that some security scanners will have chewed through this and noticed
00:35:51.780 --> 00:35:53.540
if there's a problem and reported it.
00:35:53.780 --> 00:35:58.360
And if they have, there is a, again, a very high likelihood that that version is no longer
00:35:58.560 --> 00:36:00.680
available for download in that time.
00:36:00.920 --> 00:36:01.080
Yeah.
00:36:01.480 --> 00:36:05.680
So like you look at cool, the thing I'm linking to is cooldowns.dev.
00:36:05.900 --> 00:36:09.200
And in here, it pointed out, said, does it actually work?
00:36:09.260 --> 00:36:13.720
And they gave some stats, you know, they talk about LiteLLM, some of the other issues that have come along.
00:36:13.900 --> 00:36:24.160
They said, I think within a week, I think 90% of the vulnerable ones were taken down and most of them were taken down within a day or something like that, right?
00:36:24.400 --> 00:36:30.180
Yeah. I mean, a lot of that on PyPI is thanks to our group of volunteer reporters.
00:36:30.720 --> 00:36:33.440
And we don't have any kind of commercial relationship.
00:36:33.660 --> 00:36:36.500
There's just people out there in the community who like scanning stuff.
00:36:36.860 --> 00:36:42.940
There are businesses who do it, and some of them will report back to PyPI and say, hey, we found something fishy, something smelly.
00:36:43.180 --> 00:36:44.460
We recommend you take a look.
00:36:44.920 --> 00:37:05.640
Some of these folks have gotten such a very good or almost zero false positive rate that we kind of allow them on PyPI to put that into an automated quarantine status that requires a human like myself to review it and either clear it or tank it completely.
00:37:05.960 --> 00:37:08.720
But in that interim state, it's no longer downloadable.
00:37:09.080 --> 00:37:16.460
So those like our most notable one is Kamil Mankowski, who works out in Austria, and he
00:37:16.860 --> 00:37:21.860
has gotten it down to like his reports are often within, you know, 30 minutes of publish.
00:37:22.500 --> 00:37:27.020
His tooling has scanned it, analyzed it and reported it back with zero false positives.
00:37:27.460 --> 00:37:30.540
And, you know, that only comes with curation and time.
00:37:30.590 --> 00:37:32.440
And he's doing this as a volunteer effort.
00:37:32.720 --> 00:37:34.000
So kudos out to Kamil.
00:37:34.020 --> 00:37:35.680
It's a lot of data to be processing.
00:37:36.040 --> 00:37:36.220
Yeah.
00:37:36.430 --> 00:37:40.340
I wanted to comment on the cooldowns aspect too, like maybe about like the, who is it
00:37:40.440 --> 00:37:40.680
for?
00:37:40.820 --> 00:37:45.620
Cause I think this, this is always a challenge whenever we're building something at the scale
00:37:45.940 --> 00:37:46.880
of Python, right?
00:37:47.020 --> 00:37:50.180
Where it serves so many different communities and people and right.
00:37:50.240 --> 00:37:54.400
There's people that have, you're on a developer team in a really large organization and you
00:37:54.500 --> 00:37:59.400
have your own like security team who is deciding what your security policies are.
00:37:59.480 --> 00:38:01.440
They're running a mirror of PyPI, right?
00:38:01.540 --> 00:38:02.600
Like all this stuff is happening.
00:38:02.800 --> 00:38:07.780
But then Python also needs to serve like students or people who this is their first programming
00:38:07.980 --> 00:38:08.100
language.
00:38:08.660 --> 00:38:14.280
And my thinking is, is that this sort of config where you set it once and then you don't have
00:38:14.280 --> 00:38:20.120
to think about it and you benefit from this large apparatus that already exists out there
00:38:20.170 --> 00:38:24.120
in PyPI, people that are scanning, people that are manually reviewing things, taking
00:38:24.120 --> 00:38:25.860
them down, all of Mike's work, right?
00:38:25.980 --> 00:38:31.760
Like you get to benefit from all of that work without having to have this massive, you know,
00:38:31.840 --> 00:38:37.140
separate team or policy or having to necessarily think about like reviewing every single dependency
00:38:37.450 --> 00:38:41.120
right like this is something that I don't think that a lot of developers are doing especially not
00:38:41.300 --> 00:38:46.040
students right they want to run pip install with the thing that they want to install either for
00:38:46.050 --> 00:38:50.040
their course or because they're learning they're not necessarily thinking about oh this is
00:38:50.400 --> 00:38:53.980
potentially a way that malware is going to be installed on my system so set like a really
00:38:54.620 --> 00:38:59.900
aggressive like seven days or something like that on your cooldown one time and then you're pretty
00:38:59.920 --> 00:39:05.100
okay. Like, I think a lot of people should probably be using cooldowns, especially for like, developer
00:39:05.400 --> 00:39:09.360
machines or a personal machine that you're running Python on where you're not, you don't have this
00:39:09.520 --> 00:39:14.720
giant security apparatus working for you. Yeah, I want to second that and say that a lot of the
00:39:14.780 --> 00:39:20.620
people that use Python packages have no idea of what is PyPI, where they're coming from, what does
00:39:20.640 --> 00:39:27.200
pip install mean? And so having like, and like, like, seriously, but when I started doing all of
00:39:27.120 --> 00:39:28.240
they say, I had no idea.
00:39:28.700 --> 00:39:29.900
I was just running commands
00:39:29.940 --> 00:39:31.320
that I was reading somewhere in Reddit
00:39:31.580 --> 00:39:32.520
or somewhere else.
00:39:32.960 --> 00:39:36.520
And I think just having some default ways
00:39:36.840 --> 00:39:38.280
of keeping security
00:39:39.320 --> 00:39:42.100
in my own developer environment
00:39:42.540 --> 00:39:43.720
is, I think it's great.
00:39:44.000 --> 00:39:46.240
For the most unexperienced developers,
00:39:46.500 --> 00:39:48.220
this is definitely more usable.
00:39:48.900 --> 00:39:50.060
Yeah, I think it's a great idea.
00:39:50.160 --> 00:39:51.100
I really like the idea.
00:39:51.320 --> 00:39:54.240
So I adopted this to some degree
00:39:54.660 --> 00:39:55.780
and I thought it was amazing.
00:39:56.060 --> 00:39:57.700
And then I ran into some problems.
00:39:58.220 --> 00:40:00.060
And I'd love to hear your thoughts on this.
00:40:00.180 --> 00:40:03.420
So I don't have unpinned dependencies.
00:40:04.180 --> 00:40:08.300
But I use uvpipcompile, which will say, with an update,
00:40:08.370 --> 00:40:10.740
and say, OK, well, I've decided now I'm
00:40:10.740 --> 00:40:11.460
going to release a new version.
00:40:11.560 --> 00:40:14.480
Let's go ahead and do a refresh of the update of the dependencies
00:40:15.299 --> 00:40:16.020
and recompile.
00:40:16.120 --> 00:40:17.520
And it will repin them to the newest.
00:40:17.740 --> 00:40:20.540
And without this cooldown, it'll pin them to the very latest.
00:40:20.750 --> 00:40:23.160
And so if, for some reason, something
00:40:23.180 --> 00:40:29.520
were to git pushed into PyPI an hour ago, and I ran that command, well, I might as well have
00:40:29.700 --> 00:40:34.500
unpinned dependencies, right? So I'm going to put uv pip compile dash dash, like wait, whatever the
00:40:34.580 --> 00:40:40.720
command is, exclude newer one week. And I even put it into the Docker build for all of my server
00:40:40.960 --> 00:40:47.200
stuff so that the Docker build would fail if using a combination of pip audit and this. So if there's
00:40:47.200 --> 00:40:53.140
a CVE, it will fail because there's a problem with one of the packages. And then I would use this
00:40:53.160 --> 00:40:57.480
older ones but here's what i ran into is there would be a cve in something and then it would
00:40:57.820 --> 00:41:03.280
it would window into the seven days ago and the fix would be like one day later but it wouldn't
00:41:03.360 --> 00:41:08.620
allow it to install the one without the cve because that was excluding newer and so then i end up with
00:41:08.680 --> 00:41:13.820
all of these like x ignore this one because this one you know what i mean like it's these two things
00:41:13.980 --> 00:41:17.840
clashing it's kind of like one package says version has to be greater than two on a dependency
00:41:18.060 --> 00:41:21.859
and one says version has to be less than two you're like well now what do i do yeah michael you're
00:41:21.880 --> 00:41:25.900
You're touching on the exact reason why I would have a hard time,
00:41:26.200 --> 00:41:27.540
at least right this moment,
00:41:27.880 --> 00:41:30.440
pushing for dependency cooldowns to be a default.
00:41:31.820 --> 00:41:33.020
It confuses users,
00:41:33.360 --> 00:41:35.840
especially when there are other systems
00:41:36.140 --> 00:41:38.680
that are telling them that they need to resolve a problem.
00:41:39.240 --> 00:41:42.160
And when they run the commands necessary that they know work
00:41:42.360 --> 00:41:43.400
because they've used them before
00:41:44.460 --> 00:41:46.800
to upgrade a dependency to a specific version or whatever,
00:41:47.220 --> 00:41:47.780
they don't work.
00:41:47.900 --> 00:41:49.080
Or they'll say something like,
00:41:49.140 --> 00:41:50.560
oh, that version doesn't exist
00:41:51.579 --> 00:41:53.420
because pip is like literally dropping
00:41:53.820 --> 00:41:55.180
these versions from the candidate pool
00:41:55.270 --> 00:41:56.260
or something like this, right?
00:41:56.580 --> 00:41:57.760
It'll say that version doesn't exist
00:41:58.100 --> 00:41:59.640
and you get these really confusing messages.
00:42:00.560 --> 00:42:01.820
I mean, one day I do,
00:42:02.400 --> 00:42:04.440
I would really like to have something,
00:42:05.000 --> 00:42:07.600
it doesn't necessarily have to be cooldowns,
00:42:07.840 --> 00:42:10.460
but some sort of system that the default is,
00:42:10.800 --> 00:42:11.720
if you are not,
00:42:11.930 --> 00:42:13.420
the way I like to think about it is like,
00:42:13.500 --> 00:42:15.920
if you are not showing through your tool usage,
00:42:16.880 --> 00:42:19.220
whether or not you have like operational maturity
00:42:19.240 --> 00:42:20.940
is kind of how I think about it, right?
00:42:21.040 --> 00:42:22.380
Like you're not using a mirror,
00:42:22.700 --> 00:42:24.160
you're installing direct from latest.
00:42:24.480 --> 00:42:26.780
If you're not showing that sort of operational maturity,
00:42:27.000 --> 00:42:29.140
like asking for a lock or an exact version or whatever,
00:42:29.960 --> 00:42:32.140
then there is some sort of secure default.
00:42:32.440 --> 00:42:34.160
But that secure default policy
00:42:34.820 --> 00:42:36.540
needs to take into account a lot of things.
00:42:36.620 --> 00:42:38.060
And one of those things is
00:42:38.300 --> 00:42:40.920
whether a security vulnerability is being fixed
00:42:41.160 --> 00:42:43.360
by something that is within this cooldown window
00:42:43.560 --> 00:42:44.420
or reviewing window.
00:42:44.600 --> 00:42:46.340
And maybe this can be easier
00:42:46.680 --> 00:42:49.200
if there's more of this happening
00:42:49.220 --> 00:42:54.920
the index side. Like right now, IPI is mostly you upload it, it's immediately available, right? And
00:42:55.000 --> 00:42:59.780
the scan comes after the fact, there's no intermediate step where it's like being reviewed
00:43:00.000 --> 00:43:04.760
because we just can't, there's too much volume. And so like, if we get to a world where that is
00:43:05.060 --> 00:43:09.840
happening, maybe tools can implement this sort of policy a little bit more easily, because it'll be
00:43:10.260 --> 00:43:14.760
for the most part on the index side. But from a tool perspective, it's really difficult to get
00:43:14.940 --> 00:43:21.020
a secure default that takes and respects all of these use cases perfectly right as a default.
00:43:21.740 --> 00:43:22.480
It's very challenging.
00:43:23.200 --> 00:43:29.120
So what you're saying is we need to hire a lot more people to scan packages before they
00:43:29.180 --> 00:43:30.040
get published by BI.
00:43:30.300 --> 00:43:31.200
That's what you say, right?
00:43:32.040 --> 00:43:33.200
I'm open to emails.
00:43:34.820 --> 00:43:40.800
Email Seth at Python.org for any interested parties solving this issue.
00:43:41.560 --> 00:43:41.700
Indeed.
00:43:42.020 --> 00:43:48.900
So earlier, Mike, you talked about API keys and how they're kind of outside the bounds of two-factor and so on.
00:43:49.080 --> 00:43:55.100
So the next talk was Zero Trust in 200 Milliseconds, Identity Per Transaction with Tristan and McKinnon.
00:43:55.380 --> 00:44:06.080
And that comes from FediRAMP, which is a U.S. government thing, the Federal Risk and Authorization Management Program that provides approach to security and risk and so on.
00:44:06.120 --> 00:44:19.180
If I recall correctly, this is kind of a zero trust story where it's every single time you need to use an API key, you have to get a new version of an API key.
00:44:19.540 --> 00:44:20.840
Like, I want to talk to AWS.
00:44:21.210 --> 00:44:21.300
Great.
00:44:21.560 --> 00:44:25.500
Here's a key you can use for two seconds or something, right?
00:44:25.920 --> 00:44:26.440
Use it now.
00:44:27.380 --> 00:44:27.460
Yeah.
00:44:27.540 --> 00:44:28.620
What are your thoughts on this?
00:44:28.630 --> 00:44:29.740
What are the takeaways from this one?
00:44:29.940 --> 00:44:30.180
Anyone?
00:44:31.060 --> 00:44:31.620
How do you feel about it?
00:44:31.760 --> 00:44:34.360
So I was going to say, we're all pointing at each other.
00:44:34.680 --> 00:44:36.020
I really love this talk.
00:44:36.080 --> 00:44:42.580
because it talked about a side of Python and like development that a lot of people don't
00:44:42.940 --> 00:44:47.780
necessarily experience, which is where you work in an industry that's like regulated or needs to
00:44:48.040 --> 00:44:53.960
like implement FedRAMP, right? It is a tone of extra work to do this. And a lot of times it's
00:44:53.960 --> 00:44:59.240
not really talked about a lot online because like you said, that's not necessarily like open source
00:44:59.460 --> 00:45:04.620
communities that are doing this sort of work. It's mostly, you know, industry that is doing these
00:45:04.640 --> 00:45:08.680
things. And so it's like really, really great to see this sort of talk where you're talking about
00:45:08.920 --> 00:45:15.620
something like FedRAMP compliance and zero trust in Python with a lot of different like tools that
00:45:15.760 --> 00:45:21.260
people already use. So like using the AWS SDK and how to implement with this with AWS and then
00:45:21.500 --> 00:45:27.040
extrapolating that out to other different like backends. Right. So it's back end agnostic. I really
00:45:27.160 --> 00:45:31.500
enjoyed this talk because of those reasons. Like this is just stuff that you don't necessarily see
00:45:31.760 --> 00:45:35.120
at PyCon or at open source conferences,
00:45:35.500 --> 00:45:38.280
people talking about federal policy requirements
00:45:38.420 --> 00:45:41.020
and how to implement secure controls like this.
00:45:41.200 --> 00:45:42.700
So really, really interesting talk.
00:45:42.880 --> 00:45:44.680
Yeah, it is a bit of a look in an area
00:45:44.720 --> 00:45:45.580
that you don't normally see.
00:45:45.620 --> 00:45:46.880
And yeah, it's quite cool.
00:45:47.480 --> 00:45:50.660
This next one, the next one is Rust.
00:45:51.380 --> 00:45:52.880
And this by Emma Smith.
00:45:53.260 --> 00:45:55.720
And this one certainly, it's interesting
00:45:56.000 --> 00:45:58.040
because you can debate it technically,
00:45:58.240 --> 00:45:59.540
but then you also have to debate it
00:45:59.660 --> 00:46:01.480
from an organization perspective
00:46:01.500 --> 00:46:09.460
and so on. And the idea is, what if we could have more of CPython written in Rust, right?
00:46:09.980 --> 00:46:15.560
But a lot of the people who work on CPython, hey, guess what? What is the name there? CPython,
00:46:16.040 --> 00:46:20.700
as in the language, our C developers, and they don't necessarily want to rewrite stuff in Rust,
00:46:21.220 --> 00:46:26.300
and they don't necessarily have an expertise in it, and a whole bunch of things like that. So one,
00:46:26.560 --> 00:46:29.140
thoughts on the talk. Two, thoughts on Rust and Python.
00:46:29.240 --> 00:46:53.900
I want to give my thoughts on the talk. I think I love this talk for two reasons. The first one is it was a talk about Rust in a Python conference, which shows the intersection between these two communities. And I think, I mean, I think Emma did a great job of explaining like the technical implications of the migration and like of why we need to do this.
00:46:54.240 --> 00:47:16.100
But at the same time, I think she was very clear about what this means from like a community perspective. And I think part of the talk was actually talking about how can we actually make this happen? Not from a technical perspective, but like from organizing the people and like actually getting the people to like agree with doing this and like how do we make this happen?
00:47:16.560 --> 00:47:21.600
Which I think is very on point with open source and how open source works.
00:47:21.860 --> 00:47:26.840
You don't just make a decision and take a different path on something that you're doing.
00:47:27.180 --> 00:47:31.160
There's a whole lot of people that are involved in making decisions for a specific community.
00:47:31.160 --> 00:47:37.560
And I think Emma did a great job of illustrating how that specific aspect of open source works with this particular talk.
00:47:37.730 --> 00:47:38.340
So I loved it.
00:47:38.660 --> 00:47:46.060
And one of my highlights was that Wido was there and he ended up asking questions to Emma about this particular talk.
00:47:46.200 --> 00:47:50.940
that was like, isn't it cool that you have the creator of Python asking you questions about your
00:47:51.120 --> 00:47:56.520
talk? That was that was one of my highlights. Yeah, from like a security. So I am very
00:47:56.920 --> 00:48:03.960
intrigued about this idea. I, it makes sense. But it's also like you said, like in a social sense,
00:48:04.720 --> 00:48:09.360
extremely challenging. And also even like a technical sense, it's extremely challenging,
00:48:09.580 --> 00:48:14.880
right? This is this is not an easy project. I think that there's maybe when people think about
00:48:14.900 --> 00:48:18.960
rewriting and rust and all of this stuff, right? It's almost kind of like a joke, right? That you
00:48:18.970 --> 00:48:24.460
can all just rewrite it in rust and oh, rust Python already exists. Why? Why would this be hard? Right?
00:48:24.580 --> 00:48:30.860
Like this already exists out there. And it is extremely difficult. I am really excited to talk
00:48:31.120 --> 00:48:37.780
about this at the language summit at EuroPython is a talk there also. And I think that Emma and
00:48:37.960 --> 00:48:43.119
the whole team that's working on rust for Python have their work cut out for them. It's going to be
00:48:43.060 --> 00:48:47.860
long journey. Talking about like just the technical aspect of this, I think that they
00:48:48.400 --> 00:48:55.260
have made a really great choice in which library they're decided to potentially like attack first
00:48:55.480 --> 00:49:01.060
as like a first go, which is Zlib, which is a compression library that's pretty understood,
00:49:01.780 --> 00:49:09.000
processes a lot of like untrusted data, right? So there's the memory management, memory of security
00:49:09.020 --> 00:49:14.120
vulnerability aspect. Not necessarily that Zlib has had a ton of issues in that area,
00:49:14.170 --> 00:49:21.160
but it's a really good one to attack as a first module. Yeah, I'm going to be
00:49:21.160 --> 00:49:24.140
Give us an idea of exactly what they're proposing here. Is this like,
00:49:24.140 --> 00:49:30.300
there are portions of the standard library that right now are pure Python or C, and we propose
00:49:30.300 --> 00:49:36.840
rewriting some of them in Rust? So the proposal right now is to rewrite a single standard library
00:49:36.860 --> 00:49:43.360
module in Rust with the long term goal being maybe more and even potentially the like parts
00:49:43.480 --> 00:49:44.940
of the language being rewritten in Rust.
00:49:44.940 --> 00:49:47.240
So like the I believe it was like legit.
00:49:47.900 --> 00:49:53.220
The just in time compiler was another candidate for like a larger project or maybe like a here
00:49:53.220 --> 00:49:54.500
you can cut your teeth on this.
00:49:54.520 --> 00:49:59.320
We won't merge it, but we'll it'll it'll prove out whether or not the tooling that's around
00:49:59.480 --> 00:50:04.940
this like compiling stuff to Rust and having it actually work for Python would work just
00:50:05.000 --> 00:50:05.700
as an option.
00:50:05.960 --> 00:50:08.020
this got discussed a while back too.
00:50:08.210 --> 00:50:11.100
And so this has kind of been ongoing for quite a long time.
00:50:11.190 --> 00:50:12.600
And so I'm like really excited that this talk,
00:50:12.760 --> 00:50:15.820
this is kind of like the first time that Emma and the team have like poked
00:50:15.920 --> 00:50:19.120
their head out and be like, talk to the wider community about this is happening.
00:50:19.260 --> 00:50:21.140
We're discussing this and what it could mean.
00:50:21.740 --> 00:50:23.000
But yeah, it's going to be a long road ahead.
00:50:23.170 --> 00:50:23.680
I have a feeling.
00:50:24.000 --> 00:50:24.380
So yeah.
00:50:24.670 --> 00:50:25.000
All right.
00:50:25.140 --> 00:50:28.380
Next up, Asleep at the Wheel, S-Bombs for Python Builds.
00:50:28.819 --> 00:50:33.540
Sanchit Seye and Abhishek Reddy Piley.
00:50:34.059 --> 00:50:34.760
Sorry about that.
00:50:35.600 --> 00:50:36.940
Yeah, so SBOMs.
00:50:37.100 --> 00:50:38.840
What are the thoughts on SBOMs, folks?
00:50:39.280 --> 00:50:40.140
We need more of them.
00:50:40.400 --> 00:50:41.080
Yes, and better.
00:50:41.080 --> 00:50:41.840
They need to be accurate.
00:50:42.220 --> 00:50:42.440
Exactly.
00:50:43.740 --> 00:50:52.820
I think, honestly, I was just going to comment really quick that I was very proud of this talk because Abby and Sancheid are both students.
00:50:53.600 --> 00:50:55.160
I think Sancheid is a master's student.
00:50:55.230 --> 00:50:56.200
Abby is a PhD student.
00:50:57.110 --> 00:51:05.240
And as a PhD student, I love to see the research that people are doing in conferences are not academic conferences.
00:51:05.300 --> 00:51:17.860
And I think they have done a really good work on developing their research, but also interacting with the outside community to figure out how to make their tools available and usable.
00:51:18.360 --> 00:51:31.500
I love that they have made their project part of the OpenSSF, like, bigger ecosystem, because that kind of shows how they want to make sure that anything that they're doing is actually usable.
00:51:31.560 --> 00:51:40.260
And yeah, like it's not just a paper about something that's very abstract and not really relevant, but like it's actually something that the community can use and adopt.
00:51:41.120 --> 00:51:42.980
So I'm really proud of this talk.
00:51:43.720 --> 00:51:51.800
Yeah, I was going to add that this talk is the talk that showed me what SBOMIT actually was, which is really, really cool.
00:51:52.760 --> 00:51:53.620
I'd heard of it.
00:51:53.850 --> 00:51:56.620
I kind of knew what it meant, right?
00:51:56.700 --> 00:52:06.240
It's one of these things where there's just so many security tools and approaches and so much area to cover that you kind of like end up knowing about something.
00:52:06.620 --> 00:52:13.260
And, you know, like when you'd maybe reach over there to learn more, but you don't know like how deep the iceberg goes.
00:52:13.300 --> 00:52:20.040
right and how much work had to go into making this basically work like magic to record all of the
00:52:20.110 --> 00:52:25.500
stuff that happened during your build all the network calls all the command invocations and
00:52:25.530 --> 00:52:31.080
how it gets then exported into an s bomb but then also this verifiable record using i believe it's
00:52:31.080 --> 00:52:37.460
called in toto that's what the it is an s vomit um and like how it all works end to end and so it
00:52:37.420 --> 00:52:43.740
just gets my mind thinking about like if we were to release this like either like a build farm for
00:52:43.860 --> 00:52:48.340
PyPI if we ever to work on that project this is the sort of thing that we would like reach for and
00:52:48.440 --> 00:52:52.540
say like okay maybe we could integrate this technology into that or if we were going to
00:52:52.800 --> 00:52:59.800
create a like a recommended builder like a docker image that did building like this would potentially
00:52:59.920 --> 00:53:04.820
be a part of that story where you're recording network calls and then you can get this extremely
00:53:04.840 --> 00:53:09.720
accurate software bill of materials document at the end that shows how a package was built.
00:53:10.160 --> 00:53:14.600
And then you can have that be published with the package or you can use it as a user, however
00:53:14.700 --> 00:53:15.280
you want to use it.
00:53:15.360 --> 00:53:17.000
Like that sort of information is really important.
00:53:17.100 --> 00:53:21.100
And it's really difficult to get after the fact, as opposed to like when it's in flight
00:53:21.500 --> 00:53:24.640
and when the actual programs are doing the installations and the builds and all of that.
00:53:25.200 --> 00:53:26.500
And I think you mentioned...
00:53:26.500 --> 00:53:27.020
Oh, sorry, Godwin.
00:53:27.820 --> 00:53:32.160
I was just going to say that this talk actually did a very good job of making people aware
00:53:32.180 --> 00:53:36.000
that the current tools that generate S-BOMs are not as accurate.
00:53:36.280 --> 00:53:41.620
And there's still a lot of work needed to make S-BOMs actually usable
00:53:43.140 --> 00:53:44.540
within a security perspective.
00:53:44.980 --> 00:53:47.400
And they did a great job of just making that awareness.
00:53:48.160 --> 00:53:50.020
And they also were brave enough to do a demo,
00:53:50.340 --> 00:53:54.200
which is like people now don't do demos because they all break,
00:53:54.460 --> 00:53:55.740
but they did a demo and it worked.
00:53:55.900 --> 00:53:56.700
That was really cool.
00:53:56.920 --> 00:53:57.280
Very cool.
00:53:57.920 --> 00:54:00.800
Seth, you theorized there might be some magical process
00:54:00.820 --> 00:54:04.680
involving cooldowns and pin dependencies and review.
00:54:04.950 --> 00:54:07.980
And maybe SBOMs could be an input to that to say,
00:54:08.100 --> 00:54:09.400
well, this ain't got a problem,
00:54:09.560 --> 00:54:12.220
but it has some source down in the supply chain
00:54:12.560 --> 00:54:14.560
that actually we've discovered is problematic.
00:54:14.610 --> 00:54:16.280
So everything downstream from that,
00:54:16.430 --> 00:54:19.340
we need to check or flag or whatever.
00:54:19.900 --> 00:54:22.180
Yeah, SBOM, the way I think about SBOM
00:54:22.300 --> 00:54:24.840
is mostly as just this third party.
00:54:25.940 --> 00:54:28.100
It's not a part of an ecosystem,
00:54:28.700 --> 00:54:30.560
so it works really well for Python.
00:54:30.680 --> 00:54:33.840
because we have so many Python packages out there
00:54:33.980 --> 00:54:34.660
are not just Python.
00:54:34.940 --> 00:54:37.600
It's like C, Fortran, Rust, JavaScript,
00:54:37.980 --> 00:54:39.640
all of these different ecosystems, right?
00:54:40.000 --> 00:54:40.700
GPU shaders.
00:54:41.120 --> 00:54:42.200
Yeah, GPU shaders.
00:54:42.320 --> 00:54:42.820
Throw them in there.
00:54:42.880 --> 00:54:43.160
Why not?
00:54:43.320 --> 00:54:45.280
I mean, Mike knows this even more than I do.
00:54:45.460 --> 00:54:46.140
Like there's video.
00:54:47.220 --> 00:54:50.420
It's just all sorts of great, great content on PyPI.
00:54:51.640 --> 00:54:53.400
Yeah, not that we encourage that use case.
00:54:53.720 --> 00:54:56.620
But there's a lot of stuff in Python packages
00:54:57.020 --> 00:54:59.380
and SBOMs are a great way to represent
00:54:59.800 --> 00:55:04.120
like the provenance of all that software without it being Python specific.
00:55:04.280 --> 00:55:07.000
For sure. All right. Picking up speed because we got a couple more to go through.
00:55:07.560 --> 00:55:14.620
We've got maybe the follow on or the after case here is post incident runtime S-bomb generation
00:55:15.180 --> 00:55:20.760
from Python memory by Hala, Ali and Andrew Case. And the general idea is there's what you've
00:55:20.820 --> 00:55:27.360
declared to be your supply chain inputs and then there's what's actually there. So maybe look at
00:55:27.300 --> 00:55:28.320
what is loaded into memory?
00:55:28.420 --> 00:55:31.220
And you're like, oh, why is this library also loaded?
00:55:31.880 --> 00:55:35.260
Or some other hacker type of thing got put on the machine
00:55:35.480 --> 00:55:36.180
and then loaded in.
00:55:36.180 --> 00:55:38.860
And now we can detect that through this generation
00:55:39.400 --> 00:55:42.040
of looking at loaded modules and so on, right?
00:55:42.240 --> 00:55:44.460
Yeah, this one, I was really intrigued about this
00:55:44.720 --> 00:55:48.020
because it went so deep into Python memory management
00:55:48.240 --> 00:55:51.020
and how modules are loaded and how functions are called
00:55:51.080 --> 00:55:54.320
like extremely deep dive into this topic.
00:55:54.720 --> 00:55:58.000
And so I was like super I was like in awe watching this talk.
00:55:58.150 --> 00:56:00.740
I was like they just kept on being more cool stuff happening.
00:56:01.120 --> 00:56:03.480
And so I was like looking at like runtime analysis.
00:56:03.630 --> 00:56:05.500
You can see what functions are being called.
00:56:05.810 --> 00:56:09.900
You can like to see whether or not like a CD is affecting your program.
00:56:10.140 --> 00:56:14.020
So you can like introspect your program live while it's running and see whether
00:56:14.950 --> 00:56:16.860
interesting like something is even being used.
00:56:16.860 --> 00:56:20.520
You don't even have to like look at the source code to check or whatever.
00:56:20.650 --> 00:56:23.440
You just look at your program and see if it's using that code.
00:56:23.520 --> 00:56:35.740
Yeah, yeah, because if you bother, and I don't, maybe you all know better than I do, but if I were to speculate, I'd say less than 1% of people actually run pip audit or uv pip audit sort of thing, uv audit, whatever it is, on their code.
00:56:35.900 --> 00:56:43.280
But even if you do, or you look at the CVE and you see one, or maybe get the PendaBot tells you, oh, there's a CVE in one of your dependencies, you better go fix it.
00:56:43.550 --> 00:56:45.980
And then you got to go look and say, does it really matter?
00:56:46.180 --> 00:56:57.320
I remember one of the packages I was using, it said, oh, on Windows, there's this issue that if you take untrusted input and it's a PDF and it's this way, it's going to do this terrible thing.
00:56:57.420 --> 00:57:02.920
I'm like, yeah, but my deployment target is Linux on Docker and my dev machine is Mac.
00:57:03.050 --> 00:57:05.820
And I don't think I've taken untrusted input whatsoever for this.
00:57:05.870 --> 00:57:07.360
And so do I care?
00:57:07.370 --> 00:57:07.940
I don't really care.
00:57:08.280 --> 00:57:08.640
You know what?
00:57:09.020 --> 00:57:10.040
I'm just going to not worry about it.
00:57:10.160 --> 00:57:15.560
But PitBot will fill my build and then we're back to the cooldowns and all that.
00:57:15.720 --> 00:57:18.040
But nonetheless, it's like, I think that's part of the problem.
00:57:18.060 --> 00:57:23.420
And the fact, if you could say somehow combine the CVE and the CVE, actually, I can verify
00:57:23.540 --> 00:57:24.960
it doesn't touch that bit of code.
00:57:25.120 --> 00:57:25.600
That's super cool.
00:57:25.800 --> 00:57:31.500
Yeah, on that front, I think there's an ongoing effort through the open source vulnerability
00:57:31.880 --> 00:57:38.240
database to surface more rich details as to like code paths that are affected.
00:57:38.760 --> 00:57:42.880
So that way you could automatically audit, do I use those code paths?
00:57:43.080 --> 00:57:46.100
and then thus either fail or not fail your build.
00:57:46.820 --> 00:57:48.900
But again, in languages like Python,
00:57:49.200 --> 00:57:51.800
where dynamicism is used,
00:57:52.680 --> 00:57:55.100
getting that an accurate representation
00:57:55.440 --> 00:57:57.440
of am I using that code path
00:57:57.660 --> 00:58:00.120
is often a harder question to answer
00:58:00.620 --> 00:58:03.240
because you don't necessarily even have to import the library
00:58:03.470 --> 00:58:04.580
via an import statement.
00:58:04.750 --> 00:58:05.840
You can use import lib.
00:58:05.950 --> 00:58:08.000
You can do all sorts of other different things.
00:58:08.560 --> 00:58:12.980
So the challenge is how do we surface enough information
00:58:13.000 --> 00:58:17.800
make a confident decision without misleading you down the wrong path.
00:58:18.580 --> 00:58:18.700
Indeed.
00:58:19.420 --> 00:58:22.360
Let's keep moving on because time is a ticking.
00:58:23.040 --> 00:58:28.040
The next one is GitHub Action Security and Python Packages by Andrew Nesbitt.
00:58:28.620 --> 00:58:29.280
So, yeah.
00:58:29.400 --> 00:58:29.780
Terrifying.
00:58:29.980 --> 00:58:31.140
There's some really weird stuff.
00:58:31.140 --> 00:58:32.320
That was very eye-ocaching.
00:58:32.320 --> 00:58:32.460
Weird caching.
00:58:33.280 --> 00:58:34.480
So Andrew's a nerd, right?
00:58:34.700 --> 00:58:36.080
He's the best kind of nerd, right?
00:58:36.180 --> 00:58:38.520
He loves researching things.
00:58:38.560 --> 00:58:39.940
He loves accumulating data.
00:58:40.280 --> 00:58:43.380
He's the author behind Ecosystems.
00:58:43.580 --> 00:58:46.440
That's ecosystem.sys.ms.
00:58:47.040 --> 00:58:51.180
And he analyzes lots of projects
00:58:51.570 --> 00:58:54.140
and was able to analyze a lot of GitHub project
00:58:54.360 --> 00:58:56.740
IPI-linked repositories with Zismore,
00:58:56.990 --> 00:58:58.080
which he did not write.
00:58:58.940 --> 00:59:00.420
But it is a very cool tool
00:59:00.620 --> 00:59:03.160
and great to audit your GitHub actions
00:59:03.740 --> 00:59:04.640
for security vulnerability.
00:59:05.180 --> 00:59:07.720
It's scary what its surface is.
00:59:07.920 --> 00:59:10.240
And when we're talking about
00:59:10.260 --> 00:59:15.300
folks getting started, this should be on that checklist of did you run Zizmor on your repository?
00:59:16.160 --> 00:59:21.220
Better yet, did you add it as a GitHub action to run always on your repository? But, you know,
00:59:21.320 --> 00:59:27.400
it surfaces a lot of easy to fix findings, and then sometimes surfaces the scarier ones of you've
00:59:27.540 --> 00:59:33.660
left yourself open to an injection that leads to a exploit. And he talked about a couple of those.
00:59:33.840 --> 00:59:38.560
Very interesting. Yeah, the GitHub actions have a lot of nuance and weird, there was some weird
00:59:38.700 --> 00:59:45.020
cache poisoning that people could submit PRs that would trigger a GitHub Action build.
00:59:45.720 --> 00:59:53.920
And even if they had no rights to the target system, their PR could point at a malicious
00:59:54.130 --> 00:59:55.360
package somehow.
00:59:55.510 --> 01:00:01.700
And then that would get cached into the actual build because the build ran in the context
01:00:01.900 --> 01:00:03.620
of the target repo.
01:00:04.030 --> 01:00:07.200
And hey, wouldn't it be nice if we could just cache this so we don't save it?
01:00:07.260 --> 01:00:09.440
Maybe we should cache other people's inputs.
01:00:09.800 --> 01:00:11.240
You said all the keywords there, Michael.
01:00:11.310 --> 01:00:12.860
You said pull request and target.
01:00:13.180 --> 01:00:14.760
That is the trigger for a lot of these.
01:00:15.100 --> 01:00:17.180
GitHub Actions has a lot of different trigger keywords.
01:00:17.700 --> 01:00:18.700
Push, pull request.
01:00:19.260 --> 01:00:21.400
There is one called pull request target.
01:00:22.040 --> 01:00:23.920
That one runs on forks.
01:00:24.260 --> 01:00:25.960
It runs with elevated privileges.
01:00:26.700 --> 01:00:28.060
It is dangerous.
01:00:28.400 --> 01:00:30.200
Zismore calls that out as like,
01:00:30.440 --> 01:00:32.300
you are probably using this wrong
01:00:33.010 --> 01:00:34.940
because it is a very sharp, sharp knife.
01:00:35.500 --> 01:00:37.020
If you pick it up the wrong way,
01:00:37.140 --> 01:00:41.320
You have now cut your hand and it's easy to pick up the wrong one.
01:00:41.500 --> 01:00:42.320
So Runs is more.
01:00:42.320 --> 01:00:43.700
Please start trying to juggle three of those.
01:00:44.120 --> 01:00:44.240
Yeah.
01:00:44.660 --> 01:00:45.240
Don't juggle three.
01:00:45.540 --> 01:00:46.140
Runs is more.
01:00:46.440 --> 01:00:47.360
Follow its recommendations.
01:00:47.980 --> 01:00:48.900
Move on with your life.
01:00:49.020 --> 01:00:49.400
All right.
01:00:49.580 --> 01:00:50.900
One more here.
01:00:51.300 --> 01:00:52.700
Breaking Bad packages.
01:00:53.260 --> 01:00:56.260
Why traditional vulnerability tracking fails supply chain attacks.
01:00:56.920 --> 01:00:59.100
Shelby Cunningham and Madison Figuerely.
01:00:59.420 --> 01:01:02.880
So I really like this one because it talks about the CVE system,
01:01:03.380 --> 01:01:06.720
which is something that I've spent way too much time kind of digging around in.
01:01:06.960 --> 01:01:16.580
And it's this challenge between intentional malicious software, like malware that we see on PyPI, and vulnerabilities.
01:01:17.220 --> 01:01:23.400
And I think that there's this, sometimes we use CVEs for malware and sometimes we don't.
01:01:23.760 --> 01:01:26.580
And because if we did, there'd be, you know, millions.
01:01:27.300 --> 01:01:29.200
And it's like, do we, do we not?
01:01:29.340 --> 01:01:30.340
Like, what are the trade-offs?
01:01:30.520 --> 01:01:31.480
Does it overwhelm the system?
01:01:31.700 --> 01:01:32.980
Is it even useful?
01:01:33.480 --> 01:01:50.680
And it talked about all of these different watering hole attacks that ended up publishing malware to different open source ecosystems, including PIPI and how the this vulnerability record like CD or OSV responded in turn and like how people got the word out.
01:01:50.790 --> 01:01:52.240
How did people respond to it?
01:01:53.240 --> 01:01:59.560
And yeah, it's it's really challenging because it feels it feels so close to being the right system to use, but not quite.
01:01:59.920 --> 01:02:02.120
And maybe that means that we need to build a new system.
01:02:02.480 --> 01:02:04.240
Maybe that means that who knows what it means.
01:02:04.680 --> 01:02:06.640
We need to do some more thinking in this area.
01:02:06.920 --> 01:02:12.720
Yeah, I totally see it because malware is not a problem in valid software, right?
01:02:13.460 --> 01:02:15.700
It's just a bad piece of software.
01:02:16.200 --> 01:02:21.620
Whereas if I open up this PDF in Microsoft Word and it turns me into a botnet, that's a CVE.
01:02:21.920 --> 01:02:23.880
Because Microsoft Word isn't intended to be malware.
01:02:24.580 --> 01:02:25.120
All right, folks.
01:02:25.660 --> 01:02:29.880
I think that might be it for the time that we've got.
01:02:30.360 --> 01:02:31.960
So I guess final call to action here.
01:02:32.100 --> 01:02:38.780
We have all these talks on PyCon US, and everyone links to them.
01:02:39.070 --> 01:02:41.940
So every part of the show notes links up to them.
01:02:41.990 --> 01:02:46.720
So I'll put the links in the show page for people listening and their podcast player and so on.
01:02:46.820 --> 01:02:49.360
So go out and check out the interesting talks on YouTube.
01:02:49.820 --> 01:02:50.980
I can put that out there.
01:02:51.300 --> 01:02:53.420
But let's leave it with us.
01:02:53.980 --> 01:02:56.580
Juanita, I'll give you the first word, and you can each answer this one.
01:02:56.920 --> 01:03:01.920
So if everyone out there listening did one thing this week because of this episode,
01:03:02.000 --> 01:03:03.360
because of what they heard us talking about.
01:03:03.450 --> 01:03:04.080
What should they do?
01:03:04.270 --> 01:03:04.920
What would you tell them?
01:03:04.920 --> 01:03:07.140
Like, here's the one thing really I recommend most.
01:03:08.000 --> 01:03:10.420
If it's only one, I'll just pick you, Sizmore.
01:03:11.360 --> 01:03:11.520
Okay.
01:03:12.300 --> 01:03:12.520
Mike?
01:03:13.540 --> 01:03:14.680
Look at trusted publishing.
01:03:15.140 --> 01:03:17.900
Convert at least one of your projects to use it.
01:03:18.140 --> 01:03:20.760
And don't forget to delete the old token.
01:03:21.200 --> 01:03:21.500
Got it.
01:03:21.630 --> 01:03:21.740
Okay.
01:03:22.180 --> 01:03:24.620
Spoken like a person who works on PyPI security.
01:03:25.240 --> 01:03:25.460
Seth?
01:03:25.860 --> 01:03:25.960
Yeah.
01:03:26.010 --> 01:03:31.220
So my recommendation is if after hearing all of these security problems,
01:03:31.580 --> 01:03:37.980
solutions like what's happening in security and how it's not this like solve thing to I'm assuming
01:03:38.140 --> 01:03:42.540
that because you're watching this show that you have an interest in Python and you maybe you even
01:03:42.700 --> 01:03:50.880
work with Python. I would recommend if you depend on Python or third party packages to look upstream
01:03:51.400 --> 01:03:58.000
and to see that all of this work is being done and that there is so much more to do and support
01:03:58.020 --> 01:04:04.160
those open source ecosystems that you depend on to enable them to do security. So whether that's
01:04:04.340 --> 01:04:09.120
donating engineering time, so like working on a security team, making some of these security
01:04:09.500 --> 01:04:13.760
focused contributions to open source projects that you care about, or whether that comes as
01:04:13.880 --> 01:04:17.580
like funding, right? So like donating to the Python Software Foundation, for example,
01:04:18.060 --> 01:04:25.700
nonprofit that is the home for Mike and I's job. Security is not free. It costs a lot of time to
01:04:25.720 --> 01:04:30.180
implement all of these changes that everyone ends up benefiting from anyways. And it really would
01:04:30.280 --> 01:04:36.280
not happen without internal advocates at companies and organizations working with their management and
01:04:36.320 --> 01:04:41.500
all of that to convince them to support open source that they depend on. So that's my recommendation.
01:04:41.820 --> 01:04:46.640
Perfect. And one final thing, maybe Juanita, people want to keep in touch with you.
01:04:46.960 --> 01:04:50.280
Where's, you know, can they follow you on social? Do you got a blog?
01:04:50.780 --> 01:04:56.120
I have a website where I guess I sometimes put things that I have done or I'm doing currently.
01:04:56.660 --> 01:04:58.960
But honestly, the best way to reach me out is probably LinkedIn.
01:04:59.720 --> 01:05:04.340
I try to post where I'm going to be if I'm giving talks, where to find me.
01:05:04.950 --> 01:05:07.100
But if you just want to chat, just message me on LinkedIn.
01:05:07.619 --> 01:05:11.240
I'm very happy to connect with people that are interested in any of the things that I'm working on.
01:05:11.440 --> 01:05:12.200
Right on. Mike?
01:05:12.460 --> 01:05:21.100
Yeah, I have a landing page at MikeTheMan.dev, and that will link you out to all of my other different locations, socials, blogs, etc.
01:05:22.160 --> 01:05:29.400
And that is, yeah, I'm also on LinkedIn, but I also try to post on all the different socials of like, yep, I'm going to be at EuroPython.
01:05:29.600 --> 01:05:30.380
Here's where I'm going to be.
01:05:30.980 --> 01:05:37.000
So that way people can accost me on the hallway track and demand some new security feature, which is wonderful.
01:05:37.310 --> 01:05:38.240
Love talking about it.
01:05:38.240 --> 01:05:40.080
The most well-attended track of the conference indeed.
01:05:40.600 --> 01:05:41.040
Seth.
01:05:41.200 --> 01:05:43.960
Yeah, so you can find me online, sethamlarson.dev.
01:05:44.280 --> 01:05:45.120
Links out to everywhere.
01:05:45.400 --> 01:05:48.140
I prefer Mastodon, but I also respond to LinkedIn.
01:05:49.380 --> 01:05:50.340
And there's even Signal there.
01:05:50.420 --> 01:05:53.860
So if you want to just like privately ask me a security question or something like that,
01:05:53.920 --> 01:05:56.700
or you just want to chat for a second, I respond to Signal.
01:05:57.060 --> 01:05:59.280
So any of those locations work for me.
01:05:59.440 --> 01:06:00.780
I publish a blog there as well.
01:06:00.860 --> 01:06:05.500
So if you want to read anything about security or retro video games, those are your options.
01:06:05.520 --> 01:06:05.700
Solid.
01:06:06.980 --> 01:06:07.100
Great.
01:06:07.220 --> 01:06:08.100
Thank you all for being here.
01:06:08.460 --> 01:06:08.960
See you later.
01:06:09.260 --> 01:06:09.540
Thank you.
01:06:10.560 --> 01:06:12.980
This has been another episode of Talk Python To Me.
01:06:13.360 --> 01:06:14.080
Thank you to our sponsors.
01:06:14.300 --> 01:06:15.620
Be sure to check out what they're offering.
01:06:15.760 --> 01:06:17.140
It really helps support the show.
01:06:17.940 --> 01:06:19.320
Take some stress out of your life.
01:06:19.700 --> 01:06:22.880
Get notified immediately about errors and performance issues
01:06:23.040 --> 01:06:25.140
in your web or mobile applications with Sentry.
01:06:25.660 --> 01:06:28.520
Just visit talkpython.fm/sentry
01:06:28.960 --> 01:06:30.020
and get started for free.
01:06:30.560 --> 01:06:33.020
Be sure to use our code talkpython26.
01:06:33.980 --> 01:06:37.360
That's Talk Python, the numbers two, six, all one word.
01:06:38.740 --> 01:06:42.060
Talk Python and Python Bytes both now have MCP servers.
01:06:42.600 --> 01:06:46.980
Point your AI at 10 plus years of Python episodes, transcripts, and show notes.
01:06:47.390 --> 01:06:47.540
Free.
01:06:48.070 --> 01:06:52.160
Click MCP in the nav at talkpython.fm and at pythonbytes.fm.
01:06:52.940 --> 01:06:54.820
If you or your team needs to learn Python,
01:06:55.010 --> 01:06:59.040
we have over 270 hours of beginner and advanced courses on topics
01:06:59.320 --> 01:07:05.100
ranging from complete beginners to async code, Flask, Django, HTML, and even LLMs.
01:07:05.320 --> 01:07:07.700
Best of all, there's no subscription in sight.
01:07:08.240 --> 01:07:09.920
browse the catalog at talkpython.fm.
01:07:10.660 --> 01:07:12.560
And if you're not already subscribed to the show
01:07:12.800 --> 01:07:13.980
on your favorite podcast player,
01:07:14.640 --> 01:07:15.280
what are you waiting for?
01:07:15.960 --> 01:07:17.720
Just search for Python in your podcast player.
01:07:17.880 --> 01:07:18.700
We should be right at the top.
01:07:19.120 --> 01:07:20.660
If you enjoy that geeky rap song,
01:07:20.770 --> 01:07:21.880
you can download the full track.
01:07:22.090 --> 01:07:24.000
The link is actually in your podcast blur share notes.
01:07:24.840 --> 01:07:26.160
This is your host, Michael Kennedy.
01:07:26.560 --> 01:07:27.620
Thank you so much for listening.
01:07:27.810 --> 01:07:28.620
I really appreciate it.
01:07:29.060 --> 01:07:29.760
I'll see you next time.
01:07:41.640 --> 01:07:44.440
I'm out.
00:00:00.020 --> 00:00:02.720
Security has always been the vegetables of software.
00:00:03.380 --> 00:00:06.740
Everyone agrees it matters, and somehow it never quite makes it onto the plate.
00:00:07.280 --> 00:00:09.600
At PyCon US this year, that changed.
00:00:09.960 --> 00:00:13.460
For the first time ever, security got its own dedicated day-long track,
00:00:13.860 --> 00:00:16.800
one of just two at the whole conference sitting right next to AI.
00:00:17.480 --> 00:00:19.440
And the room was packed to the back wall.
00:00:20.220 --> 00:00:22.820
On this episode, I'm joined by three people at the center of it.
00:00:23.080 --> 00:00:27.500
Seth Larson, security developer in residence at the Python Software Foundation,
00:00:27.940 --> 00:00:31.000
and very recently a CPython core developer,
00:00:31.420 --> 00:00:34.360
Juanita Gomez, a PhD researcher at UC Santa Cruz
00:00:34.700 --> 00:00:37.600
in open source security who co-chaired the track
00:00:37.920 --> 00:00:41.100
and Mike Fiedler, PyPI's safety and security engineer,
00:00:41.460 --> 00:00:43.400
one of the very few people paid full-time
00:00:43.440 --> 00:00:45.860
to keep the packages you install safe.
00:00:46.460 --> 00:00:48.100
We use the arc of the track's talks
00:00:48.300 --> 00:00:51.000
to take the temperature of Python security right now.
00:00:51.140 --> 00:00:53.220
Supply chain attacks, dependency cool-down,
00:00:53.500 --> 00:00:54.520
zero trust, S-bombs,
00:00:54.980 --> 00:00:57.060
and the push to bring Rust into CPython.
00:00:57.660 --> 00:01:01.300
and why not one of us think security is anywhere close to solved.
00:01:01.840 --> 00:01:03.620
And it turns out that's why the room was full.
00:01:04.440 --> 00:01:10.040
This is Talk Python To Me, episode 556, recorded July 6th, 2026.
00:01:11.579 --> 00:01:14.300
Talk Python To Me, yeah, we ready to roll.
00:01:14.760 --> 00:01:17.180
Upgrading the code, no fear of getting old.
00:01:17.300 --> 00:01:19.800
Async in the air, new frameworks in sight.
00:01:20.040 --> 00:01:20.980
Geeky rap on deck.
00:01:21.280 --> 00:01:22.880
Quarth crew, it's time to unite.
00:01:23.140 --> 00:01:26.020
We started in Pyramid, cruising old school lanes.
00:01:26.360 --> 00:01:27.840
Had that stable base, yes sir.
00:01:27.930 --> 00:01:28.920
Welcome to Talk Python To Me,
00:01:29.030 --> 00:01:32.220
the number one Python podcast for developers and data scientists.
00:01:32.800 --> 00:01:34.120
This is your host, Michael Kennedy.
00:01:34.500 --> 00:01:37.980
I'm a PSF fellow who's been coding for over 25 years.
00:01:38.700 --> 00:01:39.760
Let's connect on social media.
00:01:40.140 --> 00:01:43.280
You'll find me and Talk Python on Mastodon, Bluesky, and X.
00:01:43.520 --> 00:01:45.400
The social links are all in your show notes.
00:01:46.160 --> 00:01:49.680
You can find over 10 years of past episodes at talkpython.fm.
00:01:49.860 --> 00:01:53.060
And if you want to be part of the show, you can join our recording live streams.
00:01:53.420 --> 00:01:53.880
That's right.
00:01:54.100 --> 00:01:57.340
We live stream the raw uncut version of each episode on YouTube.
00:01:57.940 --> 00:02:02.360
Just visit talkpython.fm/youtube to see the schedule of upcoming events.
00:02:02.600 --> 00:02:06.220
Be sure to subscribe there and press the bell so you'll get notified anytime we're recording.
00:02:07.040 --> 00:02:08.720
This episode is brought to you by Sentry.
00:02:09.039 --> 00:02:10.280
Don't let those errors go unnoticed.
00:02:10.560 --> 00:02:12.080
Use Sentry like we do here at Talk Python.
00:02:12.580 --> 00:02:15.440
Sign up at talkpython.fm/sentry.
00:02:16.160 --> 00:02:19.400
Talk Python and Python Bytes both now have MCP servers.
00:02:20.080 --> 00:02:24.360
Point your AI at 10 plus years of Python episodes, transcripts, and show notes.
00:02:24.790 --> 00:02:24.920
Free.
00:02:25.470 --> 00:02:29.540
Click MCP in the nav at talkpython.fm and at pythonbytes.fm.
00:02:31.140 --> 00:02:35.120
Juanita, Mike, Seth, welcome all of you to Talk Python.
00:02:35.700 --> 00:02:36.120
Hi.
00:02:36.480 --> 00:02:36.660
Hello.
00:02:37.860 --> 00:02:41.240
Awesome to have some of you back, some of you here for the first time.
00:02:41.350 --> 00:02:42.080
Really, really great.
00:02:42.410 --> 00:02:45.540
So we're going to talk about Python security.
00:02:46.200 --> 00:02:57.800
And I believe, Seth, I saw that you wrote up a post article just thinking back on this kind of unique Python security track and this extra focus at PyCon US this year.
00:02:58.380 --> 00:03:08.180
I thought, hey, that'd be great to just get everyone involved together, at least everyone involved in the track, not all eight, seven or eight speakers, whatever that number adds up to be many, many speakers.
00:03:08.760 --> 00:03:19.360
And just kind of talk broadly about Python security and use this arc of the topics and talks covered at PyCon and the security track as maybe a backdrop.
00:03:19.740 --> 00:03:21.140
So welcome, welcome.
00:03:21.840 --> 00:03:29.820
Now, before we get into that exactly, let's just do quick introductions about who you are and how you're involved in stuff.
00:03:30.060 --> 00:03:31.160
Juanita, you want to kick us off?
00:03:31.360 --> 00:03:31.560
Sure.
00:03:32.300 --> 00:03:33.080
My name is Juanita.
00:03:33.600 --> 00:03:37.060
I am a PhD researcher right now at UC Santa Cruz.
00:03:37.500 --> 00:03:42.180
I work with the hospital at my university doing research in open source security and sustainability.
00:03:42.680 --> 00:03:46.100
And I've been involved in like the Python and the Sign2Pay Python community for a while.
00:03:46.320 --> 00:03:51.000
So, yeah, I got invited to coaching on the track and that was very exciting.
00:03:51.640 --> 00:03:55.600
Very cool. Where are you in your PhD? Are you past qualifying exams?
00:03:56.200 --> 00:03:57.380
I'm graduating in August.
00:03:58.420 --> 00:04:02.260
What? Oh, my God. That's awesome. Congratulations. You're far past it.
00:04:02.780 --> 00:04:04.680
So what's the plans after?
00:04:05.480 --> 00:04:17.880
I just got a job. I can't talk about it yet, but I just got a job. But I'm going to industry. I'm going to keep working on security and sustainability in open source mostly. But yeah, an industry.
00:04:18.320 --> 00:04:23.120
Cool. Congratulations on both finishing the PhD and getting a job straight away. That's super cool.
00:04:23.420 --> 00:04:23.760
Thank you.
00:04:24.160 --> 00:04:25.740
Yeah. Mike, welcome back.
00:04:25.940 --> 00:04:33.720
Hey, glad to be here. Mike Fiedler, PyPI Safety and Security Engineer, working for the Python
00:04:34.160 --> 00:04:40.700
Software Foundation based out of New York City. I'm coming up on my third year here at the PSF,
00:04:40.900 --> 00:04:47.000
which is a full milestone that I will be sharing with my compatriot here, Seth.
00:04:47.640 --> 00:04:53.139
Very cool. And I know thanks for all the work. It's been, I think, pretty impactful in three
00:04:53.160 --> 00:05:00.220
years already. Yeah, it's been kind of a wild ride of kind of incorporating this because I was a
00:05:00.460 --> 00:05:07.980
volunteer PyPI admin and contributor long before this job opened up. And having the ability to sit
00:05:08.080 --> 00:05:16.640
here and think about and work on security features and stuff for PyPI full-time has been a big eye
00:05:16.740 --> 00:05:23.780
opener as to kind of where the gaps were and kind of where they remain, but also kind of what are
00:05:23.900 --> 00:05:29.640
the very important things that we can do in the interim immediately while building up the kind of
00:05:29.780 --> 00:05:36.220
the piece by piece bits that we need to get to these longer term ideas, but being able to kind
00:05:36.220 --> 00:05:41.400
of still make progress while we're getting there. Again, it's that notion of like rebuilding the
00:05:41.400 --> 00:05:45.919
plane while you're flying it. Like, okay, well, we had the plane, but now we're like adding better
00:05:45.940 --> 00:05:51.920
sensors better kind of steering better throttles better better toggles while we're still flying
00:05:52.320 --> 00:05:58.040
and that flight is accelerating yeah 100 and seat belts i think seat belts belong in the security
00:05:58.500 --> 00:06:04.080
airplane analogy uh probably but again it's arguable sometimes seat belts are a problem
00:06:04.350 --> 00:06:10.379
so like yeah it becomes a very good discussion of trade-offs and balances and kind of what what
00:06:10.400 --> 00:06:16.740
actually will move a needle versus this is a nice to have uh you know ashtray yeah ashtrays oh my
00:06:16.740 --> 00:06:23.040
gosh i remember i remember when there are ashtrays on airplanes yeah that was crazy i'm like why is
00:06:23.040 --> 00:06:27.680
there still an ashtray on this airplane like i know they're not gonna let anyone use it fun fact
00:06:27.700 --> 00:06:33.140
they still have them in airplane bathrooms because while it is against the law they still want you to
00:06:33.240 --> 00:06:38.819
have a safe place to throw an ash your cigarette but if you're gonna violate the law so that way
00:06:38.680 --> 00:06:41.620
you don't throw it into the trash can and set something on fire.
00:06:41.880 --> 00:06:48.580
Seems reasonable. Seems reasonable. So as a way of a segue, Mike, I'll have you take this first,
00:06:48.640 --> 00:06:54.640
and then Seth, you can pick this up. You pointed out being full-time on this project versus a bunch
00:06:54.660 --> 00:06:59.560
of kind of contributors who get excited about part of it, but then there's this whole herding
00:06:59.720 --> 00:07:08.640
cats across thousands, hundreds of thousands of projects and users and contributors. And
00:07:08.660 --> 00:07:14.960
role to this versus just like a core dev type of situation, you know? Yeah, I think there's kind of
00:07:14.990 --> 00:07:20.960
two facets here, right? And there is very much a trade-off, right? When it's full-time volunteers,
00:07:21.390 --> 00:07:25.240
you get what you pay for, which is nothing, right? You haven't paid for anything. Volunteers are
00:07:25.240 --> 00:07:29.640
going to do what volunteers want to do, and they're going to do their best effort. When you hire
00:07:29.840 --> 00:07:36.400
somebody, then you set expectations and you try to make sure that you meet them, right? The double-edged
00:07:36.420 --> 00:07:42.580
sword there is that by hiring full-time employees, volunteers often will take a step off because it's
00:07:42.580 --> 00:07:48.060
like, okay, I don't need to volunteer as much as I used to because now someone's getting paid for
00:07:48.400 --> 00:07:54.720
to do it. So it's both a good thing because it highlights and focuses effort on areas that need
00:07:55.000 --> 00:08:02.340
kind of sanitization and focused effort to make progress, but it also gives volunteers a much
00:08:02.360 --> 00:08:08.560
needed break, which then in turn puts more pressure on the full-time employees to execute,
00:08:09.100 --> 00:08:16.560
which again, not enough capacity, not enough time. So we're doing our best here, but it's shown that
00:08:16.780 --> 00:08:23.200
if you do pay for a focused security effort, you do get good security outcome. And I think that's
00:08:23.300 --> 00:08:30.640
the takeaway for me and for anybody is if you pay for it, they will cut. Fair. Seth, welcome back.
00:08:30.920 --> 00:08:31.360
Hey, Michael.
00:08:32.000 --> 00:08:38.140
So quick intro for people who haven't listened to your episodes and then maybe your thoughts on this full-time thing.
00:08:38.340 --> 00:08:43.700
Yeah, so I, everyone, Seth Larson, a security developer in residence at the Python Software Foundation.
00:08:44.340 --> 00:08:49.120
I work primarily on kind of like everything that is not IPI backend.
00:08:49.420 --> 00:08:55.380
So that's the Python language, the runtime, the security response team for Python and pip,
00:08:56.080 --> 00:09:01.420
packaging tools and standards, and then kind of like how Curie World interacts with Python and vice versa.
00:09:01.570 --> 00:09:03.000
Right. So like CBE and all that.
00:09:03.890 --> 00:09:05.600
And recently a core developer, very recently.
00:09:06.740 --> 00:09:12.700
So to answer the how does this role and all that interacting with volunteers,
00:09:13.420 --> 00:09:20.660
My the way that I've tried to like because my space is like so large, my area of where I'm trying to focus.
00:09:21.050 --> 00:09:27.040
What I end up doing is I try to find projects that are obviously like high impact, all of that.
00:09:27.050 --> 00:09:31.420
Right. Like you don't want to be doing things. You don't want to be nibbling or what is the there's a snacking.
00:09:31.680 --> 00:09:38.880
That's the phrase for it. You don't want to be snacking, but you also don't want to be doing things that volunteers could technically do.
00:09:39.280 --> 00:09:50.940
Right. So if it's a job that is or a task or a project that a volunteer could do, maybe I will like pause and wait on that because I'll leave space for someone to potentially contribute there.
00:09:51.120 --> 00:10:08.780
And then the things that are less likely to get volunteer contributions, things like spinning up a CBE numbering authority for the Python Software Foundation or being an admin on the PSRT where or the Python security response team where you're doing things like, OK, we're going to like be monitoring for spam being sent to our email thread.
00:10:08.900 --> 00:10:19.140
Like volunteers maybe don't want to do that, but maybe they would want to be on the security response team contributing to coordinating vulnerability reports and then getting like acknowledged for their work.
00:10:19.340 --> 00:10:21.880
Right. Like in the in the NCD record and advisory.
00:10:22.520 --> 00:10:25.480
So that's kind of like how I think about it, because the area is so wide.
00:10:25.580 --> 00:10:32.680
I try to make sure that I leave space for other people to contribute just in case that people do get around to it before I end up getting to it.
00:10:32.820 --> 00:10:38.080
So we want to build the community volunteer muscle also, not just have it be on work.
00:10:38.100 --> 00:10:50.780
Yeah, that's really cool. How much do you focus on popular third party projects like Django? I mean, Django already has full time people above Flask or something like that versus just pure Python?
00:10:50.940 --> 00:11:01.780
Yeah, so I would say my time doesn't necessarily always like land directly on the project, but I do spend time responding to maintainers if they have questions.
00:11:02.270 --> 00:11:11.080
So like, for example, David from Flask, him and I have talked many times about how to do like a security response program or a threat model or, you know, hey, I'm seeing this.
00:11:11.360 --> 00:11:13.920
Like, can you help? Like, what what should I do in this situation?
00:11:14.100 --> 00:11:19.400
Like, we've talked about that and I've talked about it with many other maintainers, not just Flask, just to try to give them like advice.
00:11:19.740 --> 00:11:27.860
But then also whenever, like one of the nice things about this role being at like a nonprofit is that you can be super, super open.
00:11:28.170 --> 00:11:33.360
You don't have to like keep the secrets to yourself about like what you've done and like how you've seen success.
00:11:33.920 --> 00:11:45.460
So like we publish everything that we do and like where we see success and people in theory can just like take that copy paste it into their projects or their processes and have a better time than they were before.
00:11:45.710 --> 00:11:46.900
So people can learn from each other.
00:11:47.170 --> 00:11:48.680
I really do appreciate that part of the work.
00:11:49.020 --> 00:11:53.360
That is a bit of a unique aspect of doing an open source security thing as opposed to,
00:11:53.380 --> 00:11:54.220
I can't talk about it.
00:11:54.380 --> 00:11:56.000
This is, no, we don't talk about anything.
00:11:56.140 --> 00:11:57.160
So very interesting.
00:11:57.980 --> 00:11:59.320
Let's talk about this track.
00:11:59.860 --> 00:12:04.940
So there's this trailblazing Python security that talks about, for the first time ever,
00:12:05.140 --> 00:12:09.120
a day-long track devoted to the latest in Python security.
00:12:09.400 --> 00:12:14.460
And if you pull up the schedule of talks, I believe it was Saturday was the track.
00:12:15.080 --> 00:12:17.460
And that was, there was just a whole room.
00:12:17.640 --> 00:12:19.380
And what I also liked, it was a room, wasn't it?
00:12:19.660 --> 00:12:22.080
That was like a fixed place, so you didn't have to keep moving.
00:12:22.360 --> 00:12:22.500
Yeah.
00:12:22.760 --> 00:12:27.860
So Juanita, you want to kick us off and talking about why this, why do you guys focus on this
00:12:28.240 --> 00:12:28.680
this year?
00:12:28.840 --> 00:12:32.560
And, you know, why did you decide it's going to take a specific slot in?
00:12:32.940 --> 00:12:35.940
There's only two dedicated slots, security and AI.
00:12:36.180 --> 00:12:37.120
And I think that's very fitting.
00:12:37.380 --> 00:12:38.420
But tell us about this track.
00:12:38.800 --> 00:12:38.940
Okay.
00:12:39.160 --> 00:12:44.780
Well, I will let Seth talk about how did the idea come to place because I was not part
00:12:44.780 --> 00:12:45.040
of that.
00:12:45.240 --> 00:12:47.460
but I'm going to talk about why I think it's important
00:12:47.650 --> 00:12:48.860
and why it was important in the conference.
00:12:49.860 --> 00:12:53.640
I think security is something that's parallel to everything in Python.
00:12:53.970 --> 00:12:56.200
I think that if you're a maintainer for a package,
00:12:56.310 --> 00:12:59.880
I think having security somewhere on your mind should be a thing.
00:13:00.120 --> 00:13:02.700
You should be thinking about security when you're developing a thing.
00:13:03.410 --> 00:13:09.420
And I think there's a big gap in maybe the time that maintainers spend
00:13:09.660 --> 00:13:11.820
thinking about security or even the expertise.
00:13:13.140 --> 00:13:26.440
And so I think this track was like a big opportunity for people that work in PyVon as maintainers or as users to just learn about some important security things when thinking about like their development processes.
00:13:27.079 --> 00:13:32.660
I thought it was great that it was like a dedicated track because I think it highlights the importance of security.
00:13:33.030 --> 00:13:38.980
Like it's not a bunch of talks that are kind of like in the schedule that people just kind of like figure out they want to go to.
00:13:38.980 --> 00:13:42.380
But it's like we like made it a thing by making it like a full track.
00:13:42.980 --> 00:13:50.500
And I think that elevates the importance of security within Python, which I think it's not necessarily always the case.
00:13:50.780 --> 00:13:55.660
I think every time I talk to Mike, I'm like, why are you the only getting paid for doing Python security?
00:13:56.840 --> 00:14:02.680
I think increasing the awareness of the importance of security is very important.
00:14:02.720 --> 00:14:05.280
And I think that the track, I think, was meant to do that.
00:14:05.660 --> 00:14:13.300
How much do you think what were in those seven talks is representative of the broader security
00:14:13.420 --> 00:14:17.380
space, you know, getting your PhD, studying the stuff like you get maybe a little more
00:14:17.540 --> 00:14:18.900
than just Python view?
00:14:19.380 --> 00:14:21.000
Like, what did it capture?
00:14:21.120 --> 00:14:21.760
And what did it miss?
00:14:21.760 --> 00:14:22.000
I guess.
00:14:22.520 --> 00:14:27.960
I think, honestly, we made it a track that was diverse enough that we could capture like
00:14:28.300 --> 00:14:32.960
very different things within the security brother, like image.
00:14:33.500 --> 00:14:38.920
And I also think that a lot of the things that we talked about are not even necessarily Python specific.
00:14:39.460 --> 00:14:41.400
Like you should care about credentials.
00:14:41.690 --> 00:14:43.220
You should care about phishing.
00:14:43.220 --> 00:14:50.000
Like all of these things are things that you should care about, whether you do Python or C or any other like language development.
00:14:51.080 --> 00:14:59.540
I think that something that maybe I was missing a little bit after I like saw maybe after the conference,
00:14:59.820 --> 00:15:07.140
I was thinking about, I would have liked maybe like an intro version of security, something.
00:15:07.290 --> 00:15:12.160
I think something that I work with in my research is actually like security practices,
00:15:13.000 --> 00:15:15.100
mostly for like starting projects.
00:15:15.530 --> 00:15:18.240
I work with like literally university projects.
00:15:19.090 --> 00:15:23.140
And like the goal of my OSP is to improve the practices of the university projects.
00:15:23.580 --> 00:15:27.560
And some of them are maybe not as advanced to take on some of the,
00:15:27.880 --> 00:15:30.120
like I would say more advanced security practices.
00:15:30.640 --> 00:15:32.240
And so maybe something like that
00:15:32.420 --> 00:15:35.160
is something that maybe we did not capture as much,
00:15:35.360 --> 00:15:36.580
like basic things,
00:15:37.110 --> 00:15:38.640
like literally just going to GitHub
00:15:39.000 --> 00:15:41.440
and like switching some switches
00:15:41.800 --> 00:15:44.160
on the configurations of like your repository.
00:15:44.620 --> 00:15:46.320
Some of those things maybe were missing.
00:15:46.430 --> 00:15:48.460
And I think there's value on that for people
00:15:48.600 --> 00:15:51.940
that are like literally nowhere in the security like path.
00:15:52.540 --> 00:15:53.200
But apart from that,
00:15:53.200 --> 00:15:55.300
I think the diversity was really good on the track.
00:15:55.560 --> 00:15:56.500
I love it.
00:15:56.620 --> 00:16:00.140
I think that'd be a great talk to kick off the track and like security 101.
00:16:00.500 --> 00:16:03.420
Let's not get hacked the first week or something like that, you know?
00:16:04.020 --> 00:16:05.140
Maybe I'll do it next year.
00:16:05.680 --> 00:16:06.520
Yes, let's do it.
00:16:06.560 --> 00:16:07.640
I would love to see that.
00:16:08.880 --> 00:16:13.780
Like, for example, maybe just add a little bit of rate limiting and some logging.
00:16:13.890 --> 00:16:15.740
So if something does happen, you could actually tell.
00:16:15.910 --> 00:16:17.240
And, you know, these kinds of things, right?
00:16:17.240 --> 00:16:19.760
It would be, you know, there's a whole list of that stuff, right?
00:16:19.980 --> 00:16:25.000
Another idea that like came up in when we were thinking about how the track went and how the themes.
00:16:25.200 --> 00:16:30.560
this is this is funny to his idea so i you're gonna have to correct me but uh the idea of like
00:16:30.660 --> 00:16:36.140
having a little bit more interactivity uh to kind of shake things up as opposed to it being because
00:16:36.220 --> 00:16:40.400
i mean with security with these talks maybe you're expecting it to i mean it's obviously like more
00:16:40.660 --> 00:16:45.060
experts based but that ends up if you're in a talk format it's mostly talking to people but having
00:16:45.300 --> 00:16:49.120
something like a panel where you start off with like a few questions to kind of set the theme
00:16:49.460 --> 00:16:54.180
and then you kind of open it up to kind of get some vibes from the audience uh about like what
00:16:54.160 --> 00:16:59.600
questions they're having, make it more interactive in that way. That seemed really interesting to me
00:16:59.740 --> 00:17:02.640
as well. So we're going to see if we can experiment with that next year.
00:17:03.240 --> 00:17:05.800
So am I hearing you say there's going to be a one next year?
00:17:06.060 --> 00:17:07.780
We're hoping for it, for sure.
00:17:08.720 --> 00:17:11.640
We think that we should have another one next year. I mean,
00:17:11.980 --> 00:17:15.020
there was no indication that we shouldn't do this again, is what we saw.
00:17:16.079 --> 00:17:18.780
Honestly, I mean, security might be solved next year.
00:17:19.100 --> 00:17:19.800
Oh, yeah.
00:17:19.839 --> 00:17:20.480
That'd be great, wouldn't it?
00:17:20.760 --> 00:17:21.100
For sure.
00:17:21.240 --> 00:17:23.260
AI will solve all of our security problems.
00:17:23.360 --> 00:17:24.900
It's what I've been told, what I've read.
00:17:25.400 --> 00:17:28.060
Mike, you're trying to take us down a path that is a very different path.
00:17:28.940 --> 00:17:32.200
Well, I mean, it's been a few minutes and we haven't said AI yet.
00:17:32.300 --> 00:17:34.720
Well, no, you actually did because you introduced the other tracks.
00:17:35.600 --> 00:17:35.740
Yeah.
00:17:36.310 --> 00:17:39.560
Well, we only mentioned it in passing, but not with regard to this topic.
00:17:39.650 --> 00:17:42.420
I do think actually maybe if we get some time, I do want to talk to you about it.
00:17:43.680 --> 00:17:44.640
There's a lot to cover.
00:17:45.140 --> 00:17:45.960
There is so much.
00:17:46.160 --> 00:17:50.360
Maybe this could just be its own show that we could go into because there is a lot to cover.
00:17:50.580 --> 00:17:52.700
I think there's like positives and negatives,
00:17:53.000 --> 00:17:54.820
and that kind of sums up AI right there, doesn't it?
00:17:55.180 --> 00:17:56.460
It sums up everything, honestly.
00:17:56.740 --> 00:17:58.500
It sums up a lot of life, yes.
00:18:00.380 --> 00:18:00.960
Hey, one second.
00:18:01.779 --> 00:18:04.180
Normally, this would be an ad break from Sentry,
00:18:04.520 --> 00:18:05.220
but not this time.
00:18:05.580 --> 00:18:07.640
Let's just thank them for supporting the show
00:18:07.840 --> 00:18:09.140
and get right back to the conversation.
00:18:09.640 --> 00:18:13.020
Also, visit talkpython.fm/sentry after the show.
00:18:13.260 --> 00:18:13.820
Thanks, Sentry.
00:18:15.020 --> 00:18:16.000
It's a lot of gray.
00:18:16.580 --> 00:18:18.060
Yeah, not so much black and white, a lot of gray.
00:18:19.820 --> 00:18:21.480
So it was like standing room only?
00:18:21.960 --> 00:18:24.820
I mean, that sounds like that bodes well for our next year.
00:18:25.100 --> 00:18:26.180
Yeah, next year, hopefully.
00:18:26.580 --> 00:18:28.420
I mean, it'd be really great to even have a bigger room.
00:18:29.310 --> 00:18:32.720
Or, yeah, we were quite happy with the turnout.
00:18:32.830 --> 00:18:34.920
We had a few talks that basically it was standing room
00:18:35.320 --> 00:18:37.080
and there was nowhere else to come into the room.
00:18:37.400 --> 00:18:40.000
So that's always great to see as an organizer for a first-time event
00:18:40.300 --> 00:18:41.940
is when the room is too small.
00:18:42.380 --> 00:18:43.660
It means you're doing something right.
00:18:44.280 --> 00:18:44.620
Exactly.
00:18:45.960 --> 00:18:49.360
You've overachieved compared to what you were trying to work with or whatever.
00:18:49.780 --> 00:18:52.140
Yeah, I guess just one in the test,
00:18:52.840 --> 00:18:57.140
what was your experience just co-sharing a track and so on?
00:18:57.240 --> 00:18:59.000
What was it like being on that side of the conference?
00:19:00.080 --> 00:19:03.400
I think it was, I thought it was great because I think,
00:19:04.280 --> 00:19:07.740
so I've actually been organizing SyPyre also for a couple of years.
00:19:08.200 --> 00:19:09.280
And for the longest time,
00:19:09.440 --> 00:19:13.040
I've actually tried to bring security as a conversation at SyPyre.
00:19:13.360 --> 00:19:16.000
So I've learned a couple of like reds of a feather session,
00:19:16.460 --> 00:19:19.060
but having a security track seems a little impossible.
00:19:19.500 --> 00:19:31.380
I don't know, like it's so I don't know, like making making this happen at PyCon was it made me really, really happy because it gets you the opportunity to bring people to talk about the things that you really care about.
00:19:31.910 --> 00:19:35.300
Like security in Python is really like personal to me.
00:19:35.400 --> 00:19:36.760
I care a lot about it.
00:19:36.830 --> 00:19:42.800
And I think part of the problem is the lack of awareness of some of the things that we discussed at the shark.
00:19:42.980 --> 00:19:48.580
So I thought it was a great opportunity to just kind of bring that awareness into the table and making it happen.
00:19:48.660 --> 00:19:50.180
Just like being part of that conversation.
00:19:51.000 --> 00:19:53.120
I felt really proud of doing that.
00:19:53.320 --> 00:20:01.940
And I think also, I think like Seth and I and other couple of people we had, I mean, I had a lot of fun reviewing some of the talks that people submitted.
00:20:02.880 --> 00:20:06.500
We were unfortunately like limited to like eight slots.
00:20:06.880 --> 00:20:11.080
But there was a lot of things that I learned by just reading some of the talk proposals.
00:20:11.120 --> 00:20:15.740
So it was like, I think it was also like a learning experience for me to be part of the truck.
00:20:16.120 --> 00:20:29.480
Yeah, I was going to say, compared to Juanita, my experience with organizing sessions and talks and conferences, this is like the very first time that I've like really dipped my toe into organizing at this level for a conference.
00:20:30.320 --> 00:20:32.280
So it was a lot of learning for me.
00:20:32.680 --> 00:20:34.640
And I thought it was a great experience.
00:20:34.860 --> 00:20:38.340
I think other people could definitely like would enjoy doing this too.
00:20:39.060 --> 00:20:46.080
So now I'm like just understanding and learning all of these things that are about how a conference track or a talk schedule is put together.
00:20:46.680 --> 00:20:51.700
And for me, like the day of stuff was like so, so much.
00:20:52.280 --> 00:20:56.420
It's you're running around and it was like very on the fly.
00:20:56.980 --> 00:21:00.980
And, you know, they have all the recommendations that once the ball is rolling, it's like it's rolling.
00:21:01.040 --> 00:21:02.000
And it was really, really fun.
00:21:02.120 --> 00:21:03.660
I don't know. We had a lot of fun up there.
00:21:03.700 --> 00:21:05.280
I think that it was a great session.
00:21:05.660 --> 00:21:07.040
The energy was so positive.
00:21:07.480 --> 00:21:10.760
People are always coming up to you afterwards and saying, oh, that was amazing.
00:21:11.350 --> 00:21:12.760
Thank you for doing this, all of that.
00:21:12.870 --> 00:21:14.580
And it was a really great experience.
00:21:15.240 --> 00:21:15.380
Cool.
00:21:15.810 --> 00:21:17.380
Yeah, PyCon was really fun this year, too.
00:21:17.850 --> 00:21:19.660
I thought Long Beach was a pretty nice venue.
00:21:19.940 --> 00:21:22.580
There's some nice food carts and other things to do there.
00:21:22.760 --> 00:21:24.940
So that was really looking forward to back then.
00:21:25.660 --> 00:21:30.240
Yeah, now that we know the cool little bar open, you know, rooftop bars or outside bars,
00:21:30.460 --> 00:21:34.440
we can just go meet up and hang out with friends or the cool restaurant you want to go back to or whatever.
00:21:34.940 --> 00:21:35.000
Yeah.
00:21:35.740 --> 00:21:45.400
My first event there was to rent one of those like Lime or Bird scooters and just spend an hour riding around the town and the beach just to like get used to it and then going to check in.
00:21:45.720 --> 00:21:46.340
So very fun.
00:21:46.760 --> 00:21:56.080
Let's bring it over to the conference with the first of seven, I think we have seven, six or seven tracks that I put up for us to kind of riff on here.
00:21:56.660 --> 00:22:00.620
And that would be by none other than Mike Fiedler, an anatomy of a fishing campaign.
00:22:01.020 --> 00:22:01.440
What is this?
00:22:01.760 --> 00:22:02.320
Oh, boy.
00:22:02.640 --> 00:22:03.180
What is this?
00:22:03.660 --> 00:22:06.880
So this was the first track of the day, wasn't it?
00:22:07.720 --> 00:22:07.880
Yeah.
00:22:08.280 --> 00:22:09.040
I'll tell you what this is.
00:22:09.190 --> 00:22:10.940
This is why we can't have nice things, Mike.
00:22:11.060 --> 00:22:12.280
This is why we can't have nice things.
00:22:13.380 --> 00:22:14.960
It really is true, right?
00:22:15.120 --> 00:22:21.800
Like there's, for me, it was a good opportunity to kind of do a little storytelling education
00:22:22.760 --> 00:22:25.800
because these are cases that happen, right?
00:22:26.020 --> 00:22:32.019
And this was a novel enough one that I was like, this deserves some disambiguation because
00:22:32.040 --> 00:22:36.160
people hear phishing attack is like, oh yeah, yeah, yeah, yeah. This was different, right?
00:22:36.960 --> 00:22:45.080
And I was very kind of excited to speak and be selected for the spot. And you mentioned standing
00:22:45.160 --> 00:22:49.420
room only. Standing up there on the stage and looking out into a large room and seeing people
00:22:49.700 --> 00:22:56.220
standing at the back wall and not seeing little dotted seats available throughout the room was a
00:22:56.300 --> 00:23:00.720
little intimidating because it's like, you know, sometimes people don't sit in all the seats and
00:23:00.660 --> 00:23:15.520
That's fine. Or like the first two rows are empty. But no, Juanita and Seth had basically packed this room with people, not intentionally, but purely purely by curating the timeline and like setting the tone of like, yeah, this is this is going to be a story.
00:23:16.580 --> 00:23:33.060
And I was able to relate my personal firsthand experience of dealing with a phishing campaign that some of our users were tricked into visiting a website that was basically a proxy for PyPI.
00:23:34.000 --> 00:23:43.800
In previous phishing campaign attempts, a lot of folks talk about building a byte for byte or pixel perfect version of a different website and steering traffic to that.
00:23:44.080 --> 00:24:04.320
Here, they didn't even need to do that. They just threw up another proxy in front of it. And it was, you know, using email addresses that are like publicly available that maintainers put on their GitHub profiles and put in their, you know, Python package metadata. And they farmed out and emailed some unknowable number of maintainers.
00:24:04.560 --> 00:24:07.620
What an interesting security issue, right?
00:24:07.770 --> 00:24:14.840
Like you've got to be pretty sure that the login people use for their GitHub is probably the same email address that they've registered at PyPI.
00:24:15.360 --> 00:24:21.920
And the packages that you want to take over from PyPI linked to their GitHub repo, right?
00:24:22.020 --> 00:24:25.400
It's a really, it really does condense what you've got to do.
00:24:25.740 --> 00:24:26.560
A little bit, right?
00:24:26.680 --> 00:24:30.620
Like so in a lot of phishing campaigns, it's kind of a spray and pray, right?
00:24:30.720 --> 00:24:34.380
They're casting a very wide net and they're going to email 2 million people.
00:24:34.820 --> 00:24:37.440
And if they get two, that's a success for them, right?
00:24:37.960 --> 00:24:40.960
Because we have to defend 100% of the time.
00:24:41.260 --> 00:24:43.640
They only have to be right once or twice, right?
00:24:44.220 --> 00:24:46.100
And they were in this case.
00:24:47.700 --> 00:24:50.760
Again, PyPI is open source, right?
00:24:50.780 --> 00:24:52.220
You can read on the entire code base.
00:24:52.260 --> 00:24:54.220
You can see what our email templates look like.
00:24:55.020 --> 00:24:59.720
And you can see that, yeah, we do ask maintainers now and then to do an action.
00:25:00.240 --> 00:25:03.120
And they emailed maintainers and asked them to do an action.
00:25:03.640 --> 00:25:05.600
And these maintainers did an action.
00:25:05.940 --> 00:25:08.160
They did what they were asked to do.
00:25:08.760 --> 00:25:12.600
For example, you emailed people a couple of years ago and said, hey, you need to turn on 2FA.
00:25:12.880 --> 00:25:13.040
Yeah.
00:25:13.460 --> 00:25:15.920
And that's totally legitimate.
00:25:16.040 --> 00:25:19.680
And sometimes we will email people and say, hey, there's a problem with your metadata.
00:25:19.920 --> 00:25:20.720
Go in and fix it.
00:25:20.880 --> 00:25:23.640
We will occasionally tell people there's a problem.
00:25:24.300 --> 00:25:29.060
This one in particular would tell them it wasn't using our email infrastructure.
00:25:29.780 --> 00:25:34.400
You know, if you had anti-spam things, then like maybe it would have caught it.
00:25:34.550 --> 00:25:41.200
But it didn't because the mail was coming from the domain advertised for this hack.
00:25:41.500 --> 00:25:46.960
And it was basically showing instead of PyPI.org, PyPJ.org.
00:25:47.260 --> 00:25:58.560
And I would challenge you at, you know, looking at an email on your phone to hover on a link and see that difference between an I and a J in the lowercase Arial font on your phone.
00:25:58.720 --> 00:26:00.080
Like, you're not going to notice it, right?
00:26:00.320 --> 00:26:03.920
Humans, I have no qualms for the humans that fell for this, right?
00:26:04.100 --> 00:26:06.200
Like, they did what they were supposed to do.
00:26:06.520 --> 00:26:12.920
What was annoying about this attack is we've been talking about 2FA for a very long time now,
00:26:13.360 --> 00:26:16.160
and this is still phishing.
00:26:17.000 --> 00:26:21.280
You know, you can still get phished with certain forms of two-factor authentication,
00:26:21.800 --> 00:26:28.460
notably the time-based one-time password that were TOTP or what folks might think of your, like, QR code.
00:26:28.700 --> 00:26:30.280
or Google Authenticator app,
00:26:30.460 --> 00:26:32.120
all of those things are the same thing.
00:26:32.460 --> 00:26:34.020
Whereas if you used WebAuthn
00:26:34.240 --> 00:26:37.760
or the underlying technology for pass keys
00:26:38.180 --> 00:26:39.280
or like a YubiKey,
00:26:39.960 --> 00:26:43.280
that's requiring a different sort of 2FA
00:26:43.560 --> 00:26:44.860
that is more phishing resistant.
00:26:45.280 --> 00:26:47.560
So anybody who had the phishing resistant part
00:26:47.820 --> 00:26:49.280
was not subject to this attack.
00:26:50.120 --> 00:26:50.500
And then
00:26:50.500 --> 00:26:51.640
I think it might be worth
00:26:51.640 --> 00:26:55.480
maybe just a quick conversation on that
00:26:55.480 --> 00:26:57.379
because I totally agree
00:26:57.400 --> 00:26:59.720
because you could just proxy, they send over the thing,
00:26:59.840 --> 00:27:03.640
and you've got 30, 15, whatever seconds to then, you know,
00:27:03.940 --> 00:27:05.380
curry those credentials over,
00:27:05.540 --> 00:27:08.440
and you probably are fine to hack through with a proxy, right?
00:27:08.700 --> 00:27:12.120
I mean, I think it's, I think the TOTP ones are more,
00:27:12.500 --> 00:27:15.860
like if somebody gets a hold of your credentials and they're leaked, right,
00:27:15.960 --> 00:27:18.500
that's not enough to get in anymore, right?
00:27:19.120 --> 00:27:20.600
Or if they're trying to brute force something,
00:27:21.040 --> 00:27:23.720
that can be a big challenge to limit that.
00:27:23.860 --> 00:27:27.240
But for phishing, it really doesn't add a lot of safety, does it?
00:27:27.440 --> 00:27:36.560
So it doesn't because the session token that you get once you have completed your username password, then you do your TOTP.
00:27:36.940 --> 00:27:38.460
Now you have a session cookie, right?
00:27:38.620 --> 00:27:45.260
This is what your browser uses instead of asking you for your password and to FA every single page view, right?
00:27:45.500 --> 00:27:49.840
You have a session cookie that is good for, I don't know, eight hours or something like that.
00:27:50.460 --> 00:27:52.360
So you don't have to do that all the time.
00:27:52.760 --> 00:27:59.540
And this session cookie is something that they can use to then, they don't even need the TOTP within those 30 seconds.
00:27:59.750 --> 00:28:03.460
They now have a session cookie and use that to log in as you.
00:28:03.820 --> 00:28:08.260
And then the next part that they did was create an API token, publish.
00:28:08.600 --> 00:28:10.860
API tokens today do not have any expiry.
00:28:11.380 --> 00:28:14.380
So they were like, all right, I'm going to create a new API token.
00:28:14.450 --> 00:28:18.000
And now I don't need your username, your password, your TOTP, the session token.
00:28:18.250 --> 00:28:18.960
I don't need any of that.
00:28:19.010 --> 00:28:20.000
I have an API token.
00:28:20.140 --> 00:28:25.840
I can go ahead and do the things that I want to do on this website with this token.
00:28:26.240 --> 00:28:28.860
So I think there's layers of security.
00:28:29.380 --> 00:28:42.940
Something we added in the aftermath of this was if you now are using a session token and it was obtained via TOTP and it's coming from a different IP address, we're not going to accept that.
00:28:42.960 --> 00:28:48.840
We're going to ask you to recertify that you are who you said you were because something is different.
00:28:49.140 --> 00:28:52.240
But if you use WebOFN, then you're fine.
00:28:52.480 --> 00:28:54.780
The people who will get impacted by this
00:28:55.330 --> 00:28:58.180
are folks who are like bouncing between VPNs
00:28:58.360 --> 00:29:00.220
or if you're riding a train
00:29:00.310 --> 00:29:01.760
and you keep changing IP addresses
00:29:02.080 --> 00:29:04.200
as you kind of go to different cell towers,
00:29:04.420 --> 00:29:06.700
which I don't think happens very often, but it can.
00:29:07.540 --> 00:29:09.280
Those are the people who will get caught in that net.
00:29:09.620 --> 00:29:10.700
But it's like, yeah, you know,
00:29:10.820 --> 00:29:12.760
we can't tell that you are who you said you were
00:29:13.100 --> 00:29:14.260
based on those credentials.
00:29:14.380 --> 00:29:14.560
Yeah.
00:29:14.860 --> 00:29:16.020
Juanita, Seth, thoughts?
00:29:16.700 --> 00:29:21.960
I want to say that this was one of my favorite talks of the track because it was very relatable.
00:29:22.560 --> 00:29:26.940
Like a lot of the people that are sitting down in the room are maintainers who published their packages in YPI.
00:29:27.460 --> 00:29:31.340
And just having Mike's perspective on like, oh, this can happen to you.
00:29:31.760 --> 00:29:34.360
Like, you need to be aware of this.
00:29:34.750 --> 00:29:40.600
I think it makes it much more impactful because it's like you are directly affected by some of these things.
00:29:41.040 --> 00:29:49.040
And I think also Mike had a really, he not only told us a story about how all of these bad things happened, but also at the end, a call for action.
00:29:49.220 --> 00:29:53.300
This is the things that you need to do in order to avoid these things from happening to you.
00:29:53.610 --> 00:29:57.380
And so I thought that was really impactful for the people that were sitting down in that room.
00:29:58.220 --> 00:29:58.360
Nice.
00:29:58.630 --> 00:30:08.180
So one of the things I think is, I guess, I'm not sure if you mentioned it, but the result was there were some packages that got malicious code in them and then published a PyPI, right?
00:30:08.740 --> 00:30:10.460
Just one that we know of, right?
00:30:10.600 --> 00:30:14.280
We audited kind of a lot of the attacker signatures and kind of their behaviors.
00:30:14.840 --> 00:30:16.500
We're only able to turn up one.
00:30:16.970 --> 00:30:28.920
So only four of the user accounts of the, again, we have over a million user accounts on PyPI right now, but only four people fell for this phishing and like click through and actually logged in.
00:30:29.760 --> 00:30:34.320
And only one package was kind of harvested and republished.
00:30:35.080 --> 00:30:53.760
And again, that doesn't mean that others weren't created, you know, as a backup, but they went after one that is a dependency of a dependency of a dependency, right? They're working their way through the supply chain. They didn't go after anything that, you know, these other four, sorry, the other three maintainers had.
00:30:53.980 --> 00:30:57.980
They went after the one maintainer who kind of fell for the fish.
00:30:58.960 --> 00:31:03.980
And theirs was a dependency of Hugging Faces, Transformers library.
00:31:04.540 --> 00:31:12.560
And if you're doing anything at all in AI land, which a lot of people are doing a lot in AI land, Transformers is kind of key.
00:31:12.700 --> 00:31:15.160
It gets, I don't know, 30, 40 million downloads a day.
00:31:16.140 --> 00:31:20.600
And Numb to Words is a sub-dependency of Transformers.
00:31:20.680 --> 00:31:26.080
So by publishing a new version of Numb to Words, any Transformers user is going to get it.
00:31:26.380 --> 00:31:26.900
Scary.
00:31:27.520 --> 00:31:32.400
And it's, yeah, you know, and you maybe think I'm going to take on this dependency, so you'll review it.
00:31:32.450 --> 00:31:35.380
But how far down the dependency chain do you follow, right?
00:31:35.580 --> 00:31:38.260
I mean, the answer is like, you know, what was that TV show?
00:31:38.260 --> 00:31:39.160
You are the weakest link.
00:31:39.380 --> 00:31:39.940
Goodbye, right?
00:31:41.080 --> 00:31:43.740
You're only as strong as the weakest link in your chain.
00:31:44.080 --> 00:31:47.940
And we all depend on something and somebody else and somewhere, right?
00:31:48.340 --> 00:31:54.060
None of us are writing 100% everything by ourselves based on like a C standards library.
00:31:54.280 --> 00:31:56.280
Like you didn't write your compiler on your own.
00:31:56.580 --> 00:31:57.640
You used somebody else's.
00:31:57.780 --> 00:31:59.560
You didn't write the Python language on your own.
00:31:59.720 --> 00:32:00.520
You used somebody else's.
00:32:00.720 --> 00:32:05.240
And even if you are authoring Python, you're using tools that somebody else wrote, right?
00:32:05.340 --> 00:32:07.240
You didn't write your editor on your own.
00:32:07.600 --> 00:32:09.400
You didn't write your operating system on your own.
00:32:09.440 --> 00:32:12.740
And again, if you are the one person who has done all of this, I commend you.
00:32:12.840 --> 00:32:17.700
I also think you have put in a lot of effort that is commendable, but is unnecessary in
00:32:17.880 --> 00:32:18.180
today's world.
00:32:18.380 --> 00:32:21.840
but you are likely more secure as a result.
00:32:22.040 --> 00:32:22.180
Yes.
00:32:24.040 --> 00:32:25.380
This portion of Talk Python, I mean,
00:32:25.430 --> 00:32:27.340
is brought to you by our AI tools.
00:32:28.100 --> 00:32:30.120
You know that thing where you ask an AI
00:32:30.490 --> 00:32:31.200
something about Python
00:32:31.440 --> 00:32:33.860
and it confidently tells you about the library version
00:32:34.140 --> 00:32:35.080
from 18 months ago?
00:32:35.820 --> 00:32:37.800
Well, we fixed that, at least for our shows.
00:32:38.600 --> 00:32:42.000
Talk Python and Python Bytes both have MCP servers now.
00:32:42.420 --> 00:32:44.580
Connect Talk Python and your AI can search
00:32:44.920 --> 00:32:48.140
over 550 episodes, full transcripts,
00:32:48.220 --> 00:32:51.260
every guest in the entire course catalog of Talk Python courses,
00:32:52.100 --> 00:32:52.940
ConnectPython Bytes,
00:32:52.940 --> 00:32:57.480
and he gets almost 500 episodes of Python news going back to 2016,
00:32:58.220 --> 00:33:00.520
including every link we've ever put in the show notes.
00:33:00.920 --> 00:33:02.540
This means you can say things like,
00:33:03.060 --> 00:33:06.780
ask Talk Python what astral joining OpenAI means for uv,
00:33:07.620 --> 00:33:10.580
or what has Python Bytes said about Locust,
00:33:10.720 --> 00:33:14.420
and get a real answer with real links, not a hallucination.
00:33:15.040 --> 00:33:16.500
Name one of our shows in your prompt,
00:33:16.760 --> 00:33:18.740
and your AI knows exactly where to look.
00:33:19.200 --> 00:33:20.120
And if you live in the terminal,
00:33:20.480 --> 00:33:22.060
Talk Python now has a CLI too.
00:33:22.520 --> 00:33:26.860
One line, uvtoolinstalltalk-python-cli.
00:33:27.380 --> 00:33:30.620
Then search the episodes, transcripts, guests, and courses
00:33:30.850 --> 00:33:32.480
without ever even opening a browser.
00:33:32.860 --> 00:33:35.960
It's open source and it outputs text, JSON, or Markdown,
00:33:36.420 --> 00:33:39.720
so it also feeds AI tools that don't speak MCP.
00:33:40.260 --> 00:33:41.680
And here's the real reason I built it.
00:33:41.980 --> 00:33:44.560
Both shows cover around 10 years of Python history.
00:33:44.920 --> 00:33:49.360
the people, the decisions, the packages that took over, and the ones that quietly didn't.
00:33:50.020 --> 00:33:56.400
This enhanced access to all of our information is free. No account, no API keys, nothing to buy.
00:33:57.000 --> 00:34:02.320
That history contained in these shows should be there for all of us. So visit talkpython.fm
00:34:02.480 --> 00:34:07.280
and pythonbytes.fm and click the MCP link in the nav bar. Connect them right now to your agents
00:34:07.660 --> 00:34:12.080
so that they will be accessible anytime they're needed in the future. Hope you all enjoy the access.
00:34:13.679 --> 00:34:19.139
One thing that came to mind when I was looking at your talk is this whole concept of dependency
00:34:19.660 --> 00:34:23.020
cooldowns, which is making some waves.
00:34:23.100 --> 00:34:28.659
I think I noticed it pretty early in, put this up for everyone, pretty early, I guess
00:34:28.780 --> 00:34:33.480
with uv, and I think pip is getting it as well, but also some of the other package managers.
00:34:34.020 --> 00:34:38.639
But I've seen it sort of picking up steam in other areas unrelated to Python, other package
00:34:38.840 --> 00:34:39.040
managers.
00:34:39.600 --> 00:34:42.480
So I really like this idea.
00:34:42.740 --> 00:34:43.379
I really like it.
00:34:43.419 --> 00:35:09.840
I think cooldowns are a good idea for your average consumer. So in a different attack that Seth and I talk about later, we talk about how the people without using version pinning or deciding I want to use version 1.0.0 only, if you use unbounded versions, you're going to get the latest one that the registry has to offer.
00:35:09.880 --> 00:35:19.580
And when attackers are looking to exploit you, that's kind of one vector they're looking to exploit to say these people are not pinning their versions.
00:35:20.120 --> 00:35:22.700
Dumb to words was not pinned in Transformers.
00:35:23.520 --> 00:35:25.860
So they're going to get whatever the latest one is.
00:35:26.600 --> 00:35:31.060
Now, sub-dependency pinning and version bounds is a whole other set of conversations.
00:35:31.270 --> 00:35:39.460
But as an end consumer, cooldowns is the easiest way for you to say, I don't want what the latest the registry has.
00:35:39.580 --> 00:35:44.200
I want to wait three days or seven days because in the scope of those three to seven days,
00:35:44.720 --> 00:35:51.420
it is very likely that some security scanners will have chewed through this and noticed
00:35:51.780 --> 00:35:53.540
if there's a problem and reported it.
00:35:53.780 --> 00:35:58.360
And if they have, there is a, again, a very high likelihood that that version is no longer
00:35:58.560 --> 00:36:00.680
available for download in that time.
00:36:00.920 --> 00:36:01.080
Yeah.
00:36:01.480 --> 00:36:05.680
So like you look at cool, the thing I'm linking to is cooldowns.dev.
00:36:05.900 --> 00:36:09.200
And in here, it pointed out, said, does it actually work?
00:36:09.260 --> 00:36:13.720
And they gave some stats, you know, they talk about LiteLLM, some of the other issues that have come along.
00:36:13.900 --> 00:36:24.160
They said, I think within a week, I think 90% of the vulnerable ones were taken down and most of them were taken down within a day or something like that, right?
00:36:24.400 --> 00:36:30.180
Yeah. I mean, a lot of that on PyPI is thanks to our group of volunteer reporters.
00:36:30.720 --> 00:36:33.440
And we don't have any kind of commercial relationship.
00:36:33.660 --> 00:36:36.500
There's just people out there in the community who like scanning stuff.
00:36:36.860 --> 00:36:42.940
There are businesses who do it, and some of them will report back to PyPI and say, hey, we found something fishy, something smelly.
00:36:43.180 --> 00:36:44.460
We recommend you take a look.
00:36:44.920 --> 00:37:05.640
Some of these folks have gotten such a very good or almost zero false positive rate that we kind of allow them on PyPI to put that into an automated quarantine status that requires a human like myself to review it and either clear it or tank it completely.
00:37:05.960 --> 00:37:08.720
But in that interim state, it's no longer downloadable.
00:37:09.080 --> 00:37:16.460
So those like our most notable one is Kamil Mankowski, who works out in Austria, and he
00:37:16.860 --> 00:37:21.860
has gotten it down to like his reports are often within, you know, 30 minutes of publish.
00:37:22.500 --> 00:37:27.020
His tooling has scanned it, analyzed it and reported it back with zero false positives.
00:37:27.460 --> 00:37:30.540
And, you know, that only comes with curation and time.
00:37:30.590 --> 00:37:32.440
And he's doing this as a volunteer effort.
00:37:32.720 --> 00:37:34.000
So kudos out to Kamil.
00:37:34.020 --> 00:37:35.680
It's a lot of data to be processing.
00:37:36.040 --> 00:37:36.220
Yeah.
00:37:36.430 --> 00:37:40.340
I wanted to comment on the cooldowns aspect too, like maybe about like the, who is it
00:37:40.440 --> 00:37:40.680
for?
00:37:40.820 --> 00:37:45.620
Cause I think this, this is always a challenge whenever we're building something at the scale
00:37:45.940 --> 00:37:46.880
of Python, right?
00:37:47.020 --> 00:37:50.180
Where it serves so many different communities and people and right.
00:37:50.240 --> 00:37:54.400
There's people that have, you're on a developer team in a really large organization and you
00:37:54.500 --> 00:37:59.400
have your own like security team who is deciding what your security policies are.
00:37:59.480 --> 00:38:01.440
They're running a mirror of PyPI, right?
00:38:01.540 --> 00:38:02.600
Like all this stuff is happening.
00:38:02.800 --> 00:38:07.780
But then Python also needs to serve like students or people who this is their first programming
00:38:07.980 --> 00:38:08.100
language.
00:38:08.660 --> 00:38:14.280
And my thinking is, is that this sort of config where you set it once and then you don't have
00:38:14.280 --> 00:38:20.120
to think about it and you benefit from this large apparatus that already exists out there
00:38:20.170 --> 00:38:24.120
in PyPI, people that are scanning, people that are manually reviewing things, taking
00:38:24.120 --> 00:38:25.860
them down, all of Mike's work, right?
00:38:25.980 --> 00:38:31.760
Like you get to benefit from all of that work without having to have this massive, you know,
00:38:31.840 --> 00:38:37.140
separate team or policy or having to necessarily think about like reviewing every single dependency
00:38:37.450 --> 00:38:41.120
right like this is something that I don't think that a lot of developers are doing especially not
00:38:41.300 --> 00:38:46.040
students right they want to run pip install with the thing that they want to install either for
00:38:46.050 --> 00:38:50.040
their course or because they're learning they're not necessarily thinking about oh this is
00:38:50.400 --> 00:38:53.980
potentially a way that malware is going to be installed on my system so set like a really
00:38:54.620 --> 00:38:59.900
aggressive like seven days or something like that on your cooldown one time and then you're pretty
00:38:59.920 --> 00:39:05.100
okay. Like, I think a lot of people should probably be using cooldowns, especially for like, developer
00:39:05.400 --> 00:39:09.360
machines or a personal machine that you're running Python on where you're not, you don't have this
00:39:09.520 --> 00:39:14.720
giant security apparatus working for you. Yeah, I want to second that and say that a lot of the
00:39:14.780 --> 00:39:20.620
people that use Python packages have no idea of what is PyPI, where they're coming from, what does
00:39:20.640 --> 00:39:27.200
pip install mean? And so having like, and like, like, seriously, but when I started doing all of
00:39:27.120 --> 00:39:28.240
they say, I had no idea.
00:39:28.700 --> 00:39:29.900
I was just running commands
00:39:29.940 --> 00:39:31.320
that I was reading somewhere in Reddit
00:39:31.580 --> 00:39:32.520
or somewhere else.
00:39:32.960 --> 00:39:36.520
And I think just having some default ways
00:39:36.840 --> 00:39:38.280
of keeping security
00:39:39.320 --> 00:39:42.100
in my own developer environment
00:39:42.540 --> 00:39:43.720
is, I think it's great.
00:39:44.000 --> 00:39:46.240
For the most unexperienced developers,
00:39:46.500 --> 00:39:48.220
this is definitely more usable.
00:39:48.900 --> 00:39:50.060
Yeah, I think it's a great idea.
00:39:50.160 --> 00:39:51.100
I really like the idea.
00:39:51.320 --> 00:39:54.240
So I adopted this to some degree
00:39:54.660 --> 00:39:55.780
and I thought it was amazing.
00:39:56.060 --> 00:39:57.700
And then I ran into some problems.
00:39:58.220 --> 00:40:00.060
And I'd love to hear your thoughts on this.
00:40:00.180 --> 00:40:03.420
So I don't have unpinned dependencies.
00:40:04.180 --> 00:40:08.300
But I use uvpipcompile, which will say, with an update,
00:40:08.370 --> 00:40:10.740
and say, OK, well, I've decided now I'm
00:40:10.740 --> 00:40:11.460
going to release a new version.
00:40:11.560 --> 00:40:14.480
Let's go ahead and do a refresh of the update of the dependencies
00:40:15.299 --> 00:40:16.020
and recompile.
00:40:16.120 --> 00:40:17.520
And it will repin them to the newest.
00:40:17.740 --> 00:40:20.540
And without this cooldown, it'll pin them to the very latest.
00:40:20.750 --> 00:40:23.160
And so if, for some reason, something
00:40:23.180 --> 00:40:29.520
were to git pushed into PyPI an hour ago, and I ran that command, well, I might as well have
00:40:29.700 --> 00:40:34.500
unpinned dependencies, right? So I'm going to put uv pip compile dash dash, like wait, whatever the
00:40:34.580 --> 00:40:40.720
command is, exclude newer one week. And I even put it into the Docker build for all of my server
00:40:40.960 --> 00:40:47.200
stuff so that the Docker build would fail if using a combination of pip audit and this. So if there's
00:40:47.200 --> 00:40:53.140
a CVE, it will fail because there's a problem with one of the packages. And then I would use this
00:40:53.160 --> 00:40:57.480
older ones but here's what i ran into is there would be a cve in something and then it would
00:40:57.820 --> 00:41:03.280
it would window into the seven days ago and the fix would be like one day later but it wouldn't
00:41:03.360 --> 00:41:08.620
allow it to install the one without the cve because that was excluding newer and so then i end up with
00:41:08.680 --> 00:41:13.820
all of these like x ignore this one because this one you know what i mean like it's these two things
00:41:13.980 --> 00:41:17.840
clashing it's kind of like one package says version has to be greater than two on a dependency
00:41:18.060 --> 00:41:21.859
and one says version has to be less than two you're like well now what do i do yeah michael you're
00:41:21.880 --> 00:41:25.900
You're touching on the exact reason why I would have a hard time,
00:41:26.200 --> 00:41:27.540
at least right this moment,
00:41:27.880 --> 00:41:30.440
pushing for dependency cooldowns to be a default.
00:41:31.820 --> 00:41:33.020
It confuses users,
00:41:33.360 --> 00:41:35.840
especially when there are other systems
00:41:36.140 --> 00:41:38.680
that are telling them that they need to resolve a problem.
00:41:39.240 --> 00:41:42.160
And when they run the commands necessary that they know work
00:41:42.360 --> 00:41:43.400
because they've used them before
00:41:44.460 --> 00:41:46.800
to upgrade a dependency to a specific version or whatever,
00:41:47.220 --> 00:41:47.780
they don't work.
00:41:47.900 --> 00:41:49.080
Or they'll say something like,
00:41:49.140 --> 00:41:50.560
oh, that version doesn't exist
00:41:51.579 --> 00:41:53.420
because pip is like literally dropping
00:41:53.820 --> 00:41:55.180
these versions from the candidate pool
00:41:55.270 --> 00:41:56.260
or something like this, right?
00:41:56.580 --> 00:41:57.760
It'll say that version doesn't exist
00:41:58.100 --> 00:41:59.640
and you get these really confusing messages.
00:42:00.560 --> 00:42:01.820
I mean, one day I do,
00:42:02.400 --> 00:42:04.440
I would really like to have something,
00:42:05.000 --> 00:42:07.600
it doesn't necessarily have to be cooldowns,
00:42:07.840 --> 00:42:10.460
but some sort of system that the default is,
00:42:10.800 --> 00:42:11.720
if you are not,
00:42:11.930 --> 00:42:13.420
the way I like to think about it is like,
00:42:13.500 --> 00:42:15.920
if you are not showing through your tool usage,
00:42:16.880 --> 00:42:19.220
whether or not you have like operational maturity
00:42:19.240 --> 00:42:20.940
is kind of how I think about it, right?
00:42:21.040 --> 00:42:22.380
Like you're not using a mirror,
00:42:22.700 --> 00:42:24.160
you're installing direct from latest.
00:42:24.480 --> 00:42:26.780
If you're not showing that sort of operational maturity,
00:42:27.000 --> 00:42:29.140
like asking for a lock or an exact version or whatever,
00:42:29.960 --> 00:42:32.140
then there is some sort of secure default.
00:42:32.440 --> 00:42:34.160
But that secure default policy
00:42:34.820 --> 00:42:36.540
needs to take into account a lot of things.
00:42:36.620 --> 00:42:38.060
And one of those things is
00:42:38.300 --> 00:42:40.920
whether a security vulnerability is being fixed
00:42:41.160 --> 00:42:43.360
by something that is within this cooldown window
00:42:43.560 --> 00:42:44.420
or reviewing window.
00:42:44.600 --> 00:42:46.340
And maybe this can be easier
00:42:46.680 --> 00:42:49.200
if there's more of this happening
00:42:49.220 --> 00:42:54.920
the index side. Like right now, IPI is mostly you upload it, it's immediately available, right? And
00:42:55.000 --> 00:42:59.780
the scan comes after the fact, there's no intermediate step where it's like being reviewed
00:43:00.000 --> 00:43:04.760
because we just can't, there's too much volume. And so like, if we get to a world where that is
00:43:05.060 --> 00:43:09.840
happening, maybe tools can implement this sort of policy a little bit more easily, because it'll be
00:43:10.260 --> 00:43:14.760
for the most part on the index side. But from a tool perspective, it's really difficult to get
00:43:14.940 --> 00:43:21.020
a secure default that takes and respects all of these use cases perfectly right as a default.
00:43:21.740 --> 00:43:22.480
It's very challenging.
00:43:23.200 --> 00:43:29.120
So what you're saying is we need to hire a lot more people to scan packages before they
00:43:29.180 --> 00:43:30.040
get published by BI.
00:43:30.300 --> 00:43:31.200
That's what you say, right?
00:43:32.040 --> 00:43:33.200
I'm open to emails.
00:43:34.820 --> 00:43:40.800
Email Seth at Python.org for any interested parties solving this issue.
00:43:41.560 --> 00:43:41.700
Indeed.
00:43:42.020 --> 00:43:48.900
So earlier, Mike, you talked about API keys and how they're kind of outside the bounds of two-factor and so on.
00:43:49.080 --> 00:43:55.100
So the next talk was Zero Trust in 200 Milliseconds, Identity Per Transaction with Tristan and McKinnon.
00:43:55.380 --> 00:44:06.080
And that comes from FediRAMP, which is a U.S. government thing, the Federal Risk and Authorization Management Program that provides approach to security and risk and so on.
00:44:06.120 --> 00:44:19.180
If I recall correctly, this is kind of a zero trust story where it's every single time you need to use an API key, you have to get a new version of an API key.
00:44:19.540 --> 00:44:20.840
Like, I want to talk to AWS.
00:44:21.210 --> 00:44:21.300
Great.
00:44:21.560 --> 00:44:25.500
Here's a key you can use for two seconds or something, right?
00:44:25.920 --> 00:44:26.440
Use it now.
00:44:27.380 --> 00:44:27.460
Yeah.
00:44:27.540 --> 00:44:28.620
What are your thoughts on this?
00:44:28.630 --> 00:44:29.740
What are the takeaways from this one?
00:44:29.940 --> 00:44:30.180
Anyone?
00:44:31.060 --> 00:44:31.620
How do you feel about it?
00:44:31.760 --> 00:44:34.360
So I was going to say, we're all pointing at each other.
00:44:34.680 --> 00:44:36.020
I really love this talk.
00:44:36.080 --> 00:44:42.580
because it talked about a side of Python and like development that a lot of people don't
00:44:42.940 --> 00:44:47.780
necessarily experience, which is where you work in an industry that's like regulated or needs to
00:44:48.040 --> 00:44:53.960
like implement FedRAMP, right? It is a tone of extra work to do this. And a lot of times it's
00:44:53.960 --> 00:44:59.240
not really talked about a lot online because like you said, that's not necessarily like open source
00:44:59.460 --> 00:45:04.620
communities that are doing this sort of work. It's mostly, you know, industry that is doing these
00:45:04.640 --> 00:45:08.680
things. And so it's like really, really great to see this sort of talk where you're talking about
00:45:08.920 --> 00:45:15.620
something like FedRAMP compliance and zero trust in Python with a lot of different like tools that
00:45:15.760 --> 00:45:21.260
people already use. So like using the AWS SDK and how to implement with this with AWS and then
00:45:21.500 --> 00:45:27.040
extrapolating that out to other different like backends. Right. So it's back end agnostic. I really
00:45:27.160 --> 00:45:31.500
enjoyed this talk because of those reasons. Like this is just stuff that you don't necessarily see
00:45:31.760 --> 00:45:35.120
at PyCon or at open source conferences,
00:45:35.500 --> 00:45:38.280
people talking about federal policy requirements
00:45:38.420 --> 00:45:41.020
and how to implement secure controls like this.
00:45:41.200 --> 00:45:42.700
So really, really interesting talk.
00:45:42.880 --> 00:45:44.680
Yeah, it is a bit of a look in an area
00:45:44.720 --> 00:45:45.580
that you don't normally see.
00:45:45.620 --> 00:45:46.880
And yeah, it's quite cool.
00:45:47.480 --> 00:45:50.660
This next one, the next one is Rust.
00:45:51.380 --> 00:45:52.880
And this by Emma Smith.
00:45:53.260 --> 00:45:55.720
And this one certainly, it's interesting
00:45:56.000 --> 00:45:58.040
because you can debate it technically,
00:45:58.240 --> 00:45:59.540
but then you also have to debate it
00:45:59.660 --> 00:46:01.480
from an organization perspective
00:46:01.500 --> 00:46:09.460
and so on. And the idea is, what if we could have more of CPython written in Rust, right?
00:46:09.980 --> 00:46:15.560
But a lot of the people who work on CPython, hey, guess what? What is the name there? CPython,
00:46:16.040 --> 00:46:20.700
as in the language, our C developers, and they don't necessarily want to rewrite stuff in Rust,
00:46:21.220 --> 00:46:26.300
and they don't necessarily have an expertise in it, and a whole bunch of things like that. So one,
00:46:26.560 --> 00:46:29.140
thoughts on the talk. Two, thoughts on Rust and Python.
00:46:29.240 --> 00:46:53.900
I want to give my thoughts on the talk. I think I love this talk for two reasons. The first one is it was a talk about Rust in a Python conference, which shows the intersection between these two communities. And I think, I mean, I think Emma did a great job of explaining like the technical implications of the migration and like of why we need to do this.
00:46:54.240 --> 00:47:16.100
But at the same time, I think she was very clear about what this means from like a community perspective. And I think part of the talk was actually talking about how can we actually make this happen? Not from a technical perspective, but like from organizing the people and like actually getting the people to like agree with doing this and like how do we make this happen?
00:47:16.560 --> 00:47:21.600
Which I think is very on point with open source and how open source works.
00:47:21.860 --> 00:47:26.840
You don't just make a decision and take a different path on something that you're doing.
00:47:27.180 --> 00:47:31.160
There's a whole lot of people that are involved in making decisions for a specific community.
00:47:31.160 --> 00:47:37.560
And I think Emma did a great job of illustrating how that specific aspect of open source works with this particular talk.
00:47:37.730 --> 00:47:38.340
So I loved it.
00:47:38.660 --> 00:47:46.060
And one of my highlights was that Wido was there and he ended up asking questions to Emma about this particular talk.
00:47:46.200 --> 00:47:50.940
that was like, isn't it cool that you have the creator of Python asking you questions about your
00:47:51.120 --> 00:47:56.520
talk? That was that was one of my highlights. Yeah, from like a security. So I am very
00:47:56.920 --> 00:48:03.960
intrigued about this idea. I, it makes sense. But it's also like you said, like in a social sense,
00:48:04.720 --> 00:48:09.360
extremely challenging. And also even like a technical sense, it's extremely challenging,
00:48:09.580 --> 00:48:14.880
right? This is this is not an easy project. I think that there's maybe when people think about
00:48:14.900 --> 00:48:18.960
rewriting and rust and all of this stuff, right? It's almost kind of like a joke, right? That you
00:48:18.970 --> 00:48:24.460
can all just rewrite it in rust and oh, rust Python already exists. Why? Why would this be hard? Right?
00:48:24.580 --> 00:48:30.860
Like this already exists out there. And it is extremely difficult. I am really excited to talk
00:48:31.120 --> 00:48:37.780
about this at the language summit at EuroPython is a talk there also. And I think that Emma and
00:48:37.960 --> 00:48:43.119
the whole team that's working on rust for Python have their work cut out for them. It's going to be
00:48:43.060 --> 00:48:47.860
long journey. Talking about like just the technical aspect of this, I think that they
00:48:48.400 --> 00:48:55.260
have made a really great choice in which library they're decided to potentially like attack first
00:48:55.480 --> 00:49:01.060
as like a first go, which is Zlib, which is a compression library that's pretty understood,
00:49:01.780 --> 00:49:09.000
processes a lot of like untrusted data, right? So there's the memory management, memory of security
00:49:09.020 --> 00:49:14.120
vulnerability aspect. Not necessarily that Zlib has had a ton of issues in that area,
00:49:14.170 --> 00:49:21.160
but it's a really good one to attack as a first module. Yeah, I'm going to be
00:49:21.160 --> 00:49:24.140
Give us an idea of exactly what they're proposing here. Is this like,
00:49:24.140 --> 00:49:30.300
there are portions of the standard library that right now are pure Python or C, and we propose
00:49:30.300 --> 00:49:36.840
rewriting some of them in Rust? So the proposal right now is to rewrite a single standard library
00:49:36.860 --> 00:49:43.360
module in Rust with the long term goal being maybe more and even potentially the like parts
00:49:43.480 --> 00:49:44.940
of the language being rewritten in Rust.
00:49:44.940 --> 00:49:47.240
So like the I believe it was like legit.
00:49:47.900 --> 00:49:53.220
The just in time compiler was another candidate for like a larger project or maybe like a here
00:49:53.220 --> 00:49:54.500
you can cut your teeth on this.
00:49:54.520 --> 00:49:59.320
We won't merge it, but we'll it'll it'll prove out whether or not the tooling that's around
00:49:59.480 --> 00:50:04.940
this like compiling stuff to Rust and having it actually work for Python would work just
00:50:05.000 --> 00:50:05.700
as an option.
00:50:05.960 --> 00:50:08.020
this got discussed a while back too.
00:50:08.210 --> 00:50:11.100
And so this has kind of been ongoing for quite a long time.
00:50:11.190 --> 00:50:12.600
And so I'm like really excited that this talk,
00:50:12.760 --> 00:50:15.820
this is kind of like the first time that Emma and the team have like poked
00:50:15.920 --> 00:50:19.120
their head out and be like, talk to the wider community about this is happening.
00:50:19.260 --> 00:50:21.140
We're discussing this and what it could mean.
00:50:21.740 --> 00:50:23.000
But yeah, it's going to be a long road ahead.
00:50:23.170 --> 00:50:23.680
I have a feeling.
00:50:24.000 --> 00:50:24.380
So yeah.
00:50:24.670 --> 00:50:25.000
All right.
00:50:25.140 --> 00:50:28.380
Next up, Asleep at the Wheel, S-Bombs for Python Builds.
00:50:28.819 --> 00:50:33.540
Sanchit Seye and Abhishek Reddy Piley.
00:50:34.059 --> 00:50:34.760
Sorry about that.
00:50:35.600 --> 00:50:36.940
Yeah, so SBOMs.
00:50:37.100 --> 00:50:38.840
What are the thoughts on SBOMs, folks?
00:50:39.280 --> 00:50:40.140
We need more of them.
00:50:40.400 --> 00:50:41.080
Yes, and better.
00:50:41.080 --> 00:50:41.840
They need to be accurate.
00:50:42.220 --> 00:50:42.440
Exactly.
00:50:43.740 --> 00:50:52.820
I think, honestly, I was just going to comment really quick that I was very proud of this talk because Abby and Sancheid are both students.
00:50:53.600 --> 00:50:55.160
I think Sancheid is a master's student.
00:50:55.230 --> 00:50:56.200
Abby is a PhD student.
00:50:57.110 --> 00:51:05.240
And as a PhD student, I love to see the research that people are doing in conferences are not academic conferences.
00:51:05.300 --> 00:51:17.860
And I think they have done a really good work on developing their research, but also interacting with the outside community to figure out how to make their tools available and usable.
00:51:18.360 --> 00:51:31.500
I love that they have made their project part of the OpenSSF, like, bigger ecosystem, because that kind of shows how they want to make sure that anything that they're doing is actually usable.
00:51:31.560 --> 00:51:40.260
And yeah, like it's not just a paper about something that's very abstract and not really relevant, but like it's actually something that the community can use and adopt.
00:51:41.120 --> 00:51:42.980
So I'm really proud of this talk.
00:51:43.720 --> 00:51:51.800
Yeah, I was going to add that this talk is the talk that showed me what SBOMIT actually was, which is really, really cool.
00:51:52.760 --> 00:51:53.620
I'd heard of it.
00:51:53.850 --> 00:51:56.620
I kind of knew what it meant, right?
00:51:56.700 --> 00:52:06.240
It's one of these things where there's just so many security tools and approaches and so much area to cover that you kind of like end up knowing about something.
00:52:06.620 --> 00:52:13.260
And, you know, like when you'd maybe reach over there to learn more, but you don't know like how deep the iceberg goes.
00:52:13.300 --> 00:52:20.040
right and how much work had to go into making this basically work like magic to record all of the
00:52:20.110 --> 00:52:25.500
stuff that happened during your build all the network calls all the command invocations and
00:52:25.530 --> 00:52:31.080
how it gets then exported into an s bomb but then also this verifiable record using i believe it's
00:52:31.080 --> 00:52:37.460
called in toto that's what the it is an s vomit um and like how it all works end to end and so it
00:52:37.420 --> 00:52:43.740
just gets my mind thinking about like if we were to release this like either like a build farm for
00:52:43.860 --> 00:52:48.340
PyPI if we ever to work on that project this is the sort of thing that we would like reach for and
00:52:48.440 --> 00:52:52.540
say like okay maybe we could integrate this technology into that or if we were going to
00:52:52.800 --> 00:52:59.800
create a like a recommended builder like a docker image that did building like this would potentially
00:52:59.920 --> 00:53:04.820
be a part of that story where you're recording network calls and then you can get this extremely
00:53:04.840 --> 00:53:09.720
accurate software bill of materials document at the end that shows how a package was built.
00:53:10.160 --> 00:53:14.600
And then you can have that be published with the package or you can use it as a user, however
00:53:14.700 --> 00:53:15.280
you want to use it.
00:53:15.360 --> 00:53:17.000
Like that sort of information is really important.
00:53:17.100 --> 00:53:21.100
And it's really difficult to get after the fact, as opposed to like when it's in flight
00:53:21.500 --> 00:53:24.640
and when the actual programs are doing the installations and the builds and all of that.
00:53:25.200 --> 00:53:26.500
And I think you mentioned...
00:53:26.500 --> 00:53:27.020
Oh, sorry, Godwin.
00:53:27.820 --> 00:53:32.160
I was just going to say that this talk actually did a very good job of making people aware
00:53:32.180 --> 00:53:36.000
that the current tools that generate S-BOMs are not as accurate.
00:53:36.280 --> 00:53:41.620
And there's still a lot of work needed to make S-BOMs actually usable
00:53:43.140 --> 00:53:44.540
within a security perspective.
00:53:44.980 --> 00:53:47.400
And they did a great job of just making that awareness.
00:53:48.160 --> 00:53:50.020
And they also were brave enough to do a demo,
00:53:50.340 --> 00:53:54.200
which is like people now don't do demos because they all break,
00:53:54.460 --> 00:53:55.740
but they did a demo and it worked.
00:53:55.900 --> 00:53:56.700
That was really cool.
00:53:56.920 --> 00:53:57.280
Very cool.
00:53:57.920 --> 00:54:00.800
Seth, you theorized there might be some magical process
00:54:00.820 --> 00:54:04.680
involving cooldowns and pin dependencies and review.
00:54:04.950 --> 00:54:07.980
And maybe SBOMs could be an input to that to say,
00:54:08.100 --> 00:54:09.400
well, this ain't got a problem,
00:54:09.560 --> 00:54:12.220
but it has some source down in the supply chain
00:54:12.560 --> 00:54:14.560
that actually we've discovered is problematic.
00:54:14.610 --> 00:54:16.280
So everything downstream from that,
00:54:16.430 --> 00:54:19.340
we need to check or flag or whatever.
00:54:19.900 --> 00:54:22.180
Yeah, SBOM, the way I think about SBOM
00:54:22.300 --> 00:54:24.840
is mostly as just this third party.
00:54:25.940 --> 00:54:28.100
It's not a part of an ecosystem,
00:54:28.700 --> 00:54:30.560
so it works really well for Python.
00:54:30.680 --> 00:54:33.840
because we have so many Python packages out there
00:54:33.980 --> 00:54:34.660
are not just Python.
00:54:34.940 --> 00:54:37.600
It's like C, Fortran, Rust, JavaScript,
00:54:37.980 --> 00:54:39.640
all of these different ecosystems, right?
00:54:40.000 --> 00:54:40.700
GPU shaders.
00:54:41.120 --> 00:54:42.200
Yeah, GPU shaders.
00:54:42.320 --> 00:54:42.820
Throw them in there.
00:54:42.880 --> 00:54:43.160
Why not?
00:54:43.320 --> 00:54:45.280
I mean, Mike knows this even more than I do.
00:54:45.460 --> 00:54:46.140
Like there's video.
00:54:47.220 --> 00:54:50.420
It's just all sorts of great, great content on PyPI.
00:54:51.640 --> 00:54:53.400
Yeah, not that we encourage that use case.
00:54:53.720 --> 00:54:56.620
But there's a lot of stuff in Python packages
00:54:57.020 --> 00:54:59.380
and SBOMs are a great way to represent
00:54:59.800 --> 00:55:04.120
like the provenance of all that software without it being Python specific.
00:55:04.280 --> 00:55:07.000
For sure. All right. Picking up speed because we got a couple more to go through.
00:55:07.560 --> 00:55:14.620
We've got maybe the follow on or the after case here is post incident runtime S-bomb generation
00:55:15.180 --> 00:55:20.760
from Python memory by Hala, Ali and Andrew Case. And the general idea is there's what you've
00:55:20.820 --> 00:55:27.360
declared to be your supply chain inputs and then there's what's actually there. So maybe look at
00:55:27.300 --> 00:55:28.320
what is loaded into memory?
00:55:28.420 --> 00:55:31.220
And you're like, oh, why is this library also loaded?
00:55:31.880 --> 00:55:35.260
Or some other hacker type of thing got put on the machine
00:55:35.480 --> 00:55:36.180
and then loaded in.
00:55:36.180 --> 00:55:38.860
And now we can detect that through this generation
00:55:39.400 --> 00:55:42.040
of looking at loaded modules and so on, right?
00:55:42.240 --> 00:55:44.460
Yeah, this one, I was really intrigued about this
00:55:44.720 --> 00:55:48.020
because it went so deep into Python memory management
00:55:48.240 --> 00:55:51.020
and how modules are loaded and how functions are called
00:55:51.080 --> 00:55:54.320
like extremely deep dive into this topic.
00:55:54.720 --> 00:55:58.000
And so I was like super I was like in awe watching this talk.
00:55:58.150 --> 00:56:00.740
I was like they just kept on being more cool stuff happening.
00:56:01.120 --> 00:56:03.480
And so I was like looking at like runtime analysis.
00:56:03.630 --> 00:56:05.500
You can see what functions are being called.
00:56:05.810 --> 00:56:09.900
You can like to see whether or not like a CD is affecting your program.
00:56:10.140 --> 00:56:14.020
So you can like introspect your program live while it's running and see whether
00:56:14.950 --> 00:56:16.860
interesting like something is even being used.
00:56:16.860 --> 00:56:20.520
You don't even have to like look at the source code to check or whatever.
00:56:20.650 --> 00:56:23.440
You just look at your program and see if it's using that code.
00:56:23.520 --> 00:56:35.740
Yeah, yeah, because if you bother, and I don't, maybe you all know better than I do, but if I were to speculate, I'd say less than 1% of people actually run pip audit or uv pip audit sort of thing, uv audit, whatever it is, on their code.
00:56:35.900 --> 00:56:43.280
But even if you do, or you look at the CVE and you see one, or maybe get the PendaBot tells you, oh, there's a CVE in one of your dependencies, you better go fix it.
00:56:43.550 --> 00:56:45.980
And then you got to go look and say, does it really matter?
00:56:46.180 --> 00:56:57.320
I remember one of the packages I was using, it said, oh, on Windows, there's this issue that if you take untrusted input and it's a PDF and it's this way, it's going to do this terrible thing.
00:56:57.420 --> 00:57:02.920
I'm like, yeah, but my deployment target is Linux on Docker and my dev machine is Mac.
00:57:03.050 --> 00:57:05.820
And I don't think I've taken untrusted input whatsoever for this.
00:57:05.870 --> 00:57:07.360
And so do I care?
00:57:07.370 --> 00:57:07.940
I don't really care.
00:57:08.280 --> 00:57:08.640
You know what?
00:57:09.020 --> 00:57:10.040
I'm just going to not worry about it.
00:57:10.160 --> 00:57:15.560
But PitBot will fill my build and then we're back to the cooldowns and all that.
00:57:15.720 --> 00:57:18.040
But nonetheless, it's like, I think that's part of the problem.
00:57:18.060 --> 00:57:23.420
And the fact, if you could say somehow combine the CVE and the CVE, actually, I can verify
00:57:23.540 --> 00:57:24.960
it doesn't touch that bit of code.
00:57:25.120 --> 00:57:25.600
That's super cool.
00:57:25.800 --> 00:57:31.500
Yeah, on that front, I think there's an ongoing effort through the open source vulnerability
00:57:31.880 --> 00:57:38.240
database to surface more rich details as to like code paths that are affected.
00:57:38.760 --> 00:57:42.880
So that way you could automatically audit, do I use those code paths?
00:57:43.080 --> 00:57:46.100
and then thus either fail or not fail your build.
00:57:46.820 --> 00:57:48.900
But again, in languages like Python,
00:57:49.200 --> 00:57:51.800
where dynamicism is used,
00:57:52.680 --> 00:57:55.100
getting that an accurate representation
00:57:55.440 --> 00:57:57.440
of am I using that code path
00:57:57.660 --> 00:58:00.120
is often a harder question to answer
00:58:00.620 --> 00:58:03.240
because you don't necessarily even have to import the library
00:58:03.470 --> 00:58:04.580
via an import statement.
00:58:04.750 --> 00:58:05.840
You can use import lib.
00:58:05.950 --> 00:58:08.000
You can do all sorts of other different things.
00:58:08.560 --> 00:58:12.980
So the challenge is how do we surface enough information
00:58:13.000 --> 00:58:17.800
make a confident decision without misleading you down the wrong path.
00:58:18.580 --> 00:58:18.700
Indeed.
00:58:19.420 --> 00:58:22.360
Let's keep moving on because time is a ticking.
00:58:23.040 --> 00:58:28.040
The next one is GitHub Action Security and Python Packages by Andrew Nesbitt.
00:58:28.620 --> 00:58:29.280
So, yeah.
00:58:29.400 --> 00:58:29.780
Terrifying.
00:58:29.980 --> 00:58:31.140
There's some really weird stuff.
00:58:31.140 --> 00:58:32.320
That was very eye-ocaching.
00:58:32.320 --> 00:58:32.460
Weird caching.
00:58:33.280 --> 00:58:34.480
So Andrew's a nerd, right?
00:58:34.700 --> 00:58:36.080
He's the best kind of nerd, right?
00:58:36.180 --> 00:58:38.520
He loves researching things.
00:58:38.560 --> 00:58:39.940
He loves accumulating data.
00:58:40.280 --> 00:58:43.380
He's the author behind Ecosystems.
00:58:43.580 --> 00:58:46.440
That's ecosystem.sys.ms.
00:58:47.040 --> 00:58:51.180
And he analyzes lots of projects
00:58:51.570 --> 00:58:54.140
and was able to analyze a lot of GitHub project
00:58:54.360 --> 00:58:56.740
IPI-linked repositories with Zismore,
00:58:56.990 --> 00:58:58.080
which he did not write.
00:58:58.940 --> 00:59:00.420
But it is a very cool tool
00:59:00.620 --> 00:59:03.160
and great to audit your GitHub actions
00:59:03.740 --> 00:59:04.640
for security vulnerability.
00:59:05.180 --> 00:59:07.720
It's scary what its surface is.
00:59:07.920 --> 00:59:10.240
And when we're talking about
00:59:10.260 --> 00:59:15.300
folks getting started, this should be on that checklist of did you run Zizmor on your repository?
00:59:16.160 --> 00:59:21.220
Better yet, did you add it as a GitHub action to run always on your repository? But, you know,
00:59:21.320 --> 00:59:27.400
it surfaces a lot of easy to fix findings, and then sometimes surfaces the scarier ones of you've
00:59:27.540 --> 00:59:33.660
left yourself open to an injection that leads to a exploit. And he talked about a couple of those.
00:59:33.840 --> 00:59:38.560
Very interesting. Yeah, the GitHub actions have a lot of nuance and weird, there was some weird
00:59:38.700 --> 00:59:45.020
cache poisoning that people could submit PRs that would trigger a GitHub Action build.
00:59:45.720 --> 00:59:53.920
And even if they had no rights to the target system, their PR could point at a malicious
00:59:54.130 --> 00:59:55.360
package somehow.
00:59:55.510 --> 01:00:01.700
And then that would get cached into the actual build because the build ran in the context
01:00:01.900 --> 01:00:03.620
of the target repo.
01:00:04.030 --> 01:00:07.200
And hey, wouldn't it be nice if we could just cache this so we don't save it?
01:00:07.260 --> 01:00:09.440
Maybe we should cache other people's inputs.
01:00:09.800 --> 01:00:11.240
You said all the keywords there, Michael.
01:00:11.310 --> 01:00:12.860
You said pull request and target.
01:00:13.180 --> 01:00:14.760
That is the trigger for a lot of these.
01:00:15.100 --> 01:00:17.180
GitHub Actions has a lot of different trigger keywords.
01:00:17.700 --> 01:00:18.700
Push, pull request.
01:00:19.260 --> 01:00:21.400
There is one called pull request target.
01:00:22.040 --> 01:00:23.920
That one runs on forks.
01:00:24.260 --> 01:00:25.960
It runs with elevated privileges.
01:00:26.700 --> 01:00:28.060
It is dangerous.
01:00:28.400 --> 01:00:30.200
Zismore calls that out as like,
01:00:30.440 --> 01:00:32.300
you are probably using this wrong
01:00:33.010 --> 01:00:34.940
because it is a very sharp, sharp knife.
01:00:35.500 --> 01:00:37.020
If you pick it up the wrong way,
01:00:37.140 --> 01:00:41.320
You have now cut your hand and it's easy to pick up the wrong one.
01:00:41.500 --> 01:00:42.320
So Runs is more.
01:00:42.320 --> 01:00:43.700
Please start trying to juggle three of those.
01:00:44.120 --> 01:00:44.240
Yeah.
01:00:44.660 --> 01:00:45.240
Don't juggle three.
01:00:45.540 --> 01:00:46.140
Runs is more.
01:00:46.440 --> 01:00:47.360
Follow its recommendations.
01:00:47.980 --> 01:00:48.900
Move on with your life.
01:00:49.020 --> 01:00:49.400
All right.
01:00:49.580 --> 01:00:50.900
One more here.
01:00:51.300 --> 01:00:52.700
Breaking Bad packages.
01:00:53.260 --> 01:00:56.260
Why traditional vulnerability tracking fails supply chain attacks.
01:00:56.920 --> 01:00:59.100
Shelby Cunningham and Madison Figuerely.
01:00:59.420 --> 01:01:02.880
So I really like this one because it talks about the CVE system,
01:01:03.380 --> 01:01:06.720
which is something that I've spent way too much time kind of digging around in.
01:01:06.960 --> 01:01:16.580
And it's this challenge between intentional malicious software, like malware that we see on PyPI, and vulnerabilities.
01:01:17.220 --> 01:01:23.400
And I think that there's this, sometimes we use CVEs for malware and sometimes we don't.
01:01:23.760 --> 01:01:26.580
And because if we did, there'd be, you know, millions.
01:01:27.300 --> 01:01:29.200
And it's like, do we, do we not?
01:01:29.340 --> 01:01:30.340
Like, what are the trade-offs?
01:01:30.520 --> 01:01:31.480
Does it overwhelm the system?
01:01:31.700 --> 01:01:32.980
Is it even useful?
01:01:33.480 --> 01:01:50.680
And it talked about all of these different watering hole attacks that ended up publishing malware to different open source ecosystems, including PIPI and how the this vulnerability record like CD or OSV responded in turn and like how people got the word out.
01:01:50.790 --> 01:01:52.240
How did people respond to it?
01:01:53.240 --> 01:01:59.560
And yeah, it's it's really challenging because it feels it feels so close to being the right system to use, but not quite.
01:01:59.920 --> 01:02:02.120
And maybe that means that we need to build a new system.
01:02:02.480 --> 01:02:04.240
Maybe that means that who knows what it means.
01:02:04.680 --> 01:02:06.640
We need to do some more thinking in this area.
01:02:06.920 --> 01:02:12.720
Yeah, I totally see it because malware is not a problem in valid software, right?
01:02:13.460 --> 01:02:15.700
It's just a bad piece of software.
01:02:16.200 --> 01:02:21.620
Whereas if I open up this PDF in Microsoft Word and it turns me into a botnet, that's a CVE.
01:02:21.920 --> 01:02:23.880
Because Microsoft Word isn't intended to be malware.
01:02:24.580 --> 01:02:25.120
All right, folks.
01:02:25.660 --> 01:02:29.880
I think that might be it for the time that we've got.
01:02:30.360 --> 01:02:31.960
So I guess final call to action here.
01:02:32.100 --> 01:02:38.780
We have all these talks on PyCon US, and everyone links to them.
01:02:39.070 --> 01:02:41.940
So every part of the show notes links up to them.
01:02:41.990 --> 01:02:46.720
So I'll put the links in the show page for people listening and their podcast player and so on.
01:02:46.820 --> 01:02:49.360
So go out and check out the interesting talks on YouTube.
01:02:49.820 --> 01:02:50.980
I can put that out there.
01:02:51.300 --> 01:02:53.420
But let's leave it with us.
01:02:53.980 --> 01:02:56.580
Juanita, I'll give you the first word, and you can each answer this one.
01:02:56.920 --> 01:03:01.920
So if everyone out there listening did one thing this week because of this episode,
01:03:02.000 --> 01:03:03.360
because of what they heard us talking about.
01:03:03.450 --> 01:03:04.080
What should they do?
01:03:04.270 --> 01:03:04.920
What would you tell them?
01:03:04.920 --> 01:03:07.140
Like, here's the one thing really I recommend most.
01:03:08.000 --> 01:03:10.420
If it's only one, I'll just pick you, Sizmore.
01:03:11.360 --> 01:03:11.520
Okay.
01:03:12.300 --> 01:03:12.520
Mike?
01:03:13.540 --> 01:03:14.680
Look at trusted publishing.
01:03:15.140 --> 01:03:17.900
Convert at least one of your projects to use it.
01:03:18.140 --> 01:03:20.760
And don't forget to delete the old token.
01:03:21.200 --> 01:03:21.500
Got it.
01:03:21.630 --> 01:03:21.740
Okay.
01:03:22.180 --> 01:03:24.620
Spoken like a person who works on PyPI security.
01:03:25.240 --> 01:03:25.460
Seth?
01:03:25.860 --> 01:03:25.960
Yeah.
01:03:26.010 --> 01:03:31.220
So my recommendation is if after hearing all of these security problems,
01:03:31.580 --> 01:03:37.980
solutions like what's happening in security and how it's not this like solve thing to I'm assuming
01:03:38.140 --> 01:03:42.540
that because you're watching this show that you have an interest in Python and you maybe you even
01:03:42.700 --> 01:03:50.880
work with Python. I would recommend if you depend on Python or third party packages to look upstream
01:03:51.400 --> 01:03:58.000
and to see that all of this work is being done and that there is so much more to do and support
01:03:58.020 --> 01:04:04.160
those open source ecosystems that you depend on to enable them to do security. So whether that's
01:04:04.340 --> 01:04:09.120
donating engineering time, so like working on a security team, making some of these security
01:04:09.500 --> 01:04:13.760
focused contributions to open source projects that you care about, or whether that comes as
01:04:13.880 --> 01:04:17.580
like funding, right? So like donating to the Python Software Foundation, for example,
01:04:18.060 --> 01:04:25.700
nonprofit that is the home for Mike and I's job. Security is not free. It costs a lot of time to
01:04:25.720 --> 01:04:30.180
implement all of these changes that everyone ends up benefiting from anyways. And it really would
01:04:30.280 --> 01:04:36.280
not happen without internal advocates at companies and organizations working with their management and
01:04:36.320 --> 01:04:41.500
all of that to convince them to support open source that they depend on. So that's my recommendation.
01:04:41.820 --> 01:04:46.640
Perfect. And one final thing, maybe Juanita, people want to keep in touch with you.
01:04:46.960 --> 01:04:50.280
Where's, you know, can they follow you on social? Do you got a blog?
01:04:50.780 --> 01:04:56.120
I have a website where I guess I sometimes put things that I have done or I'm doing currently.
01:04:56.660 --> 01:04:58.960
But honestly, the best way to reach me out is probably LinkedIn.
01:04:59.720 --> 01:05:04.340
I try to post where I'm going to be if I'm giving talks, where to find me.
01:05:04.950 --> 01:05:07.100
But if you just want to chat, just message me on LinkedIn.
01:05:07.619 --> 01:05:11.240
I'm very happy to connect with people that are interested in any of the things that I'm working on.
01:05:11.440 --> 01:05:12.200
Right on. Mike?
01:05:12.460 --> 01:05:21.100
Yeah, I have a landing page at MikeTheMan.dev, and that will link you out to all of my other different locations, socials, blogs, etc.
01:05:22.160 --> 01:05:29.400
And that is, yeah, I'm also on LinkedIn, but I also try to post on all the different socials of like, yep, I'm going to be at EuroPython.
01:05:29.600 --> 01:05:30.380
Here's where I'm going to be.
01:05:30.980 --> 01:05:37.000
So that way people can accost me on the hallway track and demand some new security feature, which is wonderful.
01:05:37.310 --> 01:05:38.240
Love talking about it.
01:05:38.240 --> 01:05:40.080
The most well-attended track of the conference indeed.
01:05:40.600 --> 01:05:41.040
Seth.
01:05:41.200 --> 01:05:43.960
Yeah, so you can find me online, sethamlarson.dev.
01:05:44.280 --> 01:05:45.120
Links out to everywhere.
01:05:45.400 --> 01:05:48.140
I prefer Mastodon, but I also respond to LinkedIn.
01:05:49.380 --> 01:05:50.340
And there's even Signal there.
01:05:50.420 --> 01:05:53.860
So if you want to just like privately ask me a security question or something like that,
01:05:53.920 --> 01:05:56.700
or you just want to chat for a second, I respond to Signal.
01:05:57.060 --> 01:05:59.280
So any of those locations work for me.
01:05:59.440 --> 01:06:00.780
I publish a blog there as well.
01:06:00.860 --> 01:06:05.500
So if you want to read anything about security or retro video games, those are your options.
01:06:05.520 --> 01:06:05.700
Solid.
01:06:06.980 --> 01:06:07.100
Great.
01:06:07.220 --> 01:06:08.100
Thank you all for being here.
01:06:08.460 --> 01:06:08.960
See you later.
01:06:09.260 --> 01:06:09.540
Thank you.
01:06:10.560 --> 01:06:12.980
This has been another episode of Talk Python To Me.
01:06:13.360 --> 01:06:14.080
Thank you to our sponsors.
01:06:14.300 --> 01:06:15.620
Be sure to check out what they're offering.
01:06:15.760 --> 01:06:17.140
It really helps support the show.
01:06:17.940 --> 01:06:19.320
Take some stress out of your life.
01:06:19.700 --> 01:06:22.880
Get notified immediately about errors and performance issues
01:06:23.040 --> 01:06:25.140
in your web or mobile applications with Sentry.
01:06:25.660 --> 01:06:28.520
Just visit talkpython.fm/sentry
01:06:28.960 --> 01:06:30.020
and get started for free.
01:06:30.560 --> 01:06:33.020
Be sure to use our code talkpython26.
01:06:33.980 --> 01:06:37.360
That's Talk Python, the numbers two, six, all one word.
01:06:38.740 --> 01:06:42.060
Talk Python and Python Bytes both now have MCP servers.
01:06:42.600 --> 01:06:46.980
Point your AI at 10 plus years of Python episodes, transcripts, and show notes.
01:06:47.390 --> 01:06:47.540
Free.
01:06:48.070 --> 01:06:52.160
Click MCP in the nav at talkpython.fm and at pythonbytes.fm.
01:06:52.940 --> 01:06:54.820
If you or your team needs to learn Python,
01:06:55.010 --> 01:06:59.040
we have over 270 hours of beginner and advanced courses on topics
01:06:59.320 --> 01:07:05.100
ranging from complete beginners to async code, Flask, Django, HTML, and even LLMs.
01:07:05.320 --> 01:07:07.700
Best of all, there's no subscription in sight.
01:07:08.240 --> 01:07:09.920
browse the catalog at talkpython.fm.
01:07:10.660 --> 01:07:12.560
And if you're not already subscribed to the show
01:07:12.800 --> 01:07:13.980
on your favorite podcast player,
01:07:14.640 --> 01:07:15.280
what are you waiting for?
01:07:15.960 --> 01:07:17.720
Just search for Python in your podcast player.
01:07:17.880 --> 01:07:18.700
We should be right at the top.
01:07:19.120 --> 01:07:20.660
If you enjoy that geeky rap song,
01:07:20.770 --> 01:07:21.880
you can download the full track.
01:07:22.090 --> 01:07:24.000
The link is actually in your podcast blur share notes.
01:07:24.840 --> 01:07:26.160
This is your host, Michael Kennedy.
01:07:26.560 --> 01:07:27.620
Thank you so much for listening.
01:07:27.810 --> 01:07:28.620
I really appreciate it.
01:07:29.060 --> 01:07:29.760
I'll see you next time.
01:07:41.640 --> 01:07:44.440
I'm out.