Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-92162 — Educational write-up and test-mode PoC for CVE-2026-92162, a path traversal in Flatpak's DeployAppstream arch parameter enabling root directory creation. | Kitploit
Tools/GitHubGitHub/0xsemizzz/cve-2026-92162
Privilege EscalationVulnerability AnalysisExploitationPost-ExploitationPenetration TestingPapers & ResearchLearning & Education
GitHub0xsemizzz/cve-2026-92162

CVE-2026-92162

Educational write-up and test-mode PoC for CVE-2026-92162, a path traversal in Flatpak's DeployAppstream arch parameter enabling root directory creation.

View Repository
14h 22m agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-92162: Flatpak DeployAppstream arch Path Traversal

Educational write up and test mode proof of concept for a path traversal in the Flatpak system helper (flatpak-system-helper). The DeployAppstream D-Bus method accepts an arch string that is placed into a filesystem path and created as root, with no validation. An active local user can supply ../ components and cause the root privileged service to create directories outside the intended appstream tree.

This repository accompanies the full technical analysis and research post-mortem. It exists for education, for defenders who want to understand the mechanism, and for authorized testing on systems you own or have written permission to assess.

Responsible use

This material is published after coordinated disclosure and after a fixed Flatpak release was made available. Run the proof of concept only against a lab machine that you own or are explicitly authorized to test. Do not run it against systems you do not control. You are responsible for staying within the law and within the scope of any authorization you hold.

The issue in one paragraph

handle_deploy_appstream() in the system helper validates the origin argument but not the arch argument. For an OCI remote, arch flows into flatpak_build_file and then g_mkdir_with_parents, which runs as root and resolves ../ lexically. The polkit action for the method is org.freedesktop.Flatpak.appstream-update, which is allow_active=yes, so an active local session reaches the code with no password prompt. On a system that already has an OCI remote, such as a default Fedora Workstation with its fedora remote, a low privileged user can create root owned directories at an arbitrary path. The payload in this repository targets /root/.ssh itself.

Part of a two vulnerability chain

This vulnerability, Finding A, was demonstrated as part of a two vulnerability chain used to escalate from an unauthenticated local user to root on the machine, in a controlled and authorized lab. The chain works as follows: Finding A creates /root/.ssh as root. Finding B, a secondary write primitive, can then write attacker controlled content into that directory. Together they give an attacker a root owned file at an attacker chosen path. Each bug alone is limited: Finding A only creates directories, and Finding B can only write where a parent directory already exists. Finding A supplies the parent directory that Finding B needs, and the pair becomes root file write.

Finding B was independently identified by this research, but it is not a new finding: it is the known, still unpatched weakness in the extra data write path of Deploy documented in the research post-mortem. This write up therefore covers and is credited for Finding A, and uses Finding B only as the known, unpatched component that the chain relies on.

This repository demonstrates Finding A only. The chaining methodology and the defensive lessons are documented in the research post-mortem.

The fix

The project already ships flatpak_is_valid_arch, which restricts an architecture name to [A-Za-z0-9_]. The remediation is to call it on the arch argument at the handler boundary and inside the path building helpers. A ../ value cannot pass that predicate. Update to the fixed Flatpak release.

Repository layout

root@kitploit:~
.
├── README.md                 This file.
├── requirements.txt          System package prerequisites for the PoC.
└── poc_arch_traversal.sh     PoC for the unvalidated arch parameter.
                              Sandboxed test mode by default, production
                              mode targets /root/.ssh. Educational use only.

How to use

Prerequisites

  • A Linux machine with flatpak installed and the requirements.txt packages present.
  • A local console login (not SSH) if you run the production mode, because the trigger relies on polkit allow_active=yes. Check with: loginctl list-sessions and confirm your session shows a seat.
  • No OCI registry is needed. The directory is created before any network fetch, so the registry URL is never contacted successfully.
  • The helper binary defaults to /usr/libexec/flatpak-system-helper; the script first looks for a freshly built helper in builddir/ or _build/ of the Flatpak source tree, and FLATPAK_SYSTEM_HELPER overrides everything. See requirements.txt for the system packages needed.

Step 0: check for an OCI remote

The production mode auto-detects an existing OCI remote on the system installation and uses it. Any OCI remote works, even a fake or unreachable one, because the mkdir happens before the registry is ever contacted. If no OCI remote exists, the script cancels with a "No OCI remote found" message and sends nothing.

Fedora Workstation already ships the OCI fedora remote, so nothing needs to be done there. Check what exists with flatpak remotes --system (an OCI remote shows oci in its options column).

Step 1: add an OCI remote (only if Step 0 found none)

This is the only command in the whole flow that needs sudo, and the script never runs it for you. Add one with:

root@kitploit:~
sudo flatpak remote-add --system --no-gpg-verify oci-poc oci+http://127.0.0.1:19876

(flatpak has no --oci flag, at least through 1.19.0, the version this work is based on; the oci+ URL prefix is what makes the remote an OCI registry.) A "Warning: Could not update extra metadata" message is expected when no registry is running; the remote is still added.

Step 2: run the sandboxed test mode (safe, no root)

root@kitploit:~
bash poc_arch_traversal.sh

The script starts a private D-Bus bus and a helper in --session mode, all under a temporary directory. It calls DeployAppstream with the payload ../../../../../root/.ssh and verifies that the escaped directory was created at <workdir>/root/.ssh, mirroring the real target. Expect a D-Bus error in the middle of the output: that is the OCI index fetch failing after the directory was already created, and it is the expected behavior.

Step 3: run the production mode (creates /root/.ssh as root)

root@kitploit:~
bash poc_arch_traversal.sh prod

The script never asks for a password. It auto-detects an OCI remote, triggers DeployAppstream unauthenticated with the traversal payload, and prints the helper's response. The root helper creates /root/.ssh and then fails on the unreachable registry, which prints the expected D-Bus error. If the response is an authentication error instead, you are not in an active local session; run it from the machine's console. A specific remote can be forced with bash poc_arch_traversal.sh prod <remote>.

Step 4: verify it yourself

The trigger itself runs unprivileged, but confirming the result needs root, so the script leaves that to you. After the run, on the same machine:

root@kitploit:~
sudo ls -laR /root/.ssh
sudo stat -c '%U:%G' /root/.ssh

The directory must exist and be owned by root:root. The D-Bus error in the script output is not a failure: it proves the mkdir ran before the fetch, since the escaped directory exists even though the method call failed.

If /root/.ssh already existed before the run (for example on a host with a running sshd), the run is a no-op on that path and leaves nothing behind: the helper's lock file is transient and is removed when the method returns, and icons is only written after a successful index fetch. For a clean verification, run against a path that does not exist yet.

Cleanup

root@kitploit:~
sudo rm -rf /root/.ssh      # only if it did not exist before the run
sudo flatpak remote-delete --system oci-poc

Credit

Research and write up by Yehia Ali Mohamed Ezzat.

  • GitHub: 0xSemizzz
  • Site: https://0xsemizzz.vercel.app/

License

Documentation and code in this repository are provided for educational purposes. Use at your own risk and only where you are authorized.

Download Tool