3 added 1152 characters in body
source | link

If you're using system() within C to invoke shell commands that take arguments, best is to use the environment to pass those arguments to avoid having to quote them.

With the path of the file (containing any character) stored at file_path:

if (setenv("FILE", file_path, 1) < 0) {
  perror("setenv");
  exit(1);
}
system("mkdir -p -- \"$(dirname -- \"$FILE\")\" && touch -- \"$FILE\"");

That way, you're passing a fixed string to sh -c (called by system() internally) and don't have to worry with arbitrary code injection vulnerabilities as long as your shell code is correct (note the quotes and -- above).

(the above has the usual sh command substitution issue whereby all trailing newline characters are stripped, so it would fail on a file_path like foo/bar\n/file. I'll leave it to you to decide if you want to make the effort to work around that).

If you wanted to pass the file names in the shell code passed to system(), do not do:

sprintf(cmd, "mkdir -p -- \"%s\" && touch -- \"%s\"", dir_path, file_path);

as that would still be a command injection vulnerability (for instance with a filename like $(reboot) or ";reboot;:". Same if you used single quotes instead of double quotes.

You'd need:

sprintf(cmd, "mkdir -p -- %s && touch -- %s",
  shquote(dir_path), shquote(file_path));

where shquote() would be a function (whose implementation is left as an exercise) that replaces every ' character with '\'' and encloses the result in single quotes. So for instance returns 'foo'\''bar' for foo'bar (bear in mind that the length of the quoted file can be up to 4 * length + 2, which you'll need to take into account when allocating space for the cmd buffer).

That's the safest quoting approaches. Quoting approaches that use double quotes or backslashes all have issues in some locales using exotic charsets that can cause arbitrary code injection vulnerabilities.

If you're using system() within C to invoke shell commands that take arguments, best is to use the environment to pass those arguments to avoid having to quote them:

if (setenv("FILE", file_path, 1) < 0) {
  perror("setenv");
  exit(1);
}
system("mkdir -p -- \"$(dirname -- \"$FILE\")\" && touch -- \"$FILE\"");

That way, you're passing a fixed string to sh -c (called by system() internally) and don't have to worry with arbitrary code injection vulnerabilities as long as your shell code is correct (note the quotes and -- above).

If you wanted to pass the file names in the shell code passed to system(), do not do:

sprintf(cmd, "mkdir -p -- \"%s\" && touch -- \"%s\"", dir_path, file_path);

as that would still be a command injection vulnerability (for instance with a filename like $(reboot) or ";reboot;:". Same if you used single quotes instead of double quotes.

You'd need:

sprintf(cmd, "mkdir -p -- %s && touch -- %s",
  shquote(dir_path), shquote(file_path));

where shquote() would be a function (whose implementation is left as an exercise) that replaces every ' character with '\'' and encloses the result in single quotes. So for instance returns 'foo'\''bar' for foo'bar.

That's the safest quoting approaches. Quoting approaches that use double quotes or backslashes all have issues in some locales using exotic charsets that can cause arbitrary code injection vulnerabilities.

If you're using system() within C to invoke shell commands that take arguments, best is to use the environment to pass those arguments to avoid having to quote them.

With the path of the file (containing any character) stored at file_path:

if (setenv("FILE", file_path, 1) < 0) {
  perror("setenv");
  exit(1);
}
system("mkdir -p -- \"$(dirname -- \"$FILE\")\" && touch -- \"$FILE\"");

That way, you're passing a fixed string to sh -c (called by system() internally) and don't have to worry with arbitrary code injection vulnerabilities as long as your shell code is correct (note the quotes and -- above).

(the above has the usual sh command substitution issue whereby all trailing newline characters are stripped, so it would fail on a file_path like foo/bar\n/file. I'll leave it to you to decide if you want to make the effort to work around that).

If you wanted to pass the file names in the shell code passed to system(), do not do:

sprintf(cmd, "mkdir -p -- \"%s\" && touch -- \"%s\"", dir_path, file_path);

as that would still be a command injection vulnerability (for instance with a filename like $(reboot) or ";reboot;:". Same if you used single quotes instead of double quotes.

You'd need:

sprintf(cmd, "mkdir -p -- %s && touch -- %s",
  shquote(dir_path), shquote(file_path));

where shquote() would be a function (whose implementation is left as an exercise) that replaces every ' character with '\'' and encloses the result in single quotes. So for instance returns 'foo'\''bar' for foo'bar (bear in mind that the length of the quoted file can be up to 4 * length + 2, which you'll need to take into account when allocating space for the cmd buffer).

That's the safest quoting approaches. Quoting approaches that use double quotes or backslashes all have issues in some locales using exotic charsets that can cause arbitrary code injection vulnerabilities.

2 added 1152 characters in body
source | link

If you're using system() within C to invoke shell commands that take arguments, best is to use the environment to pass those arguments to avoid having to quote them:

if (setenv("FILE", file_path, 1) < 0) {
  perror("setenv");
  exit(1);
}
system("mkdir -p -- \"$(dirname -- \"$FILE\")\" && touch -- \"$FILE\"");

That way, you're passing a fixed string to sh -c (called by system() internally) and don't have to worry with arbitrary code injection vulnerabilities as long as your shell code is correct (note the quotes and -- above).

If you wanted to pass the file names in the shell code passed to system(), do not do:

sprintf(cmd, "mkdir -p -- \"%s\" && touch -- \"%s\"", dir_path, file_path);

as that would still be a command injection vulnerability (for instance with a filename like $(reboot) or ";reboot;:". Same if you used single quotes instead of double quotes.

You'd need:

sprintf(cmd, "mkdir -p -- %s && touch -- %s",
  shquote(dir_path), shquote(file_path));

where shquote() would be a function (whose implementation is left as an exercise) that replaces every ' character with '\'' and encloses the result in single quotes. So for instance returns 'foo'\''bar' for foo'bar.

That's the safest quoting approaches. Quoting approaches that use double quotes or backslashes all have issues in some locales using exotic charsets that can cause arbitrary code injection vulnerabilities.

If you're using system() within C to invoke shell commands that take arguments, best is to use the environment to pass those arguments to avoid having to quote them:

if (setenv("FILE", file_path, 1) < 0) {
  perror("setenv");
  exit(1);
}
system("mkdir -p -- \"$(dirname -- \"$FILE\")\" && touch -- \"$FILE\"");

If you're using system() within C to invoke shell commands that take arguments, best is to use the environment to pass those arguments to avoid having to quote them:

if (setenv("FILE", file_path, 1) < 0) {
  perror("setenv");
  exit(1);
}
system("mkdir -p -- \"$(dirname -- \"$FILE\")\" && touch -- \"$FILE\"");

That way, you're passing a fixed string to sh -c (called by system() internally) and don't have to worry with arbitrary code injection vulnerabilities as long as your shell code is correct (note the quotes and -- above).

If you wanted to pass the file names in the shell code passed to system(), do not do:

sprintf(cmd, "mkdir -p -- \"%s\" && touch -- \"%s\"", dir_path, file_path);

as that would still be a command injection vulnerability (for instance with a filename like $(reboot) or ";reboot;:". Same if you used single quotes instead of double quotes.

You'd need:

sprintf(cmd, "mkdir -p -- %s && touch -- %s",
  shquote(dir_path), shquote(file_path));

where shquote() would be a function (whose implementation is left as an exercise) that replaces every ' character with '\'' and encloses the result in single quotes. So for instance returns 'foo'\''bar' for foo'bar.

That's the safest quoting approaches. Quoting approaches that use double quotes or backslashes all have issues in some locales using exotic charsets that can cause arbitrary code injection vulnerabilities.

1
source | link

If you're using system() within C to invoke shell commands that take arguments, best is to use the environment to pass those arguments to avoid having to quote them:

if (setenv("FILE", file_path, 1) < 0) {
  perror("setenv");
  exit(1);
}
system("mkdir -p -- \"$(dirname -- \"$FILE\")\" && touch -- \"$FILE\"");