暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL的函数和运算符 - XML 函数(3)

数据库杂货铺 2021-07-19
700
错误处理。对于 ExtractValue() UpdateXML(),使用的 XPath 定位器必须要有效,要搜索的 XML 必须包含正确嵌套和关闭的元素。如果定位器无效,会产生错误:
 
    mysql> SELECT ExtractValue('<a>c</a><b/>', '/&a');
    ERROR 1105 (HY000): XPATH syntax error: '&a'
     
    如果 xml_frag 包含不正确嵌套和关闭的元素,则返回 NULL 并生成警告,如下例所示:
     
      mysql> SELECT ExtractValue('<a>c</a><b', '//a');
      +-----------------------------------+
      | ExtractValue('<a>c</a><b', '//a') |
      +-----------------------------------+
      | NULL |
      +-----------------------------------+
      1 row in set, 1 warning (0.00 sec)

      mysql> SHOW WARNINGS\G
      *************************** 1. row ***************************
      Level: Warning
      Code: 1525
      Message: Incorrect XML value: 'parse error at line 1 pos 11:
      END-OF-INPUT unexpected ('>' wanted)'
      1 row in set (0.00 sec)

      mysql> SELECT ExtractValue('<a>c</a><b/>', '//a');
      +-------------------------------------+
      | ExtractValue('<a>c</a><b/>', '//a') |
      +-------------------------------------+
      | c |
      +-------------------------------------+
      1 row in set (0.00 sec)
       
      重要
       
      对于作为 UpdateXML() 的第三个参数的替换 XML,没有检查它是否仅由正确嵌套和关闭的元素组成。
       
      XPath 注入。当恶意代码被引入系统以获得对权限和数据的未授权访问时,就会发生代码注入。它基于开发人员对用户输入数据的类型和内容所做的假设。XPath 在这方面也不例外。
       
      常见的情况是,应用程序通过匹配 XML 文件中找到的登录名和密码组合来处理授权,使用如下 XPath 表达式
       
        //user[login/text()='neapolitan' and password/text()='1c3cr34m']/attribute::id
         
        这个 XPath 等价于如下 SQL 语句:
         
          SELECT id FROM users WHERE login='neapolitan' AND password='1c3cr34m';
           
          使用 XPath PHP 应用程序可能会这样处理登录过程:
           
            <?php

            $file = "users.xml";

            $login = $POST["login"];
            $password = $POST["password"];

            $xpath = "//user[login/text()=$login and password/text()=$password]/attribute::id";

            if( file_exists($file) )
            {
            $xml = simplexml_load_file($file);

            if($result = $xml->xpath($xpath))
            echo "You are now logged in as user $result[0].";
            else
            echo "Invalid login name or password.";
            }
            else
            exit("Failed to open $file.");

            ?>
             
            对输入没有执行任何检查。这意味着恶意用户可以进行“短路”测试,登录名和密码都输入 ' or 1=1,导致 $xpath 按如下所示计算:
             
              //user[login/text()='' or 1=1 and password/text()='' or 1=1]/attribute::id
               
              因为方括号内的表达式总是为 true,它匹配 XML 文档中每个用户元素的 id 属性:
               
                //user/attribute::id
                 
                避免这种攻击的一种方法是在 $xpath 的定义中引用要插入的变量名,强制从 Web 表单传递的值转换为字符串:
                 
                  $xpath = "//user[login/text()='$login' and password/text()='$password']/attribute::id";
                   
                  这与防止 SQL 注入攻击通常推荐的策略相同。一般来说,防止 XPath 注入攻击和防止 SQL 注入应该遵循的实践是一样的:
                   
                  ● 不要在应用程序中接受来自用户的未经测试的数据。
                   
                  ● 检查所有用户提交的数据类型,拒绝或转换错误类型的数据
                   
                  ● 测试超出范围的数值数据,截断、舍入或拒绝超出范围的值。测试字符串是否包含非法字符,或者去掉它们,或者拒绝包含它们的输入。
                   
                  ● 不要输出显式的错误消息,这些错误消息可能会为未授权的用户提供可能被用来危害系统的线索,可以将这些日志记录到文件或数据库表中。
                   
                  正如 SQL 注入攻击可以用来获取关于数据库模式的信息一样,XPath 注入也可以用来遍历 XML 文件来揭示它们的结构,正如 Amit Klein 在其论文 Blind XPath Injection(PDF文件,46KB)中讨论的那样。
                   
                  检查发送回客户端的输出也很重要。考虑一下当我们使用 MySQL ExtractValue() 函数时会发生什么:
                   
                    mysql> SELECT ExtractValue(
                    -> LOAD_FILE('users.xml'),
                    -> '//user[login/text()="" or 1=1 and password/text()="" or 1=1]/attribute::id'
                    -> ) AS id;
                    +-------------------------------+
                    | id |
                    +-------------------------------+
                    | 00327 13579 02403 42354 28570 |
                    +-------------------------------+
                    1 row in set (0.01 sec)
                     
                    因为 ExtractValue() 将多个匹配作为一个空格分隔的字符串返回,所以这种注入攻击将 users.xml 中包含的每个有效 ID 作为一行输出提供给用户。作为额外的保护措施,还应该在将输出返回给用户之前测试输出。这里有一个简单的例子:
                     
                      mysql> SELECT @id = ExtractValue(
                      -> LOAD_FILE('users.xml'),
                      -> '//user[login/text()="" or 1=1 and password/text()="" or 1=1]/attribute::id'
                      -> );
                      Query OK, 0 rows affected (0.00 sec)

                      mysql> SELECT IF(
                      -> INSTR(@id, ' ') = 0,
                      -> @id,
                      -> 'Unable to retrieve user ID')
                      -> AS singleID;
                      +----------------------------+
                      | singleID |
                      +----------------------------+
                      | Unable to retrieve user ID |
                      +----------------------------+
                      1 row in set (0.00 sec)
                       
                      通常,将数据安全地返回给用户的指导原则与接受用户输入的指导原则相同。这些可以概括为:
                       
                      ● 总是测试输出数据的类型和允许的值。
                       
                      ● 永远不要允许未经授权的用户查看错误消息,这些错误消息可能使该应用程序被利用。
                       
                       
                       
                       
                      官方网址:
                      https://dev.mysql.com/doc/refman/8.0/en/xml-functions.html
                      文章转载自数据库杂货铺,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                      评论