-
-
Notifications
You must be signed in to change notification settings - Fork 79
Harden system calls #1392
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Harden system calls #1392
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -271,12 +271,18 @@ sub draw { | |||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| sub use_svgMethod { | ||||||||||||||||||||||||||
| my ($self, $working_dir) = @_; | ||||||||||||||||||||||||||
| if ($self->svgMethod eq 'dvisvgm') { | ||||||||||||||||||||||||||
| system WeBWorK::PG::IO::externalCommand('dvisvgm') | ||||||||||||||||||||||||||
| . " $working_dir/image.dvi --no-fonts --output=$working_dir/image.svg > /dev/null 2>&1"; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Validate svgMethod against known SVG converters to prevent command injection. | ||||||||||||||||||||||||||
| my $method = $self->svgMethod; | ||||||||||||||||||||||||||
| if ($method eq 'dvisvgm') { | ||||||||||||||||||||||||||
| my $cmd = WeBWorK::PG::IO::externalCommand('dvisvgm'); | ||||||||||||||||||||||||||
| system {$cmd} $cmd, "$working_dir/image.dvi", '--no-fonts', "--output=$working_dir/image.svg"; | ||||||||||||||||||||||||||
| } elsif ($method eq 'pdf2svg') { | ||||||||||||||||||||||||||
| my $cmd = WeBWorK::PG::IO::externalCommand('pdf2svg'); | ||||||||||||||||||||||||||
| system {$cmd} $cmd, "$working_dir/image.pdf", "$working_dir/image.svg"; | ||||||||||||||||||||||||||
|
Comment on lines
+277
to
+282
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, looking closer at this I see that the |
||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||
| system WeBWorK::PG::IO::externalCommand($self->svgMethod) | ||||||||||||||||||||||||||
| . " $working_dir/image.pdf $working_dir/image.svg > /dev/null 2>&1"; | ||||||||||||||||||||||||||
| warn "Unknown svgMethod '$method'. Must be 'dvisvgm' or 'pdf2svg'."; | ||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| warn "Failed to generate svg file." unless -r "$working_dir/image.svg"; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
@@ -285,11 +291,24 @@ sub use_svgMethod { | |||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| sub use_convert { | ||||||||||||||||||||||||||
| my ($self, $working_dir, $ext) = @_; | ||||||||||||||||||||||||||
| system WeBWorK::PG::IO::externalCommand('convert') | ||||||||||||||||||||||||||
| . join('', map { " -$_ " . $self->convertOptions->{input}->{$_} } (keys %{ $self->convertOptions->{input} })) | ||||||||||||||||||||||||||
| . " $working_dir/image.pdf" | ||||||||||||||||||||||||||
| . join('', map { " -$_ " . $self->convertOptions->{output}->{$_} } (keys %{ $self->convertOptions->{output} })) | ||||||||||||||||||||||||||
| . " $working_dir/image.$ext > /dev/null 2>&1"; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Validate convertOptions keys and values to prevent shell injection. | ||||||||||||||||||||||||||
| # Only alphanumeric option names and simple values are permitted. | ||||||||||||||||||||||||||
| my @args; | ||||||||||||||||||||||||||
| for my $phase (qw(input output)) { | ||||||||||||||||||||||||||
| my $opts = $self->convertOptions->{$phase} // {}; | ||||||||||||||||||||||||||
| for my $key (keys %$opts) { | ||||||||||||||||||||||||||
| warn("Invalid convert option name: $key"), next unless $key =~ /^[a-zA-Z][a-zA-Z0-9\-]*$/; | ||||||||||||||||||||||||||
| my $val = $opts->{$key}; | ||||||||||||||||||||||||||
| warn("Invalid convert option value for $key"), next unless defined $val && $val =~ /^[a-zA-Z0-9.\-+:x%]+$/; | ||||||||||||||||||||||||||
|
Comment on lines
+301
to
+303
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I mentioned this validation should be done in the
Suggested change
Don't use commas to separate statements. This is bad practice. See https://metacpan.org/pod/Perl::Critic::Policy::ValuesAndExpressions::ProhibitCommaSeparatedStatements. |
||||||||||||||||||||||||||
| push @args, "-$key", $val; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| push @args, "$working_dir/image.pdf" if $phase eq 'input'; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| push @args, "$working_dir/image.$ext"; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| my $convert = WeBWorK::PG::IO::externalCommand('convert'); | ||||||||||||||||||||||||||
| system {$convert} $convert, @args; | ||||||||||||||||||||||||||
| warn "Failed to generate $ext file." unless -r "$working_dir/image.$ext"; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -270,7 +270,7 @@ sub convert_file_to_png_for_tex { | |
| $self->debug_message('convert filePath ', $sourceFilePath, "\n"); | ||
|
|
||
| my $conversion_command = WeBWorK::PG::IO::externalCommand('convert'); | ||
| my $returnCode = system "$conversion_command '${sourceFilePath}[0]' $targetFilePath"; | ||
| my $returnCode = system {$conversion_command} $conversion_command, "${sourceFilePath}[0]", $targetFilePath; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think there is really any benefit or added security by using This is true for all of the places where you have done this. Since the program name is the same it won't actually do anything different. It is just making the code line longer. There is benefit to switching from the pure string argument to the list argument since it avoids invoking the shell and thus avoids potential shell expansion, but adding the program name does not add anything since they are the same. |
||
| if ($returnCode || !-e $targetFilePath) { | ||
| $resource_object->warning_message( | ||
| qq{Failed to convert "$sourceFilePath" to "$targetFilePath" using "$conversion_command": $!}); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The places that you are doing the validation in this file are not the right places for the validation. It should be done in the
$selfmethod when thesvgMethodorconvertOptionsis set. That is defined on lines 32 - 44 of this file. Validation to protect system calls against injection is exactly the point of using a blessed$selfmethod instead of a blessed$selfhash, and it is already validating theextfield in this way.I can't believe that I was this sloppy when the
svgMethodandconvertOptionswere added by not taking care of validation. Theextvalidation was in the initial code, and those were added later.