Security
This page describes the subset of my contributions related to the security of open-source projects.
Motivation
In October 2020, I noticed that Ubuntu and other Linux distributions were not keeping pace with the rapid release schedules of many software development tools. To use the latest releases, I started downloading and installing the tools from their vendor’s or project’s website instead of getting them solely from the Ubuntu package repositories that provide my operating system.
In December 2020, I learned of the SolarWinds attack and became increasingly worried about the software on my workstation. I was particularly concerned that the developer tools I had installed were adding hundreds of trusted sources to my system through their build-time dependencies and run-time plugins. The current releases of the tools were not available from Ubuntu, but I was no longer willing to trust any packages built elsewhere.
To solve this dilemma, I started working with the upstream projects to close the gaps in their security by:
- adding dependency verification,
- enabling reproducible builds, and
- creating verifiable builds.
Dependency Verification
OpenJFX is the open-source project that develops JavaFX. It uses a complex build system based on Gradle to build JavaFX and its native libraries on Linux, macOS, and Windows. My first goal was to add the three security measures recommended by the Gradle team for any project using Gradle:
Project | Issue | Fix | Integrated | Summary |
---|---|---|---|---|
OpenJFX | JDK-8262236 | #411 | 2021-02-23 | Configure Gradle checksum verification |
OpenJFX | JDK-8263204 | #419 | 2021-03-09 | Add Gradle Wrapper Validation Action |
OpenJFX | JDK-8264010 | #437 | 2021-05-03 | Add Gradle dependency verification |
These changes reduce the risk of compromising the build system or including malware in JavaFX.
Reproducible Builds
In March 2021, I got involved in the Reproducible Builds project when I saw that Bernhard Wiedemann’s initial pull request for JavaFX had stalled. I created a new pull request that was broader in scope and sought to enable reproducible builds for all JavaFX artifacts on all three platforms: Linux, macOS, and Windows. After more than two years of code reviews, cross-platform testing, patience, and persuasion, the pull request was approved by the project’s lead reviewers in June 2023.
The experience I gained working on the JavaFX pull request allowed me to be the main reviewer of a related enhancement to the jar
and jmod
tools of the Java Development Kit (JDK).
During this time, I also found and fixed the last remaining bug that blocked reproducible builds of the JDK. The bug was especially interesting because, although its cause was unrelated to reproducible builds, it would have been practically impossible to find without them.
All three contributions are listed below. I reviewed the first pull request and authored the other two:
Project | Issue | Fix | Integrated | Summary |
---|---|---|---|---|
JDK | JDK-8276766 | #6481 | 2021-12-11 | Enable jar and jmod to produce deterministic timestamped content |
JDK | JDK-8292892 | #10070 | 2022-09-21 | Javadoc index descriptions are not deterministic |
OpenJFX | JDK-8264449 | #446 | 2023-06-20 | Enable reproducible builds with SOURCE_DATE_EPOCH |
These changes allow anyone to publish reproducible builds of the JDK and JavaFX.
Verifiable Builds
I decided early on to publish my own builds of the tools I use in software development. By building the tools on the same Launchpad build farm that builds the Ubuntu operating system, I could once again have a single trusted source for all of the software on my workstation.
The easiest way to build software on Launchpad, especially for Ubuntu, is by creating a Snap package. Snap packages have the additional security benefit of running in complete isolation with limited access to the system. I created Snap packages of the JDK and JavaFX with the goal of providing the most open and transparent builds available and allowing developers to verify exactly where and how each package was built. See the Verify section of the README files for details.
Project | Source | Package | Published | Summary |
---|---|---|---|---|
OpenJFX | openjfx | openjfx | 2020-11-25 | Current JavaFX release and early-access builds |
JDK | openjdk | openjdk | 2020-12-03 | Current JDK release and early-access builds |
I also created strictly-confined packages of Apache NetBeans and Apache Maven:
Project | Source | Package | Published | Summary |
---|---|---|---|---|
NetBeans | strictly-netbeans | strictly-netbeans | 2022-06-01 | Apache NetBeans® in a strictly-confined snap |
Maven | strictly-maven | strictly-maven | 2022-06-01 | Apache Maven™ in a strictly-confined snap |
These packages allow developers on Linux to install, verify, and run a complete set of development tools that includes the Java Development Kit, Apache Maven, and Apache NetBeans, all within a strictly-confined environment on their system.
Remaining Work
Although the bulk of work related to reproducible builds is complete for the JDK and OpenJFX projects, that work uncovered the following additional issues:
- JDK-8306884: Building WebKit on Linux is not deterministic
- JDK-8306885: Building WebKit on Windows is not deterministic
- Building the optional WebKit native library for JavaFX on Linux or Windows is often not deterministic.
The library, called
libjfxwebkit.so
on Linux andjfxwebkit.dll
on Windows, is usually different from one build to the next even on the same system with the same project path. - JDK-8306886: Building macOS libraries can be non-deterministic
- There are often differences in some of the JavaFX native libraries between any two builds on macOS, such as
libjavafx_iio.dylib
,libglib-lite.dylib
, andlibjfxwebkit.dylib
. - JDK-8307082: Build path is recorded in JavaFX Controls module
- The absolute path of the project directory ends up in the JavaFX Controls module
javafx.controls.jar
, breaking reproducible builds for systems using different build paths.