前言

今天在先知论坛看帖子发现了一个网站php-security-calendar-2017

这个网站是一个PHP代码审计的网站,讲到的是PHP中一些函数的用法和注意。这里简单的记录下。

Day 1 - Wish List

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Challenge {
const UPLOAD_DIRECTORY = './solutions/';
private $file;
private $whitelist;

public function __construct($file) {
$this->file = $file;
$this->whitelist = range(1, 24);
}

public function __destruct() {
if (in_array($this->file['name'], $this->whitelist)) {
move_uploaded_file(
$this->file['tmp_name'],
self::UPLOAD_DIRECTORY . $this->file['name']
);
}
}
}

$challenge = new Challenge($_FILES['solution']);

这个题目说的是in_array()函数的问题

查看in_array()函数的定义

in_array :(PHP 4, PHP 5, PHP 7)

功能 :检查数组中是否存在某个值

定义 : bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )

在 $haystack 中搜索 $needle ,

如果第三个参数 $strict 的值为 TRUE ,则 in_array() 函数会进行强检查,

检查 $needle 的类型是否和 $haystack 中的相同。

如果找到 $haystack ,则返回 TRUE,否则返回 FALSE。

在这个题目中用in_array()来检查文件名是为range(1,24)生成的数字。

但是在定义中的第三个参数没有设置为TRUE,所以这种检查是不严格的。

例如1a会被强制转换为1进行比较,也就有1a=1绕过检查。

在先知的帖子下面关于这个函数有一端代码关于in_array

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php

$array = array(
'egg' => true,
'cheese' => false,
'hair' => 765,
'goblins' => null,
'ogres' => 'no ogres allowed in this array'
);

// Loose checking -- return values are in comments

// First three make sense, last four do not

var_dump(in_array(null, $array)); // true
var_dump(in_array(false, $array)); // true
var_dump(in_array(765, $array)); // true
var_dump(in_array(763, $array)); // true
var_dump(in_array('egg', $array)); // true
var_dump(in_array('hhh', $array)); // true
var_dump(in_array(array(), $array)); // true

// Strict checking
var_dump(in_array(null, $array, true)); // true
var_dump(in_array(false, $array, true)); // true
var_dump(in_array(765, $array, true)); // true
var_dump(in_array(763, $array, true)); // false
var_dump(in_array('egg', $array, true)); // false
var_dump(in_array('hhh', $array, true)); // false
var_dump(in_array(array(), $array, true)); // false

?>

所以在使用in_array函数时需要设置第三个参数进行严格的比较即对数据类型也进行比较。