Skip to content

Commit 532d8d4

Browse files
import file validation
1 parent a9f1107 commit 532d8d4

19 files changed

+192
-194
lines changed

protected/components/CSVActiveRecorder.php

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ public function __construct(array $data, $model, $additionalParams = [])
1515
{
1616

1717
$this->model = $model;
18-
if (isset($data['filename'])) {
19-
chmod($data['filename'], 0777);
20-
}
18+
2119

2220
$this->translations = require __DIR__ . '/../../resources/locale/php/en/csv-translate.php';
2321
$this->data = $data;
@@ -45,41 +43,46 @@ public function save()
4543
$this->addError($e->getMessage());
4644
return false;
4745
}
48-
4946
}
5047

5148
private function createSQL($tableName)
5249
{
5350
$sql = "LOAD DATA LOCAL INFILE '" . $this->data['filename'] . "'" .
54-
" INTO TABLE " . $tableName .
55-
" CHARACTER SET UTF8 " .
56-
" FIELDS TERMINATED BY '" . $this->data['boundaries']['delimiter'] . "'" .
51+
" INTO TABLE " . $tableName .
52+
" CHARACTER SET UTF8 " .
53+
" FIELDS TERMINATED BY '" . $this->data['boundaries']['delimiter'] . "'" .
5754
" LINES TERMINATED BY '\\r\\n'" .
5855
" IGNORE 1 LINES";
5956

60-
$sql .= " (" . implode(",", array_map(
61-
function ($v) {
62-
return '@' . $v;
63-
},
64-
array_keys($this->data['columns'])
65-
)
57+
$sql .= " (" . implode(
58+
",",
59+
array_map(
60+
function ($v) {
61+
return '@' . $v;
62+
},
63+
array_keys($this->data['columns'])
64+
)
6665
) . ")";
6766

6867
$columns = $this->data['columns'];
69-
$sql .= " SET " . implode(" ", array_map(
70-
function ($v) use ($columns) {
71-
return $columns[$v] . " = @" . $v . ", ";
72-
},
73-
array_keys($this->data["columns"])
74-
)
75-
);
76-
if ($this->data["additionalParams"] > 0) {
77-
$sql .= " " . implode(" ", array_map(
78-
function ($v) {
79-
return $v['key'] . '= "' . $v['value'] . '",';
68+
$sql .= " SET " . implode(
69+
" ",
70+
array_map(
71+
function ($v) use ($columns) {
72+
return $columns[$v] . " = @" . $v . ", ";
8073
},
81-
$this->additionalParams
74+
array_keys($this->data["columns"])
8275
)
76+
);
77+
if ($this->data["additionalParams"] > 0) {
78+
$sql .= " " . implode(
79+
" ",
80+
array_map(
81+
function ($v) {
82+
return $v['key'] . '= "' . $v['value'] . '",';
83+
},
84+
$this->additionalParams
85+
)
8386
);
8487
}
8588

@@ -101,10 +104,9 @@ public function translateColumns()
101104
$foundTranslation = true;
102105
}
103106
}
104-
if ( ! $foundTranslation) {
107+
if (! $foundTranslation) {
105108
$resultColumns[$csvColumn] = $csvColumn;
106109
}
107-
108110
}
109111
return $resultColumns;
110112
}

protected/components/Util.php

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -296,20 +296,81 @@ public static function calculation_price($buyrate, $duration, $initblock, $incre
296296
return $ratecost;
297297
}
298298

299-
public static function valid_extension($filename, $allowed = [])
299+
/**
300+
* Validate file extension and real MIME type.
301+
*
302+
* @param string $tmpPath Temporary path (ex: $_FILES['file']['tmp_name'])
303+
* @param string $originalName Original filename (ex: $_FILES['file']['name'])
304+
* @param array $allowed Allowed extensions (ex: ['png','jpg','pdf'])
305+
* @return array ['ext' => 'png', 'mime' => 'image/png']
306+
*/
307+
public static function validExtension($tmpPath, $originalName, array $allowed = [])
300308
{
301-
$ext = strtolower(CFileHelper::getExtension($filename));
309+
// Extension -> MIME map (only safe/common formats)
310+
$mimeMap = [
311+
'jpg' => ['image/jpeg', 'image/pjpeg'],
312+
'jpeg' => ['image/jpeg', 'image/pjpeg'],
313+
'png' => ['image/png'],
314+
'gif' => ['image/gif'],
315+
'txt' => ['text/plain'],
316+
'csv' => ['text/csv', 'application/vnd.ms-excel', 'text/plain'],
317+
'wav' => ['audio/wav', 'audio/x-wav', 'audio/wave'],
318+
'gsm' => ['audio/x-gsm'],
319+
];
320+
321+
// Get extension from original filename
322+
$ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));
323+
324+
// Block dangerous extensions explicitly
325+
$dangerous = ['php', 'phtml', 'phar', 'php5', 'php7', 'php8', 'cgi', 'pl', 'exe', 'sh', 'bash'];
326+
if (in_array($ext, $dangerous, true)) {
327+
self::jsonError();
328+
}
302329

303-
if (! in_array($ext, $allowed)) {
304-
echo json_encode([
305-
'success' => false,
306-
'errors' => 'File error',
307-
]);
308-
exit;
330+
// Check if extension is in the allowed list
331+
if (!in_array($ext, $allowed, true)) {
332+
self::jsonError();
333+
}
334+
335+
// Check if we have a MIME map for this extension
336+
if (!isset($mimeMap[$ext])) {
337+
self::jsonError();
338+
}
339+
340+
// Detect real MIME type
341+
$finfo = new finfo(FILEINFO_MIME_TYPE);
342+
$mime = $finfo->file($tmpPath) ?: '';
343+
344+
// Block empty or generic MIME
345+
if ($mime === '' || $mime === 'application/octet-stream') {
346+
self::jsonError();
347+
}
348+
349+
// Check if real MIME matches the allowed ones for this extension
350+
if (!in_array($mime, $mimeMap[$ext], true)) {
351+
self::jsonError();
352+
}
353+
354+
// Extra check for images
355+
if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif'], true)) {
356+
$img = @getimagesize($tmpPath);
357+
if ($img === false) {
358+
self::jsonError();
359+
}
309360
}
310361

311362
return $ext;
312363
}
364+
365+
private static function jsonError()
366+
{
367+
echo json_encode([
368+
'success' => false,
369+
'errors' => 'File error',
370+
]);
371+
Yii::app()->end();
372+
}
373+
313374
public static function isJson($string)
314375
{
315376
if (!is_string($string)) {

protected/controllers/AuthenticationController.php

Lines changed: 26 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
/**
34
* =======================================
45
* ###################################
@@ -52,7 +53,8 @@ public function actionLogin()
5253
[
5354
'condition' => $condition,
5455
'params' => [':user' => $user, ':pass' => $password],
55-
]);
56+
]
57+
);
5658

5759
$loginkey = isset($_POST['loginkey']) ? $_POST['loginkey'] : false;
5860

@@ -65,7 +67,7 @@ public function actionLogin()
6567
$mail->send();
6668
}
6769

68-
if ( ! isset($modelUser->id)) {
70+
if (! isset($modelUser->id)) {
6971
Yii::app()->session['logged'] = false;
7072
echo json_encode([
7173
'success' => false,
@@ -145,20 +147,21 @@ public function actionLogin()
145147
}
146148
Yii::app()->session['googleAuthenticatorKey'] = $ga->getQRCodeGoogleUrl('VoIP-' . $modelUser->username . '-' . $modelUser->id, $secret);
147149

148-
$modelLogUsers = LogUsers::model()->count('id_user = :key AND ip = :key1 AND description = :key2 AND date > :key3',
150+
$modelLogUsers = LogUsers::model()->count(
151+
'id_user = :key AND ip = :key1 AND description = :key2 AND date > :key3',
149152
[
150153
':key' => $modelUser->id,
151154
':key1' => $_SERVER['REMOTE_ADDR'],
152155
':key2' => 'Username Login on the panel - User ' . $modelUser->username,
153156
':key3' => date('Y-m-d'),
154-
]);
157+
]
158+
);
155159
if ($modelLogUsers > 0) {
156160
Yii::app()->session['checkGoogleAuthenticator'] = false;
157161
} else {
158162
Yii::app()->session['checkGoogleAuthenticator'] = true;
159163
}
160164
}
161-
162165
} else {
163166
Yii::app()->session['showGoogleCode'] = false;
164167
Yii::app()->session['newGoogleAuthenticator'] = false;
@@ -177,7 +180,6 @@ public function actionLogin()
177180
'success' => Yii::app()->session['username'],
178181
'msg' => Yii::app()->session['name_user'],
179182
]);
180-
181183
}
182184

183185
private function mountMenu()
@@ -229,8 +231,10 @@ public function actionCheck()
229231
if (Yii::app()->session['logged']) {
230232

231233
$this->mountMenu();
232-
$modelGroupUserGroup = GroupUserGroup::model()->count('id_group_user = :key',
233-
[':key' => Yii::app()->session['id_group']]);
234+
$modelGroupUserGroup = GroupUserGroup::model()->count(
235+
'id_group_user = :key',
236+
[':key' => Yii::app()->session['id_group']]
237+
);
234238

235239
$modelGroupUser = GroupUser::model()->findByPk(Yii::app()->session['id_group']);
236240

@@ -410,7 +414,6 @@ public function actionGoogleAuthenticator()
410414
'success' => $sussess,
411415
'msg' => Yii::app()->session['name_user'],
412416
]);
413-
414417
}
415418

416419
public function actionChangePassword()
@@ -422,18 +425,18 @@ public function actionChangePassword()
422425
$isClient = Yii::app()->session['isClient'];
423426
$errors = '';
424427

425-
$modelUser = User::model()->find("id LIKE :id_user AND password LIKE :currentPassword",
428+
$modelUser = User::model()->find(
429+
"id LIKE :id_user AND password LIKE :currentPassword",
426430
[
427431
":id_user" => $id_user,
428432
":currentPassword" => $currentPassword,
429-
]);
433+
]
434+
);
430435

431436
if (isset($modelUser->id)) {
432-
try
433-
{
437+
try {
434438
$modelUser->password = $newPassword;
435439
$passwordChanged = $modelUser->save();
436-
437440
} catch (Exception $e) {
438441
$errors = $this->getErrorMySql($e);
439442
}
@@ -460,7 +463,7 @@ public function actionImportLogo()
460463
} else {
461464
$uploadfile = $uploaddir . 'logo_custom.png';
462465
}
463-
$typefile = Util::valid_extension($_FILES["logo"]["name"], ['png']);
466+
Util::validExtension($_FILES['logo']['tmp_name'], $_FILES["logo"]["name"], ['png']);
464467

465468
move_uploaded_file($_FILES["logo"]["tmp_name"], $uploadfile);
466469
}
@@ -476,7 +479,7 @@ public function actionImportWallpapers()
476479
if (isset($_FILES['wallpaper']['tmp_name']) && strlen($_FILES['wallpaper']['tmp_name']) > 3) {
477480

478481
$uploaddir = "resources/images/wallpapers/";
479-
$typefile = Util::valid_extension($_FILES["wallpaper"]["name"], ['jpg']);
482+
Util::validExtension($_FILES['wallpaper']['tmp_name'], $_FILES["wallpaper"]["name"], ['jpg']);
480483

481484
$uploadfile = $uploaddir . 'Customization.jpg';
482485
move_uploaded_file($_FILES["wallpaper"]["tmp_name"], $uploadfile);
@@ -495,7 +498,6 @@ public function actionImportWallpapers()
495498
'success' => $success,
496499
'msg' => $msg,
497500
]);
498-
499501
}
500502

501503
public function actionImportLoginBackground()
@@ -505,7 +507,7 @@ public function actionImportLoginBackground()
505507

506508
if (isset($_FILES['loginbackground']['tmp_name']) && strlen($_FILES['loginbackground']['tmp_name']) > 3) {
507509

508-
$typefile = Util::valid_extension($_FILES["loginbackground"]["name"], ['jpg']);
510+
Util::validExtension($_FILES['loginbackground']['tmp_name'], $_FILES["loginbackground"]["name"], ['jpg']);
509511

510512
$uploadfile = 'resources/images/lock-screen-background.jpg';
511513
try {
@@ -514,17 +516,7 @@ public function actionImportLoginBackground()
514516
$msg = 'Refresh the system to see the new wallpaper';
515517
} catch (Exception $e) {
516518
}
517-
518519
}
519-
520-
$colors = ['black', 'blue', 'gray', 'orange', 'purple', 'red', 'yellow', 'green'];
521-
foreach ($colors as $key => $color) {
522-
$types = ['crisp', 'neptune', 'triton'];
523-
foreach ($types as $key => $type) {
524-
copy("/var/www/html/mbilling/resources/images/lock-screen-background.jpg", "/var/www/html/mbilling/$color-$type/resources/images/lock-screen-background.jpg");
525-
}
526-
}
527-
528520
echo json_encode([
529521
'success' => $success,
530522
'msg' => $msg,
@@ -569,7 +561,6 @@ public function actionForgetPassword()
569561
'success' => $success,
570562
'msg' => $msg,
571563
]);
572-
573564
}
574565

575566
public function actionCancelCreditNotification()
@@ -648,11 +639,12 @@ public function checkCaptcha()
648639
]
649640
);
650641

651-
$opts = ['http' => [
652-
'method' => 'POST',
653-
'header' => 'Content-type: application/x-www-form-urlencoded',
654-
'content' => $post_data,
655-
],
642+
$opts = [
643+
'http' => [
644+
'method' => 'POST',
645+
'header' => 'Content-type: application/x-www-form-urlencoded',
646+
'content' => $post_data,
647+
],
656648
];
657649

658650
$context = stream_context_create($opts);

protected/controllers/CallArchiveController.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
/**
34
* Acoes do modulo "Call".
45
*
@@ -83,7 +84,7 @@ public function init()
8384

8485
parent::init();
8586

86-
if ( ! Yii::app()->session['isAdmin']) {
87+
if (! Yii::app()->session['isAdmin']) {
8788
$this->extraValues = [
8889
'idUser' => 'username',
8990
'idPlan' => 'name',
@@ -202,9 +203,7 @@ public function actionDownloadRecord()
202203

203204
$folder = $this->magnusFilesDirectory . 'monitor';
204205

205-
if ( ! file_exists($folder)) {
206-
mkdir($folder, 0777, true);
207-
}
206+
208207
array_map('unlink', glob("$folder/*"));
209208

210209
if (count($modelCdr)) {
@@ -282,5 +281,4 @@ public function actionGetTotal()
282281
$modelCall->totalCall = number_format($modelCall->sumsessionbill - $modelCall->sumbuycost, 4);
283282
echo json_encode($modelCall);
284283
}
285-
286284
}

0 commit comments

Comments
 (0)