How to help an Open Source project that your company depends on
I'm in touch with a company that is trying to figure out how to best help specific Open Source projects that they depend on (i.e. that are part of their SBOM). I'll do something unusual for me today, and do a public braindumb on the topic, and adjust these notes over time. Let's dive right in:
Why help Open Source in the first place?
Benefits of helping the Open Source projects that you depend on include that:
- your software dependency is more likely to stay in good enough shape to fix vulnerabilities and release security fixes with little delay, and that increases your own products security
- you avoid a "riding a dead horse" situation without knowing
- you get organic marketing (brand visibility, value signaling, attention from potential hires, ..)
- you get a feel of being part of the solution
- you build relationships for the future
What state does the project need to be in to be considered healthy?
Project health has many aspects, some less obvious, in particular to non-developers. All aspects of project help offer unique opportunities to be helpful.
To be a healthy dependency, you want the following future state for the project (in no particular order):
- maintainable and secure code,
- maintainable build system,
- tests and good test coverage (to avoid bugs and regressions),
- secure CI pipeline running the tests (to avoid regression),
- static analysis in CI (to reduce introduction of bugs),
- runtime analysis (to reduce introduction of bugs) e.g. use of AddressSanitizer and UndefinedBehaviorSanitizer with C/C++ projects,
- code auto-formatting and checks for formatting violations in CI (for readability, morale, efficiency of review),
- support for recent toolchains (e.g. recent compilers, for agility and morale),
- (no support for ancient toolchains (for agility and morale),)
- an all-warnings-addressed situation
(e.g. using
-Werror -Wno-error=...
in CI (but not in packaging) for C/C++ code) or actively working towards reducing the list of explicit exclusions for all static analysis tools in use, - collaborative attitude among project contributors,
- low number of stuck issues (for morale and efficiency),
- low number of stuck pull requests (for morale and efficiency),
- timely, thorough, co-operative code review for pull requests (for morale and progress),
- timely and co-operative responses, analysis, discussion in issues (for morale and progress),
- integrated use of fuzzing (to detect unknown vulnerabilities) with good fuzzing code coverage (upstream and/or in OSS-Fuzz).
How to fund help in general?
There are multiple options:
- a) pay existing hands upstream (through funding or employment) that are open to direct funding
- b) bring new hands that you already pay for (e.g. through ongoing employment)
- c) bring new hands that you will pay for
- d) combinations of (a), (b) and/or (c)
- e) pay a third party to organize (d) for you well
Every project is unique in the needs: some maintainers are happy to spend more of their own time for compensation, others are already at their limit of spending time, need self-organizing additional hands, have no use for payment at all, and so on. Finding the approach that works for a specific project through analysis and discussion is key.
What are the challenges in funding a project?
- Paying contributors can get them into situations of conflict of interests.
- Paying contributors can create an atmosphere of envy and injustice.
- Paying contributors can become tricky legally when they work on the project during both work hours and spare time, e.g. with regard to legal maximum de-facto work hours per day.
- Paying existing contributors can affect their motivation to work on the project for better or worse.
- Paying existing contributors on project A can make them neglect other important duties, e.g. work on project B.
- Producing more (or too many) non-trivial pull requests takes away time from existing contributors (and can hence hurt more than help).
- Some contributors like to avoid voice/video calls and some like to avoid text ping-pong, i.e. individual needs need individual approaches.
What can be done about these challenges?
Some ideas about how to tackle these challenges:
- For (1) communicate (and mean) that you understand and expect that their conscience, ethical behavior and the community interests of the project are at least as important as your business interest.
- For (2) consider approaching the whole project on the topic of funded contributions before starting to fund.
- For (3) discuss the issue with funded contributors upfront.
- For (4) discuss the topic with funded contributors upfront, to get a sense for the kind of affect you would have.
- For (5) discuss their situation in life and other duties with them before funding.
- For (6) discuss with existing contributors:
- how to maximize pull requests for reviewability to their eyes,
- how much volume or pace of contribution they can sustainably handle at the moment,
- whether voice/video calls or text ping-pong fits there individual needs better, and
- which issues (or types of issues) to start helping with and which issues to not touch at the moment.
- For (7) discuss with existing contributors.
Take home points
- It can be done.
- Every project has different needs.
- There are plenty of things that projects need help with.
- Doing it wrong can hurt a project and make matters worse.
- You have a unique profile what kind of help fits you best.
- Tip: You can bookmark this page to find your way back here easily later.
Did any of that hit a nerve with you or made no sense at all?
Let me know and have a nice day!
(German) Heiße Haferflocken mit Apfel und Zimt
Hintergrund
In meiner Kindheit hat meine Mam dieses Gericht oft vor der Schule für uns Kinder als Frühstück zubereitet. Eine tolle kleine Mahlzeit, die schnell und treffsicher gelingt.
Zutaten (für 1 Person oder Portion)
- 250 ml Vollmilch (mit 3,x % Fett)
- 6 (leicht gehäufte) Esslöffel grobe Haferflocken
- 1 Teelöffel (feiner weißer) Zucker
- 1 Apfel (am besten: Sorte Elstar)
- Zimt
Zubereitung
- Den Apfel mit einer groben Reibe reiben und als "Heuhaufen" in der Mitte eines tiefen Tellers aufbauen.
- Den Berg Apfel großzügig mit Zimt bestreuen.
- Die Haferflocken, Milch und den Zucker in einen Topf geben und bei mittlere Hitze auf den Herd stellen.
- Mit einem Esslöffel kontinuierlich rühren und immer mal wieder kurz pausieren, nur um nicht durch das Rühren den Anfang vom Kochen — mit sichtbarer Blasenbildung — zu verpassen.
- Sobald die Milch beginnt zu kochen, den Topf vom Herd nehmen und die Milch-Haferflocken-Suppe um den Apfelberg herum verteilen.
- Fertig.
Happy new year! / Fwd: Robyn 'Get Myself Together'
Django security hardenings that are not happening
The story behind it
I was pointed to a vulnerable Django setup not too long ago, and had a closer look. Their setup would have allowed potential arbitrary remote code execution through this combination of configurations, with emphasis on combination:
- They were using a Redis database that listens to the public internet for both a Django Celery Queue and a Django cache. With the right credentials, an attacker could talk to the database directly.
- They had Redis credentials — user and password — in the
CELERY_BROKER_URL
Django setting (which is not uncommon with Celery). - Django's
default
SafeExceptionReporterFilter
does not cleanse setting keyCELERY_BROKER_URL
, and so Django's debug mode revealsCELERY_BROKER_URL
content including credentials on server errors. - They had Debug mode enabled by mistake and without knowing, more on how that was possible below.
- They had a Django view that could be forced to crash to then reveal the debug error page.
- Django would un
pickle
anything that an attacker puts into the Redis cache after takeover and thus run attacker code throughpickle
as known for years.
In isolation, none of these cause as big of a problem, but combined
things get scary; looking at that same picture from the opposite side,
fixing any single of these parts would have closed the attack vector as
whole. The affected setup has part (4) fixed now, the
related pull request
is public.
It's a good reminder that in Python both bool('False')
and bool('0')
evaluate to True
even when it feels wrong in some way.
What about closing some of these open doors for everyone and by default, wouldn't that be nice?
Trying to close these open doors by default in Django
Regarding (2) and (3), the CELERY_BROKER_URL
issue with
SafeExceptionReporterFilter
is something that I already
reported over five years ago
but it's easy to argue that never activating debug mode is the only true fix
(and that's not wrong but also doesn't help the situation)
and so it was closed as "wontfix" then, and again this year when I wanted
to give it another shot with a
pull request
when it became clear again to be a killer in practice.
Regarding (4), the debug mode that was enabled by accident could have
been prevented by Django limiting settings.DEBUG
to instances of bool
(or by disallowing string values like
"off"
, "no"
, "0"
, "disabled"
, "false"
, "False"
except the latter approach does not scale well beyond English if that matters).
It can always be argued that we cannot protect all users from themselves
and that this is beyond the line of user responsibility,
but it would have saved that particular setup.
The issue was closed as "wontfix".
Regarding (6), making use of pickle
in caching secure by wrapping it with a
layer of did-we-pickle-this-ourself-earlier protection will cost some
performance (which is yet to be proven critical), but it would make a good
secure default and something that only those users should turn off in order
to re-gain the lost performance who understand their threat model well and
whether it's really okay to own all of Django when the cache database
gets owned.
It was closed as "wontfix".
Because I had one more hardening issue to report that keeps coming up in
the wild, I filed one more issue for the security-by-obscurity issue with
/static/staticfiles.json
where attackers can learn about your Django
dependencies, their precise versions and get new ideas for targetted attacks
from that, in particular with setups missing security updates
(which is the true issue to be fixed in the setup, indeed).
Almost everyone starts hiding that file once made aware of the implications but
the issue was closed as "wontfix".
Four hardening issues closed as "wontfix" felt like an unfortunate pattern to me — I knew "wontfix" as an exception only, even outside of security — so I reached out to the Django security team via e-mail to be sure they were in support of these "wontfix"es and that this was not just one big misunderstanding. They are in support of it and me investing more time in discussions on the forums is their wished way forward, too. So not a misunderstanding.
I have decided to direct my time and energy elsewhere, to rather blog about it here in order to raise awareness about these issues before these doors are closed by default. I also have some hope (just a tiny bit) that maybe one of my readers — could be you — wants to be the force to advance these topics in the Django forums.
Bonus track
Regarding (5), the particular crash I found was interesting.
EmailField
comes with max_length=254
by default and so if you have API endpoints
that ask for well-formed e-mail-addresses and store them into the database
without length validation, passing a too-long-but-well-formed e-mail address
may allow crashing view code (at database entrance) that looks perfectly
healthy at first but doesn't do enough for
validating objects.
Stay secure, and have a nice day!
Sebastian Pipping
Fwd: Seth Godin: Stop Waiting for Permission!
Fwd: Simon Sinek & Trevor Noah on Friendship
Expat 2.6.3 released, includes security fixes
For readers new to Expat:
libexpat is a fast streaming XML parser. Alongside libxml2, Expat is one of the most widely used software libre XML parsers written in C, specifically C99. It is cross-platform and licensed under the MIT license.
Expat 2.6.3 has been released earlier today. The key motivation for cutting a release and cutting it now are the three security findings by TaiYou that were assigned identifiers CVE-2024-45490, CVE-2024-45491 and CVE-2024-45492.
Out of the remaining bunch of fixes in and around the build system, the BSD-motivated portability contributions by Dag-Erling Smørgrav stand out with this release. Thanks to everyone who contributed to this release of Expat!
For more details about this release, please check out the change log.
If you maintain Expat packaging or a bundled copy of Expat or a pinned version of Expat somewhere, please update to 2.6.3. Thank you!
Sebastian Pipping