Bläddra i källkod

Fix #306 - Filter invalid input

George Baugh 2 år sedan
förälder
incheckning
208c13b8a7
1 ändrade filer med 46 tillägg och 0 borttagningar
  1. 46 0
      lib/Trog/DataModule.pm

+ 46 - 0
lib/Trog/DataModule.pm

@@ -9,6 +9,7 @@ use File::Copy;
 use Mojo::File;
 use Mojo::File;
 use Plack::MIME;
 use Plack::MIME;
 use Path::Tiny();
 use Path::Tiny();
+use Ref::Util();
 
 
 use Trog::Utils;
 use Trog::Utils;
 use Trog::Auth();
 use Trog::Auth();
@@ -257,14 +258,59 @@ If any post already exists with the same id, a new post with a version higher th
 
 
 Passes an array of new posts to add to the data store module's write() function.
 Passes an array of new posts to add to the data store module's write() function.
 
 
+These will have their parameters filtered to those present in the %schema hash.
+
 You probably won't want to override this.
 You probably won't want to override this.
 
 
 =cut
 =cut
 
 
+my $not_ref = sub {
+	return !Ref::Util::is_ref(shift);
+};
+
+my $valid_cb = sub {
+	my $subname = shift;
+	my ($modname) = $subname =~ m/^([\w|:]+)::\w+$/;
+	eval {
+		require $modname;
+	} or do {
+		WARN("Post uses a callback whos module cannot be found!");	
+		return 0;
+	};
+
+	no strict 'refs';
+	my $ref = eval '\&'.$subname;
+	use strict;
+	return is_coderef($ref);
+};
+
+# TODO more strict validation of strings?
+our %schema = (
+	'title' => $not_ref,
+	'callback' => $valid_cb,
+	'user_acls' => \&Ref::Util::is_arrayref,
+	'id' => $not_ref,
+	'user' => $not_ref,
+	'created' => $not_ref,
+	'tags' => \&Ref::Util::is_arrayref,
+	'form' => $not_ref,
+	'local_href' => $not_ref,
+	'data' => $not_ref,
+	'version' => $not_ref,
+	'visibility' => $not_ref,
+	'aliases' => \&Ref::Util::Is_arrayref,
+);
+
 sub add ( $self, @posts ) {
 sub add ( $self, @posts ) {
     my @to_write;
     my @to_write;
 
 
     foreach my $post (@posts) {
     foreach my $post (@posts) {
+		# Filter all the irrelevant data
+		foreach my $key (keys(%$post)) {
+			# We need to have the key in the schema, and it validate.
+			delete $post->{$key} unless List::Util::any { ($_ eq $key) && ($schema{$key}->($post->{$key})) } keys(%schema);
+		}
+
         $post->{id}      //= UUID::Tiny::create_uuid_as_string( UUID::Tiny::UUID_V1, UUID::Tiny::UUID_NS_DNS );
         $post->{id}      //= UUID::Tiny::create_uuid_as_string( UUID::Tiny::UUID_V1, UUID::Tiny::UUID_NS_DNS );
         $post->{aliases} //= [];
         $post->{aliases} //= [];
         $post->{aliases} = [ $post->{aliases} ] unless ref $post->{aliases} eq 'ARRAY';
         $post->{aliases} = [ $post->{aliases} ] unless ref $post->{aliases} eq 'ARRAY';