1

问题

是否有任何其他不安全的变量类型在不转义的情况下打印到 HTML 页面或 URL?使用自定义 toString 方法忽略对象)。

背景

我正在编写一个内部库来神奇地清理任何东西(简单的字符串,整数,浮点数等,数组,嵌套数组,对象,......)给定数据的目的地(HTML页面或URL)。

对于字符串,很明显我必须为某些字符串应用htmlspecialchars和/或urlencode

如果可能的话,我想保留变量的类型,所以如果可能的话,我不想转换整数、浮点数等。

示例代码

这是我的类的一部分的当前状态(请注意,下面的代码还没有考虑对象函数和属性!)

class HogwartsExpress {
    private static $URL = 0;
    private static $HTML = 1;

    // ...

    private static function escape_array($arr, $method){
        $escaped_arr = array();
        foreach ($arr as $k=>$v){
            $safe_k = self::escape_non_array($k, $method);
            $escaped_arr[$safe_k] = is_array($v) ? self::escape_array($v, $method): self::escape_non_array($v, $method);
        }
        return $escaped_arr;
    }

    private static function escape_non_array($val, $method){
        if (is_string($val)){
            switch ($method){
                case self::$URL:  return urlencode($val);
                case self::$HTML: return htmlspecialchars($val);
            }
        }
        else {
            return $val;
        }
    }
}
4

1 回答 1

0

似乎没有人有这方面的经验,或者我使用的搜索词不正确,所以我决定做一些研究。

是的,在少数情况下。

清理输出变量时要考虑的情况:

  • 嵌套数组元素
  • 对象函数和属性
  • 资源(在 URL 中不安全)

某些上下文的安全字符

网址(网址代码)

返回一个字符串,其中包含除 -_ 之外的所有非字母数字字符。已被替换...

安全字符:0-9 AZ az-_。

HTML (htmlspecialchars)

执行的翻译是:

  • '&'(和号)变为 '&'
  • 当 ENT_NOQUOTES 未设置时,'"'(双引号)变为 '"'。
  • 仅当设置了 ENT_QUOTES 时,“'”(单引号)才变为 '''(或 ')。
  • '<' (小于)变为 '<'
  • '>' (大于)变成 '>'

不安全字符:&" ' < >

非字符串变量类型

布尔值

// boolean (TRUE|FALSE)
echo TRUE;  //1
echo FALSE; //

可能的字符:1

整数

// decimal non-zero /[+-]?[1-9][0-9]*/
echo 1;       //1
echo 83;      //83
echo -7;      //-7
echo +30;     //30

// decimal zero     /[+-]0/
echo 0;       //0
echo +0;      //0
echo -0;      //0

// hexadecimal      /[+-]?0[xX][0-9a-fA-F]+/
echo 0x0;     //0
echo -0x0;    //0
echo 0x0A;    //10
echo -0X13;   //-19
echo +0x22;   //34

// octal            /[+-]?0[0-7]+/
echo 00;      //0
echo -00;     //0
echo +00;     //0
echo 07;      //7
echo 09;      //0
echo -02;     //-2
echo 020;     //16
echo +015;    //13

// binary           /[+-]?0b[01]/
echo 0b0;     //0
echo +0b0;    //0
echo -0b0;    //0
echo 0b111;   //7
echo -0b101;  //-5
echo +0b1101; //13

可能的字符:0-9 -

浮点数

// Float /[+-]?({REQ}|(({OPT}\.{REQ})|({REQ}\.{OPT})))[eE][+-]?{REQ}/
// OPT   /[0-9]*/
// REQ   /[0-9]+/
echo .53;   //0.53
echo 42;    //42
echo 64.;   //64
echo 25.11; //25.11
echo -5.2;  //-5.2
echo +8.8;  //8.8
echo -3.2E1 //-32
echo +2.e-2 //0.02

可能的字符:0-9 - 。

大批

echo array('a' => 3.2, 'b' => 5); //Array
$foo = array('bar' => '<');
echo $foo['bar'];                 //<

主输出:数组

内部输出:嵌套元素(需要检查每个嵌套元素 - 请参阅问题源代码。)

目的

class Foo {}
echo new Foo(); //{error}

class Bird {
    function __construct() { $this->beak_len = 3.5; echo 'hoot'; }
    function __toString(){ return 'hedwig'; }
    function tweet(){ echo 'HOOT'; }
}
$owl = new Bird();   //hoot
echo $owl;           //hedwig
$owl->tweet();       //HOOT
echo $owl->beak_len; //3.5

输出源:构造函数、__toString、其他函数、属性(每个都必须检查)

资源

似乎不太可能必须打印资源,但为了完整起见,此处提供了一些信息。

资源类型列表

$doc = xml_parser_create();
echo $doc;                  //Resource id #4
$tmp = tmpfile();
echo $tmp;                  //Resource id #4

输出:资源 ID #[0-9](# 在 URL 中不安全)

无效的

// NULL
echo NULL; // {null}

输出

于 2013-09-01T22:01:21.460 回答