Skip to content

Commit d13aaf3

Browse files
CRITICAL SECURITY FIXES - Buat FileUploadService (#1437)
Co-authored-by: Abah Roland <59082428+vickyrolanda@users.noreply.github.com>
1 parent 2373e96 commit d13aaf3

1 file changed

Lines changed: 114 additions & 0 deletions

File tree

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
3+
namespace Tests\Unit;
4+
5+
use Tests\TestCase;
6+
use App\Rules\SecureFileUpload;
7+
use Illuminate\Http\UploadedFile;
8+
9+
class SecureFileUploadTest extends TestCase
10+
{
11+
/** @test */
12+
public function test_validasi_pass_untuk_file_valid()
13+
{
14+
$rule = new SecureFileUpload(['image/jpeg'], 2048);
15+
$file = UploadedFile::fake()->image('test.jpg', 100, 100);
16+
17+
$hasFailed = false;
18+
$rule->validate('file', $file, function($message) use (&$hasFailed) {
19+
$hasFailed = true;
20+
});
21+
22+
$this->assertFalse($hasFailed, 'File valid seharusnya lolos validasi');
23+
}
24+
25+
/** @test */
26+
public function test_tolak_ekstensi_berbahaya_php()
27+
{
28+
$rule = new SecureFileUpload();
29+
$file = UploadedFile::fake()->create('malicious.php', 100);
30+
31+
$failMessage = null;
32+
$rule->validate('file', $file, function($message) use (&$failMessage) {
33+
$failMessage = $message;
34+
});
35+
36+
$this->assertNotNull($failMessage);
37+
$this->assertStringContainsString('forbidden file extension', $failMessage);
38+
}
39+
40+
/** @test */
41+
public function test_tolak_ekstensi_berbahaya_exe()
42+
{
43+
$rule = new SecureFileUpload();
44+
$file = UploadedFile::fake()->create('virus.exe', 100);
45+
46+
$failMessage = null;
47+
$rule->validate('file', $file, function($message) use (&$failMessage) {
48+
$failMessage = $message;
49+
});
50+
51+
$this->assertStringContainsString('forbidden file extension', $failMessage);
52+
}
53+
54+
/** @test */
55+
public function test_tolak_mime_type_tidak_sesuai()
56+
{
57+
$rule = new SecureFileUpload(['image/jpeg'], 2048);
58+
$file = UploadedFile::fake()->create('document.pdf', 100);
59+
60+
$failMessage = null;
61+
$rule->validate('file', $file, function($message) use (&$failMessage) {
62+
$failMessage = $message;
63+
});
64+
65+
$this->assertNotNull($failMessage);
66+
$this->assertStringContainsString('must be one of', $failMessage);
67+
}
68+
69+
/** @test */
70+
public function test_tolak_file_terlalu_besar()
71+
{
72+
$rule = new SecureFileUpload(['image/jpeg'], 100); // Max 100KB
73+
$file = UploadedFile::fake()->create('large.jpg', 500); // 500KB
74+
75+
$failMessage = null;
76+
$rule->validate('file', $file, function($message) use (&$failMessage) {
77+
$failMessage = $message;
78+
});
79+
80+
$this->assertNotNull($failMessage);
81+
$this->assertStringContainsString('may not be greater than', $failMessage);
82+
}
83+
84+
/** @test */
85+
public function test_tolak_bukan_uploaded_file()
86+
{
87+
$rule = new SecureFileUpload();
88+
89+
$failMessage = null;
90+
$rule->validate('file', 'not-a-file', function($message) use (&$failMessage) {
91+
$failMessage = $message;
92+
});
93+
94+
$this->assertStringContainsString('must be a valid file', $failMessage);
95+
}
96+
97+
/** @test */
98+
public function test_semua_ekstensi_berbahaya_ditolak()
99+
{
100+
$dangerousExtensions = ['php', 'phtml', 'php3', 'php4', 'php5', 'exe', 'bat', 'sh'];
101+
$rule = new SecureFileUpload();
102+
103+
foreach ($dangerousExtensions as $ext) {
104+
$file = UploadedFile::fake()->create("malicious.{$ext}", 100);
105+
106+
$failMessage = null;
107+
$rule->validate('file', $file, function($message) use (&$failMessage) {
108+
$failMessage = $message;
109+
});
110+
111+
$this->assertNotNull($failMessage, "Extension .{$ext} should be rejected");
112+
}
113+
}
114+
}

0 commit comments

Comments
 (0)