Rosenpass Penetration Test

Radically Open Security’s penetration test of the Rosenpass project

Last month, we had the good fortune to collaborate with Radically Open Security (ROS), who ran a series of penetration tests on our Rosenpass project with the aim of identifying, and then addressing, any unseen security flaws in the project. These tests were primarily undertaken by Morgan Hill, a freelance security consultant working with ROS who focuses on Rust language projects. The report produced from these tests forms the basis of this blogpost and can be found in both the documentation section and linked below.

As always in this business, what was secure yesterday may be broken today, and thus we are always grateful to those who test our set ups. We were particularly keen to work with Radically Open Security, as an organisation strongly committed to maintaining, and improving the security of the internet as a whole. They make a point of releasing theirs tools as open source software for wider use and adoption, as well as providing detailed explanations to their partners on how to perform the same audits themselves.

The results of this penetration test were promising, with one moderate and three low risk issues found, alongside one inconsistency in documentation. The moderate risk was addressed promptly in the Rosenpass 0.2.1 release, with work planned on the low risk issues.

Methodolodgy

To penetration test and audit Rosenpass Radically Open Security employed a series of stages to discover weekenesses. First, they seek a high level overview of the code and its dependencies. To do this in Rust projects they use cargo audit which lists any known vulnerabilities found in dependencies. For Rust projects cargo geiger is a valuable tool to identify unsafe blocks that typically warrant extra attention at the code audit stage. If there is unsafe code present then miri can be used to identify potential issues such as race conditions and undefined behaviour.

Secondly, ROS begin a comprehensive code audit. A code audit involves going through each line of code with a fine-tooth comb. The aim is not only to understand what each line is intended to do, but importantly to understand what each line allows to be done. Special attention is showen to unsafe code blocks, networking code or anything parsing user input. The pentester may write stubs to run interesting code paths and attach debuggers to assess the realworld behviour.

Thirdly, ROS utilizes fuzzing for a belt and braces approach. Fuzzing is a method of rapidly testing code paths with a barrage of computer generated input that can turn up issues not spotted by human eyes. Rust provides a very low friction entry into fuzzing with cargo fuzz which uses libfuzzer to get started with basic coverage guided fuzzing. To fuzz the penentester must idenify interesting functions and write fuzz targets to harness them. These fuzz targets can be contributed back to the project. If libfuzzer is insuffecent then the targets can be use with other fuzzers such as AFL++.

Discovered vulnerabilities are then classified according to the scale of the risk they pose:

  • Extreme. Where there is an extreme risk of security controls becoming compromised, with the possibility of catastrophic losses.
  • High. Where there is a high risk of security controls becoming compromised, with the possibility for significant losses.
  • Elevated. Where there is an elevated risk of security controls becoming compromised, with the possibility for material losses.
  • Moderate. Where there is a moderate risk of security controls becoming compromised, with the possibility for limited losses.
  • Low. Where there is a low risk of security controls becoming compromised, with the possibility for measurable negative impacts.

Results

Message Handler vulnerability to DoS (Denial of Service) attack

Moderate risk

The penetration test found a vulnerability in Rosenpass’ message handler, as it previously did not validate the length of a message. If an attacker sent a small UDP datagram to the target, this could result in a panic, crashing the Rosenpass program and halting the key exchange. This could result in a pre-shared key becoming stale, or the exchange never occurring in the first place. By default, user data would continue to be passed by the WireGuard interface. A stale key would be logged, but its notice would subject to user error.

This issue was assigned RUSTSEC-2023-0077 in the Rust security advisory database.

ROS suggests checking the message length against what is expected before its processing.

Temporary exposure of SSH private key to other users on the host

Low risk

It was also discovered that the GitLab CI (Continuous Integration) configuration may temporarily expose an SSH private key to other users on the host, as the file mode is set after the file is written. An attacker with persistence as another on the CI runner may be able to monitor for, and take advantage of, this momentary exposure to steal the private key.

ROS suggests running umask 077 before writing the SSH private key to the filesystem.

Two issues relating to unmaintained GitHub Actions

Low risk

In both the release and quality control GitHub workflows, an unmaintained action was discovered. Use of unmaintained actions pose a security risk as, as always, what was secure yesterday may be broken today. The first, softprops/action-gh-release, and the second, actions-rs/audit-check are thus both in need of replacement. It is also important to monitor dependencies such as this, to ensure that they remain maintained over time.

The RespHello Biscuit and Auth fields are swapped in the implementation versus the protocol paper

Inapplicable risk

An inconsistency was discovered in the order of these fields between implementation and its documentation. Although this issue has not manifested in either the Rust nor Go implementation of Rosenpass, it poses a potential issue for any future third party implementations that rely on the protocol paper. The paper should be updated to match the implementation.

Conclusions

We are pleased to say that no severe security risks were discovered in the course of ROS’ penetration test. We remain grateful for the opportunity to have had our project be subjected to an unbiased audit, especially as a young project aiming to provide production-ready Post-Quantum solutions.

Morgan Hill’s work primarily comprised a line-by-line code audit, generating several leads that were then subject to further interrogation. Finding generally high-quality code, alongside the safety characteristics of the Rust programming Language, most of these leads could be safely disregarded.

The ROS report notes the high responsiveness of the Rosenpass developers, who were quick to respond to the moderate issue, allowing it the be fixed and successfully re-tested before the publication of this report.

The ROS report also notes that its overall impression of Rosenpass is that “of a responsive and engaged project utilizing modern tools to achieve their aims”, although there is further work to be undertaken to resolve the hardening issues discovered in Rosenpass’ CI/CD.

As can never be overstated, an audit such as this, however successful, is but a snapshot of a project’s security. It is deeply important to continually assess and improve upon Rosenpass’ security, responding to new threats before they become severe.

We would like to extend a heartfelt “thank you” Radically Open Security, as well as personally to Morgan Hill, who carried out this penetration test. We look forward to future opportunities to collaborate, and to further improve our project.

Radically Open Security’s report can be read in full here.