Right,
[Music]
welcome back everyone. It is my great
pleasure to introduce Tim and Nikki who
will be talking to us about myths about
open source security that developers
believe.
For now, a warm welcome.
Good day everyone. Welcome to our talk
about a few myths, just a few that open
source developers believe brackets for
now. I'm Nikki. I'm a product manager at
Google.
I'm Tim. I'm a software engineer at
Google.
And we work on open source dependency
analysis in the coolest team, uh, Ghost,
the Google open source security team.
And yes, we have stickers. Come get us
later. Um, so we're going to run through
a bunch of myths. uh that we have
ourselves previously held uh and that
when we're chatting to folks about uh
about open source um that they might
think that's right where the
ghostbusters ghost myth bust. Yeah, I'm
sorry. Okay. Um so myth number one,
installing Python packages is easy and
safe. All right, let's start with the
easy X I You're in the right room. Uh
the easy part. Okay, look. Yeah, that
Okay, that I think easy is correct. Nice
work, US. We're halfway there, at least
in Python. Um, but actually, it's pretty
true of most ecosystems. We're good
here. All right. How about the safe part
of our hypothesis? Like so many things
uh with dependencies, the answer is, of
course, it depends. Um, it depends on
what that thing that we just installed
was and what it contained. uh what you
ended up installing as a free fun bonus
thrown in those transitive dependency
steak knives.
We interrupt this talk for a brief
public safety reminder. It's a beautiful
autumn day. You're in the office. You've
just returned from a meeting when you
notice a USB stick abandoned on the
floor. You look at it. You look at your
laptop.
You leave it untouched. some mysteries
you think weren't meant to be answered.
Okay, pop quiz. Um, what's the
difference between these two things? One
is plugging in a mystery USB stick and
the other is running npm install on a
package. Well, they do have a few
similarities, but actually npm install
gets run potentially as root in your
data center whereas a thumb drive is
just on one developer machine.
Okay, so there have been a few bigname
supply chain attacks over the last few
years uh and lots more that you might
not have heard about. Um in fact just so
so in a few days ago I felt compelled to
update these slides uh with another
headline and another clarification.
Um so
so how risky is it? Um, you can think of
risk in two different dimensions. There
there's the risk of the package itself,
but also how many packages there are.
So, first off, how many? Well, there's
somewhere between zero and a lot. Uh,
how many free as in puppies, transitive
dependencies are we getting? Well, I
don't know. It's hard to say, but on
average, well, there are lots of
different ways to measure average. And
honestly, all of the ways that we tried
for average ended up with the answer, it
depends, but kind of a lot in some
ecosystems more than others. Um, okay.
So, how risky is that dependency? And
again, it depends. One aspect of risk, I
should take this moment to say most of
these images are from emoji kitchen. I I
I was going to mention that at the end
of the talk because now we just lost our
audience. That's fine. But um how how
risky is this package? What is the
impact? If the risk occurred, what's the
probability of it happening? And what's
the impact of it happening? And there
are lots of dimensions to this risk. Is
it malware? Sure. But also, do the
maintainers follow best security
practice or are they burnt out and
susceptible to sock puppet social
engineering attacks? If there are bugs,
are they or security concerns, are they
apt and ideally remediated or is the
package abandoned? Is the package just
new? No one really knows. Maybe it's a
typo squatting attempt. Is it a package
with a solid history, but also with
leaked or fished credentials? The
package is available right now, but will
it be next week? And is there an
attestation available so you can be sure
it's the same package that you think
that it really should be. Some of these
risks change based on the ecosystem.
Packages. Package managers here uh can
be a great help. Shout out to Pippi for
being absolutely on the ball with some
great security features and some others
you can protect against yourself when
those risks matter to you somewhat.
Okay, myth number two. There's only one
dependency graph. You may remember me
from such pyons as 2024. uh we
calculated approximately
this number on the order of 10 to the 81
valid dependency graphs for a single
dependency for D3. Um okay so that's
almost the number of atoms in the
universe. Uh but good news that number's
gone up since then. That was a whole
year ago.
But why? Well there are just more
packages available now which generally
means a lot more options when satisfying
requirements. And what do I mean by
satisfying requirements? Well, you have
a project. Say you want to use Express.
It's a minimalist web framework. It's a
node. But actually, so we've got these
requirements on that package. Maybe you
need it to be version five or above for
those shiny new features. So it turns
out there are three versions that could
satisfy that constraint. Here's our
situation. Your package depends on
Express. It has three valid versions to
pick from. That's not so bad. Three.
Great. I can count that high. But
Express has its own dependencies. For
example, it depends on body paser. And
there are currently around five versions
that would satisfy that constraint. And
that's a very small part of the
dependency tree. So, so there are more
layers and each dependency on each of
those layers on each of those versions
of each of those layers and it stops
becoming a tree. And very quickly, yeah,
it's a mess. And if you were going to
run npm install say a month later, it's
entirely reasonable and expected that a
huge part of this graph is thrown into
chaos and a wildly different one emerges
because which version actually ends up
in your dependency graph depends on a
lot of different things. The build tools
compute the dependency graphs by
evaluating constraints created by
dependency requirements. I prefer
version three or greater. Environmental
constraints. This is a build for
Windows. what kind of build it is. Build
the tests as well as the software and
perhaps build specific considerations.
The binary must be minified. So a new
version showing up can change the graph.
A version being deleted that changes the
graph. Different tooling using UV
instead of pip or yarn instead of npm or
even just a different version of npm.
One quirk I quite like at least with npm
if you rename a package you're
installing think import fu as blah or
arvark that can change your dependency
graph because some implementations of
npm resolve the dependencies in lexical
graphical order which can cause
requirement yeah
requirement conflicts to resolve
differently depending on which one gets
evaluated first.
So
where does that leave us? There is never
the dependency graph. There is only ever
a dependency graph on your particular
machine and at your specific point in
time using this specific package manager
and so on. Okay. Myth number three,
names are unique. Okay. So you've
decided on a dependency, you know you
want to use it. Great. And and you know
its name and what the version that you
want to use is. Go for it. Except what
was it called again? Packages by any
other name might smell as sweet, but
name confusion can certainly be a
thorny. I'm so sorry. Okay. So, um,
names are not unique. Not across
ecosystems. Fair enough. Maybe each
ecosystem really does need a Babel
package, but also names might not be
unique across registries and namespaces.
There could be quite a few reasons for
this, and some of those reasons are more
problematic than others. Name squatting
is essentially when someone comes along
and registers a bunch of common names to
sell later. It's really common with
domains, uh, social media and also
happens with package registries. Uh, I'm
not sure how lucrative it is in case
you're looking for a career change, but
um, you can think of name squatting as a
specific type of typo squatting. The
broader concept here is that some minor
mistake when you're typing the package
means that the user doesn't end up with
a package that they expect. they end up
with your package instead. That mistake
might be a genuine typo, typos targeting
a specific package, or it might be
reusing the names of packages that are
popular in other ecosystems, or it might
just sound right, like these VS Code
extensions that were all uploaded by the
same malicious account and found in
April this year. And of course, that's
the challenge. What is legit? What seems
legit? And what's safe? Two of these are
legitimate offiscation tools that
developers could use. But which two?
It's these ones. But you have no way of
knowing unless you actually know. Um, so
what's a dev to do? Well, uh, maybe Tim
can find some answers.
Maybe.
Be prepared for speaking rate to tone
down to like five.
Yeah. Just just Yeah. If you were
listening to this at 2x uh Well, at
four. Yeah. No. Yeah.
So myth number four, popular things are
more secure.
So you probably know a core tenant of
open source is Linus' law where given
enough eyeballs or bugs are shallow,
which is to roughly say that popular
open source things are safer, right?
Unexpected uh expectedly it's more
complicated than that. Firstly, popular
things tend to be more complex.
Most often, if you're writing Python
packages that are popular, you're likely
to be writing solutions that cater to
thousands or if not millions of distinct
users and use cases.
And it happens that popular things tend
to have more features, more nuanced
optimizations, etc.
Of course, complexity tends to mean
greater attack surface. And this is sort
of the inherent trade-off of using
popular open source software. you get
comprehensive battle tested solutions,
but they're often much more complex and
therefore greater tendency for potential
vulnerabilities.
Secondly,
popular things are often the only thing
that people even care to attack.
So, a tangent.
When I was growing up, I thought there
were only ever two operating systems in
this world, Windows, Mac OS. And then
some day in high school a tragedy
occurred and I heard about Linux for the
first time.
Uh and I genuinely heard this being
lorded as like one of the reasons why a
person ought to consider using Linux
because supposedly it's virus free. And
I recall this was genuinely like a
frequently quoted benefit of using Linux
for personal computing.
As we all know, the statement is
obviously false, but there is some truth
around this idea because Linux
unfortunately never really took off as a
popular operating system for desktop
computing. Uh, in terms of market share,
we're currently sitting at around 2%
roughly. This is 2024 data.
So, if you were an attacker and you
wanted to distribute malicious
executables,
you would probably not be targeting
Linux. And that that happens to be a
huge reason why Linux was just the more
secure choice.
Likewise here, I would not need to tell
you which package would be more likely
uh to be valuable to attack.
Pyramid here, by the way, is another web
server framework that you probably
haven't heard about. It does fewer
things and is expectedly less popular
than Django. And so it just happens
fewer people are going to care to
compromise pyramids.
Okay, here's some really recent news.
This landed like earlier, literally just
this week. Uh, what you're looking at
here is a sample of a few JavaScript
packages that have been released
recently with a malicious change.
That change, by the way, is going to
drain your crypto wallet.
Uh, and here are the weekly downloads
for some of those packages. We're
talking in the ballpark of uh billions
of downloads. And this is in just a
single oneweek period.
So in addition to you as a developer
needing to be security aware, the
ecosystem as a whole has a
responsibility to adopt strong security
practices.
Uh at at a minimum think things like
multiffactor authentication,
package signing, etc.
uh sort of amusingly between ecosystems
there's actually a surprising spectrum
as to how strong their security
practices are. For instance, consider
this. How long is it going to take for
90% of reported malicious packages to be
taken down? In other words, like you
report 100 packages as being malicious.
How long does it take for 90 of them
roughly to be taken down?
For Pippi, the answer is roughly 24 to
36 hours.
And for npm, that figure is like an
order of magnitude higher.
Yeah. And so this is where we give a
special shout out to Pipi for actually
being an outlier with how responsive
they are.
Uh but even though like Pippi tends to
act particularly fast here, things get
downloaded at such a huge scale that we
are still talking about like hundreds of
thousands of downloads for one package
in a single 24-hour period. And that's
still enough to potentially produce huge
impact.
So the lesson here is
the takeaway here is not to stay away
from popular things. Often you don't
have a choice. Um for instance, you
should not be swearing off Python today
and rewriting all your things in Cobalt.
The lesson is just to not blindly use
popular technology expecting that it'll
be more secure.
There are many good good angles to this.
However, like the good thing is if you
do opt to use something secure uh
popular, like generally speaking, if
something bad were to happen, uh you
know, many people care and they're going
to act quickly and remediations tend to
come about quicker.
And as you saw just then with these
malicious JavaScript packages, uh people
noticed it really quickly, they reported
it quickly, and now it's being
remediated quickly.
If you're curious, uh, for actual stats,
it could have been much worse, but, uh,
it turns out those malicious packages
were downloaded roughly on the order of
hundreds of thousands of times before
takedown.
Uh, how disastrous did this end up
being?
Remember, these malicious packages would
drain your crypto wallet. So, how much
did they actually managed to steal?
Uh, current analysis shows that the
attacker actually made off with a
jaw-dropping
$5 US.
Uh, plus plus a bit more in um various
NFTts and meme coins and whatnot.
Anyway, like we were very lucky here,
but this is just another reason why
popular packages get targeted. Like you
need huge volume for huge impact.
onto a different myth. Open source is
immutable.
The packages you install today are going
to be the same as the packages you
install tomorrow, right?
Not necessarily, because unlike other
package managers in other ecosystems,
pip doesn't actually make integrity
checks by default. And by integrity
checks, we just mean pip does not take
the hash of the packages you download
and uh check that in future times you
run pip install it remains the same.
If you want that sort of thing, you
should be running this command instead
with the uh require hashes flag.
And so unless you specifically opt into
doing something like this, you actually
just don't have a real practical
guarantee you're getting the same
contents as the last time you ran pip
install.
And here's another myth. Git tags are
immutable.
To remind you, git tags are very simple.
They're just like aliases for a commit.
That's pretty much it. We use them as a
sort of human readable bookmark for a
specific commit.
The convention
for Python packages as well as packages
in other ecosystems is we tend to use
git tags to point to the specific commit
that a version was built at. Something
that looks like what you're seeing on
the slides here.
Anyway, a big distinction between git
branches and git tags is that tags are
not meant to be reassigned after you
created them.
In other words, by design, or at least
by intention, they're meant to be
immutable.
Except no, you can just do this. Uh
there's no magic here. You really can
just drop and recreate a tag on a
different commit and then push it
upstream. And it feels really trivial to
stand here and point out that you can do
this, but the fact that you can actually
has some very interesting slash dire
consequences to open source security.
Let's put our black hats on. You have a
malicious package fu version 1.0.0 that
you want to publish to users on Pippi.
You can upload this to Pippi with no
issues. Uh but we have an obvious
problem. Anyone who is suspicious of our
malicious uh package can inspect our
source code and they can see our
wrongdoing because it's all in plain
sight. So here's a trick to actually
conceal our malicious code. Suppose we
built and published FU version 1.0.0
zero at the bad commit DF456
and suppose we have a good commit right
after this one's completely innocent the
trick is we can move the version tag
v1.0.0 from bad to good
and the clever thing here is we've moved
the tag from bad to good but Pipi is
actually still publishing the bad one
and this is great because now you can
shake off suspicion very easily like
anyone who suspects foul play they can
just audit your project at version 1.0.0
Z and they'll find nothing wrong.
And it's it really is that easy. And
people really do pull off this kind of
exploit. If you're curious, search up
the Bolt DB incident. People did this
for a package and they actually had
potential remote code execution over
three years before people found out.
Yep. Myth six, Python is dead. Python 2
is dead.
Yeah. Like so far in this conference,
it's been AI this, AI that. I don't
think I've heard a single mention of
Python 2, so probably safe to say it's
dead.
Some background first. Python 2 was
first released in October 2000.
After 20 long years, we finally mark the
end of life of Python 2 in April 2020.
So, it's been a good 5 years since 2020.
Is it dead?
Nah, Python 2 is not dead yet. It has
been 5 years, but people are definitely
still using it. Much less actively for
sure, but definitely still in use. In
fact, the percentage of people
reportedly using Python 2 actually
hasn't changed that much since 2020. It
was sitting at around 6% then and a year
ago was sitting at around 4%.
Anyway, let's look at something more
concrete maybe. Let's look at the actual
download stats from Pippi. This is a
rough count of the number of packages
downloaded in the last 12 months. And
good news, looks like Python 2 is dead.
But uh stretching out the y-axis a bit
more, you can see there is a small but
still persistent sliver remaining for
Python 2. But like in relative terms,
this looks okay, right? Uh the problem
is Python is the world's most popular
programming language at the moment. And
that tiny sliver is actually three
billion package downloads in the past 12
months,
which is to say that nearly 20 million
packages have been downloaded since PyCon
started this Friday at 9:00 a.m.
And in the time it took to deliver that
sentence, another 800 or so were
downloaded.
Yeah. So, Python 2 is not quite dead,
but who cares? in general like why does
it matter that people are using end of
life things?
It matters because when something
becomes end of life it means you no
longer get security patches on that
thing or at least you don't reliably get
them.
In this case it's been like 5 years.
Python 2 and its main libraries have had
ample time for many vulnerabilities to
be discovered and there's only ever
going to be more over time.
So what you're looking at here is just a
very small sample of a few
vulnerabilities affecting the Python 2
standard library and also some
cornerstone libraries like NumPy,
Pillow, Django, etc.
So if something gets marked end of life
and that something actually matters to
you and your organization,
it really is best that you do something
about it.
And gosh, like if only there was some
kind of new industry changing, emerging
technology that could solve all this
without human intervention. Nikki,
surely something along those lines would
come and save us.
Interesting theory. If only we had Oh,
we have a myth for that. Okay, our last
myth. AI will save us. Yay. Um, but
first, nostalgia story time with Nikki.
And so at university I learned that
computers are very very fast. Very dumb
but very very very very fast. So that
means they will do exactly what you tell
them to and not necessarily what you
want them to and they'll do it very
quickly. So now one of those things is
no longer a limiting factor. They no
longer do exactly what you tell them to
but rather they just kind of follow the
vibe of it. LLMs can accelerate the
generation of code. They can automate
the creation of boilerplate. That's a
great thing that they can do. LLMs can
significantly lower the barrier to
entry, maybe help onboard junior
developers or even complete noviceses
much, much faster. And that means that a
lot of the tasks that traditionally
might have required some
critical thought no longer do. That's
great. Like installing dependencies. Oh.
Um, well, okay. So if we're moving from
author to auditor, how closely are folks
actually validating things and do they
understand it? If you are looking, if
they are looking, are they just checking
to see that the vibes seem right? Um
because AI does not solve our open
source problems. It automates and
accelerates human endeavors and human
mistakes at industrial scale. Uh, and
one of those mistakes that we've seen
with our eyes on your dependencies is
slop squatting. Think typos squatting,
but specifically targeting AI generated
code. So, specifically, an LLM model
tendencies to hallucinate a non-existing
package name because it turns out that
LLMs don't know what packages actually
exist. They just go by the vibes and
what seems right. So, LLM make stuff up.
That's what a generative model is. And
according to this linked study, roughly
20% of generated code samples had at
least one recommended package that
didn't exist. And crucially, more than
half of hallucinated packages reappeared
in multiple runs. So a malicious actor
could pretty easily just run an LLM,
find those packages that don't exist,
find register those package names, and
upload some malicious code. Ah, and if
the developers aren't paying a lot of
attention to what they're actually
importing, because remember that those
packages look totally plausible. Well,
that's a bit scary. And there are other
scary potential futures, too. Are LLM's
actually going to be great at finding
zero days in our source code? And how
might we, as a community meet that
challenge? Many maintainers are already
pretty burnt out. They're already
inundated with generated PRs and
security reports generated by
well-meaning people. Does the future
actually look like reducing our reliance
on open source? How long until some CEO
says just vibe that up the whole thing?
Then we won't be relying on that one dev
in Nebraska and our code won't be open
source. So we'll be protected, scare
quotes intended, from those LLMs who are
out there hunting for zero days trying
to hack us. But do we want that future?
Do we want Vibes source instead of open
source? Your being here in this room
demonstrates that you believe in the
value of open source. We know the value
of Eyes on the Code and the myriad other
benefits that come from being part of an
open source community.
Well, no matter which path we go down,
and I'd personally really like to avoid
Vibe Source as a default,
but hey, uh, no matter what future,
scary or not, we end up in, it looks
like there'll be jobs in security.
Uh, so I'm Nikki.
I'm Tim.
And those were some myths about open
source that we hope you no longer
believe.
[Applause]
Thank you uh Nikki and Tim for the very
riveting talk. I
Scary.
Scary. Very scary.
Um
but a little optimistic.
Just a tiny bit.
And you you can all go and check out um
Emoji Kitchen now.
Um please accept these uh speaker gifts
on behalf of the conference. Um,
do we have any questions? We have one
question over there.
Do you have any commentary on the case
of um releasing on Pippi with an SIS and
then at a later point in time adding a
malicious uh wheel to the release? So,
you know, you reinstall the same version
of the package, but now it contains a,
you know, a platform wheel that is
malicious.
Yeah, that seems bad. Um, uh, uh, I I'm
looking at Caleb in the front row
saying, "Yes, we have comments." Um, uh,
come grab us afterwards. Yeah.
Might have time for one short question.
Um, you said that PIP does not grab
hashes by default. Do you know off the
top of your head if UV does?
Yes, it does. Someone knows and they say
yes, it does.
Great.
Any of the ones that use a lock by
default.
Any of the ones that use a lock file by
default to do.
Uh please join me again in thanking
Nikki and Tim for the excellent talk.
[Applause]