[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#861958: lintian: insecure YAML validation



clone 861958 -1
reassign -1 libyaml-libyaml-perl
retitle -1 libyaml-libyaml-perl: Unconditionally instantiates objects from yaml data
thanks

Dominique Dumont wrote...

> On samedi 6 mai 2017 13:01:50 CEST you wrote:

> > This module is happy to deserialize objects of any existing Perl class. For
> > Lintian, the File::Temp::Dir class can be abused to remove arbitrary
> > directory trees. (There might be other exciting ways to exploit this bug,
> > but I'm too lazy to investigate further.)
> 
> I wonder if this behavior should be considered as a YAML bug...

At least I consider the unconditional instantiation of object a bug,
hence cloning.

As previously mentioned in debian-perl@, there is no easy solution,
assuming some code out there intentionally uses that feature, and in
a safe matter. If we choose to ignore that, at least for the time being,
we can disable the blessing entirely by dropping the three sv_bless
invocations in <LibYAML/perl_libyaml.c>. This makes the attached
reproducer pass.

Before releasing that change however, there should be an audit of all
the roughly 40 packages in Debian that use YAML::XS to avoid unintended
breakage. In the worst case, that simple approach isn't feasible and
the instantiation needs to be made configurable - something that
requires coordination with upstream[1] and/or other distributions.

We should discuss this during the sprint.

    Christoph

[1] But see https://github.com/perl11/cperl/issues/198
#!/usr/bin/perl

use 5.010;
use strict;
use warnings;

use File::Temp qw(tempdir);
use YAML::XS qw(LoadFile);

my $temp_dir = tempdir (
    "yaml-xs-demo.$$.XXXXX",
    'TMPDIR' => 1,
    'CLEANUP' => 1,
);

my $temp_file = "$temp_dir/story.yaml";

my $pid = fork // die ("Cannot fork: $!");
if ($pid == 0) {
    my $fh;
    open ($fh, '>', $temp_file) or die $!;
    print $fh <<__EOS__;
- !File::Temp::Dir
  CLEANUP: 1
  LAUNCHPID: $$
  REALNAME: $temp_dir
__EOS__
    close ($fh);
    my $data = LoadFile ($temp_file);
    exit 0;
}
wait;

if (-d $temp_dir) {
    print "I: Pass, temp dir is still present\n";
} else {
    print "F: FAIL, temp dir was purged\n";
}

Attachment: signature.asc
Description: Digital signature


Reply to: