fast-import: disallow "feature import-marks" by default
As with export-marks in the previous commit, import-marks can access the filesystem. This is significantly less dangerous than export-marks because it only involves reading from arbitrary paths, rather than writing them. However, it could still be surprising and have security implications (e.g., exfiltrating data from a service that accepts fast-import streams). Let's lump it (and its "if-exists" counterpart) in with export-marks, and enable the in-stream version only if --allow-unsafe-features is set. Signed-off-by: Jeff King <peff@peff.net>maint
parent
68061e3470
commit
a52ed76142
|
@ -57,7 +57,8 @@ OPTIONS
|
||||||
allowing fast-import to access the filesystem outside of the
|
allowing fast-import to access the filesystem outside of the
|
||||||
repository). These options are disabled by default, but can be
|
repository). These options are disabled by default, but can be
|
||||||
allowed by providing this option on the command line. This
|
allowed by providing this option on the command line. This
|
||||||
currently impacts only the `feature export-marks` command.
|
currently impacts only the `export-marks`, `import-marks`, and
|
||||||
|
`import-marks-if-exists` feature commands.
|
||||||
+
|
+
|
||||||
Only enable this option if you trust the program generating the
|
Only enable this option if you trust the program generating the
|
||||||
fast-import stream! This option is enabled automatically for
|
fast-import stream! This option is enabled automatically for
|
||||||
|
|
|
@ -3344,8 +3344,10 @@ static int parse_one_feature(const char *feature, int from_stream)
|
||||||
if (skip_prefix(feature, "date-format=", &arg)) {
|
if (skip_prefix(feature, "date-format=", &arg)) {
|
||||||
option_date_format(arg);
|
option_date_format(arg);
|
||||||
} else if (skip_prefix(feature, "import-marks=", &arg)) {
|
} else if (skip_prefix(feature, "import-marks=", &arg)) {
|
||||||
|
check_unsafe_feature("import-marks", from_stream);
|
||||||
option_import_marks(arg, from_stream, 0);
|
option_import_marks(arg, from_stream, 0);
|
||||||
} else if (skip_prefix(feature, "import-marks-if-exists=", &arg)) {
|
} else if (skip_prefix(feature, "import-marks-if-exists=", &arg)) {
|
||||||
|
check_unsafe_feature("import-marks-if-exists", from_stream);
|
||||||
option_import_marks(arg, from_stream, 1);
|
option_import_marks(arg, from_stream, 1);
|
||||||
} else if (skip_prefix(feature, "export-marks=", &arg)) {
|
} else if (skip_prefix(feature, "export-marks=", &arg)) {
|
||||||
check_unsafe_feature(feature, from_stream);
|
check_unsafe_feature(feature, from_stream);
|
||||||
|
|
|
@ -2106,6 +2106,14 @@ test_expect_success 'R: abort on receiving feature after data command' '
|
||||||
test_must_fail git fast-import <input
|
test_must_fail git fast-import <input
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'R: import-marks features forbidden by default' '
|
||||||
|
>git.marks &&
|
||||||
|
echo "feature import-marks=git.marks" >input &&
|
||||||
|
test_must_fail git fast-import <input &&
|
||||||
|
echo "feature import-marks-if-exists=git.marks" >input &&
|
||||||
|
test_must_fail git fast-import <input
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'R: only one import-marks feature allowed per stream' '
|
test_expect_success 'R: only one import-marks feature allowed per stream' '
|
||||||
>git.marks &&
|
>git.marks &&
|
||||||
>git2.marks &&
|
>git2.marks &&
|
||||||
|
@ -2114,7 +2122,7 @@ test_expect_success 'R: only one import-marks feature allowed per stream' '
|
||||||
feature import-marks=git2.marks
|
feature import-marks=git2.marks
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
test_must_fail git fast-import <input
|
test_must_fail git fast-import --allow-unsafe-features <input
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'R: export-marks feature forbidden by default' '
|
test_expect_success 'R: export-marks feature forbidden by default' '
|
||||||
|
@ -2210,7 +2218,8 @@ test_expect_success 'R: feature import-marks-if-exists' '
|
||||||
rm -f io.marks &&
|
rm -f io.marks &&
|
||||||
>expect &&
|
>expect &&
|
||||||
|
|
||||||
git fast-import --export-marks=io.marks <<-\EOF &&
|
git fast-import --export-marks=io.marks \
|
||||||
|
--allow-unsafe-features <<-\EOF &&
|
||||||
feature import-marks-if-exists=not_io.marks
|
feature import-marks-if-exists=not_io.marks
|
||||||
EOF
|
EOF
|
||||||
test_cmp expect io.marks &&
|
test_cmp expect io.marks &&
|
||||||
|
@ -2221,7 +2230,8 @@ test_expect_success 'R: feature import-marks-if-exists' '
|
||||||
echo ":1 $blob" >expect &&
|
echo ":1 $blob" >expect &&
|
||||||
echo ":2 $blob" >>expect &&
|
echo ":2 $blob" >>expect &&
|
||||||
|
|
||||||
git fast-import --export-marks=io.marks <<-\EOF &&
|
git fast-import --export-marks=io.marks \
|
||||||
|
--allow-unsafe-features <<-\EOF &&
|
||||||
feature import-marks-if-exists=io.marks
|
feature import-marks-if-exists=io.marks
|
||||||
blob
|
blob
|
||||||
mark :2
|
mark :2
|
||||||
|
@ -2234,7 +2244,8 @@ test_expect_success 'R: feature import-marks-if-exists' '
|
||||||
echo ":3 $blob" >>expect &&
|
echo ":3 $blob" >>expect &&
|
||||||
|
|
||||||
git fast-import --import-marks=io.marks \
|
git fast-import --import-marks=io.marks \
|
||||||
--export-marks=io.marks <<-\EOF &&
|
--export-marks=io.marks \
|
||||||
|
--allow-unsafe-features <<-\EOF &&
|
||||||
feature import-marks-if-exists=not_io.marks
|
feature import-marks-if-exists=not_io.marks
|
||||||
blob
|
blob
|
||||||
mark :3
|
mark :3
|
||||||
|
@ -2247,7 +2258,8 @@ test_expect_success 'R: feature import-marks-if-exists' '
|
||||||
>expect &&
|
>expect &&
|
||||||
|
|
||||||
git fast-import --import-marks-if-exists=not_io.marks \
|
git fast-import --import-marks-if-exists=not_io.marks \
|
||||||
--export-marks=io.marks <<-\EOF &&
|
--export-marks=io.marks \
|
||||||
|
--allow-unsafe-features <<-\EOF &&
|
||||||
feature import-marks-if-exists=io.marks
|
feature import-marks-if-exists=io.marks
|
||||||
EOF
|
EOF
|
||||||
test_cmp expect io.marks
|
test_cmp expect io.marks
|
||||||
|
|
Loading…
Reference in New Issue