【问题标题】:Sanitize strings to avoid special characters break javascript generated by php清理字符串以避免特殊字符破坏 php 生成的 javascript
【发布时间】:2016-04-21 06:17:26
【问题描述】:

我有一个 php 'search' 脚本,它在 MySQL 数据库中查找请求的数据并打印一个表。通过单击图标可以修改或删除该表的每一行。当您单击其中一个图标时,将调用一个显示显示的 javascript 函数。

这是一段代码:

      while ($row = mysqli_fetch_row($result)) {
            // Define $id
            $id = $row[7];

            // Sanitize output
            $user = htmlentities($row[0]);
            $name = htmlentities($row[1]);
            $surnames = htmlentities($row[2]);
            $email = htmlentities($row[3]);
            $role = htmlentities($row[4]);
            $access = htmlentities($row[5]);
            $center = htmlentities($row[6]);

            $message .= "<tr>
                    <td>" . $user . "</td>" .
                    "<td>" . $name . "</td>" .
                    "<td>" . $surnames . "</td>" .
                    "<td>" . $email . "</td>" .
                    "<td>" . $role . "</td>" .
                    "<td>" . $access . "</td>" .
                    "<td>" . $center . "</td>" .
                    "<td>" .
                        "<input type='image' src='../resources/edit.png' id='edit_" . $user . "' class='edit' onclick=edit_user(\"$user\",\"$name\",\"$surnames\",'$email','$role','$access',\"$center\",'$id') title='Editar'></button>" . 
                    "</td>" .
                    "<td>" .
                        "<input type='image' src='../resources/delete.png' id='delete_" . $user . "' class='delete' onclick=delete_user(\"$user\",'$role') title='Eliminar'></button>" . 
                    "</td>
                </tr>";
        }

这只是我生成的表格的一部分。毕竟,我用 json_encode 对表进行编码并回显它。回声由 ajax 函数捕获,该函数将其解码(JSON.parse)并将其放入 div 中。

表格已正确呈现,正常字符一切正常,但我发现如果我有引号、斜杠和其他有意义的字符,我可能会遇到一些问题。字符串在表格中正确显示,所以php没有问题,但是生成的javascript对某些字符串不起作用。

例如,如果我介绍:

</b>5'"

或:

<b>5'6"</b><br><div

作为用户,当我点击编辑或删除图标时,我在 javascript 控制台中遇到了一些错误:

未捕获的 SyntaxError:无效的正则表达式:缺少 / home.php:1 Uncaught SyntaxError: missing ) after argument list

Uncaught SyntaxError: missing ) after argument list

Uncaught SyntaxError: Unexpected token ILLEGAL

我尝试过 addlash、replace、htmlentites、htmlspecialchars 的几种组合...但我找不到合适的组合。

为了避免任何问题,正确的处理方法是什么?

谢谢。

编辑:

我已经对此进行了调查,它似乎有效:

在php中我使用这个函数:

function javascript_escape($str) {
$new_str = '';

$str_len = strlen($str);
for($i = 0; $i < $str_len; $i++) {
    $new_str .= '\\x' . dechex(ord(substr($str, $i, 1)));
}

return $new_str;
}

然后我使用类似的东西

$('<textarea />').html(user).text()

在javascript中解码字符串。

这对 XSS 攻击安全吗?

【问题讨论】:

  • 至少你需要在 Javascript onclick 代码周围加上引号,否则任何空格都会导致语法错误,并且它是无效的 HTML 没有包含引号。然后,你需要` escape any quotes. Try onclick="edit_user('$user', '$name', ....); return false"` 和$user, $name,其他变量应该是贯穿addslashes
  • 更好的做法是使用 Javascript 事件处理程序,而不是直接将 onclick= 打印到元素中。见this question and answer
  • 你可以使用 ...id='edit_" . MD5($user) . "' class=...
  • @dres010 试过了,我得到 Uncaught SyntaxError: Unexpected token ILLEGAL
  • @IarsAnders 我想我可以添加带有 id 的 eventListeners,但我也有同样的 id 问题。生成不好,双引号完成了 id,虽然我使用了 addsplashes。

标签: javascript php special-characters sanitization


【解决方案1】:

首先,创建数组的 HTML 安全 JSON 字符串,并修改您的代码以使用如下数据属性:

      while ($row = mysqli_fetch_row($result)) {
            // Define $id
            $id = $row[7];

            // Sanitize output
            $user = htmlentities($row[0]);
            $name = htmlentities($row[1]);
            $surnames = htmlentities($row[2]);
            $email = htmlentities($row[3]);
            $role = htmlentities($row[4]);
            $access = htmlentities($row[5]);
            $center = htmlentities($row[6]);

            $json_str_edit = htmlentities(json_encode(array($row[0], $row[1], $row[2], $row[3], $row[4], $row[5], $row[6], $id)));
            $json_str_delete = htmlentities(json_encode(array($row[0], $row[4])));

            $message .= "<tr>
                    <td>" . $user . "</td>" .
                    "<td>" . $name . "</td>" .
                    "<td>" . $surnames . "</td>" .
                    "<td>" . $email . "</td>" .
                    "<td>" . $role . "</td>" .
                    "<td>" . $access . "</td>" .
                    "<td>" . $center . "</td>" .
                    "<td>" .
                        "<input type=\"image\" src=\"../resources/edit.png\" id=\"edit_$user\" class=\"edit\" data-user=\"$json_str_edit\" title=\"Editar\"></button>" . 
                    "</td>" .
                    "<td>" .
                        "<input type=\"image\" src=\"../resources/delete.png\" id=\"delete_$user\" class=\"delete\" data-user=\"$json_str_delete\" title=\"Eliminar\"></button>" . 
                    "</td>
                </tr>";
        }

然后创建一个事件监听器来像这样在 JS 中捕捉相关的点击事件:

function edit_user(user, name, surnames, email, role, access, center, id) {
    // `this` will refer to the html element involved in the event

    }

function delete_user(user, role) {
    // `this` will refer to the html element involved in the event

    }

document.addEventListener('click', function(event) {
    if(event.target.hasAttribute('data-user')) {
        switch(event.target.className) {
            case 'edit':
                edit_user.apply(event.target, JSON.parse(event.target.dataset.user));
                break;
            case 'delete':
                delete_user.apply(event.target, JSON.parse(event.target.dataset.user));
                break;
            }
        }
    }, false);

或者从 addEventListener 方法中,您可以像这样简单地将这个 onclick 事件侦听器直接添加到元素中(在这种情况下,我真的不认为这很重要):

onclick="edit_user.apply(this, JSON.parse(this.dataset.user))"

仅供参考 在脚本中使用单引号以避免转义双引号字符是更常见的做法。让事情变得更干净、更标准化。

【讨论】:

  • 谢谢,但是 JSON 是不够的。我试过用引号,它们破坏了功能。
  • @vjsp90 你试过我的解决方案了吗?它绝对应该有效。如果您的引号破坏了任何内容,那只是因为您没有正确地转义它们。
  • 是的,我试过了。如果你放了一些东西'",即使我使用 addlashes 来转义字符串,它也不起作用。
  • @vjsp90 然后缩小真正的问题并解决它。您应该能够调试代码,不是吗?这个答案是针对您最初的问题的,我不应该浪费时间为您调试代码。这并不意味着复制和粘贴答案。这是为了向你展示做你想做的事情的正确方法。
  • @vjsp90 我已修改我的代码以正确转义双引号,以便能够在实际 HTML 中使用双引号。应该这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 2010-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-30
  • 2014-10-05
相关资源
最近更新 更多