AmberDB
view release on metacpan or search on metacpan
t/amberdb_security_paths.t view on Meta::CPAN
#!/usr/bin/perl
# t/amberdb/amberdb_security_paths.t - Tests for path sanitization, simple mode IDs, and transact_error
use 5.016000;
use strict;
use warnings;
use Test::More;
use File::Temp qw(tempdir);
use lib 'lib';
use AmberDB;
my $tmpdir = tempdir( CLEANUP => 1 );
my $adb = AmberDB->new(
path => { dbase_dir => $tmpdir },
cfg => { simple => 0 }
);
# ---------------------------------------------------------------------------
subtest '1. Path Traversal & Table Name Sanitization' => sub {
plan tests => 10;
is( $adb->sanitize_table("uyeler/bekleyen.uyeler"), "uyeler/bekleyen.uyeler", "Allows subdirectories and dots" );
is( $adb->sanitize_table("./dosya"), "dosya", "Strips ./" );
is( $adb->sanitize_table(".\\dosya"), "dosya", "Strips .\\" );
is( $adb->sanitize_table("../secret"), "secret", "Strips ../" );
is( $adb->sanitize_table("..\\secret"), "secret", "Strips ..\\" );
is( $adb->sanitize_table("../../etc/passwd"), "etc/passwd", "Strips nested ../../" );
is( $adb->sanitize_table("uyeler/../secret"), "uyeler/secret", "Strips inner .. segment" );
is( $adb->sanitize_table("uyeler/./bekleyen"), "uyeler/bekleyen", "Strips inner . segment" );
is( $adb->sanitize_table("/.dosya"), ".dosya", "Allows hidden file style /.dosya" );
is( $adb->sanitize_table("uyeler/.gizli"), "uyeler/.gizli", "Allows hidden file style uyeler/.gizli" );
};
# ---------------------------------------------------------------------------
subtest '2. table_path resolution and subdirectory auto-creation' => sub {
plan tests => 3;
my $path1 = $adb->table_path("test_basic");
like( $path1, qr{test_basic$}, "Basic table path resolved" );
my $path2 = $adb->table_path("uyeler/bekleyen.uyeler");
like( $path2, qr{uyeler/bekleyen\.uyeler$}, "Subdirectory table path resolved" );
my $path3 = $adb->table_path("../../../escape_test");
unlike( $path3, qr{\.\.}, "Path traversal not present in resolved path" );
};
# ---------------------------------------------------------------------------
subtest '3. Simple Mode Arbitrary String ID Length' => sub {
plan tests => 4;
# Standard mode: only numeric positive integer allowed
$adb->config( simple => 0 );
$adb->table_attr( test_table => { use_simple => 0 } );
my $valid_num = $adb->id_check("test_table", "12345");
is( $valid_num, "12345", "Numeric ID accepted in standard mode" );
my $str_id = $adb->id_check("test_table", "user123_abc");
is( $str_id, "123", "Non-digits stripped in standard mode" );
# Table use_simple mode: arbitrary string ID allowed
$adb->table_attr( test_table => { use_simple => 1 } );
my $uuid = "123e4567-e89b-12d3-a456-426614174000";
my $simple_uuid = $adb->id_check("test_table", $uuid);
is( $simple_uuid, $uuid, "Long UUID accepted in table use_simple mode" );
my $email_id = $adb->id_check("test_table", 'test.user_99@example.com');
is( $email_id, 'test.user_99@example.com', "Exact email ID preserved intact in table use_simple mode" );
};
# ---------------------------------------------------------------------------
subtest '4. Transact transact_error and rollback' => sub {
plan tests => 4;
can_ok( $adb, 'transact_error' );
$adb->{_error} = [];
$adb->transact_start();
$adb->transact_error( "test_table.db", "Simulated fatal error" );
my $res = $adb->transact_end();
is( $res->{status}, 'rollback', "Transaction rolled back due to transact_error" );
ok( @{ $res->{errors} } > 0, "Errors captured in rollback response" );
is( $res->{errors}->[0]->{context}, "test_table.db", "Correct error context captured" );
};
# ---------------------------------------------------------------------------
subtest '5. _eval_plural_rule hardening' => sub {
plan tests => 4;
ok( $adb->_eval_plural_rule("n == 1", 1), "n == 1 true for 1" );
ok( !$adb->_eval_plural_rule("n == 1", 5), "n == 1 false for 5" );
ok( !$adb->_eval_plural_rule("n / 0 == 1", 2), "Division by zero returns 0 safely without dying" );
ok( !$adb->_eval_plural_rule("system('dir')", 1), "Code injection strictly blocked by whitelist" );
};
done_testing();
( run in 0.974 second using v1.01-cache-2.11-cpan-54e63673c56 )