在INPUT元素中设置不执行javascript的特殊字符

时间:2016-12-20 09:01:09

标签: javascript asp.net xss

我遇到的问题是我想允许在输入中使用特殊字符(以编码方式),但是要阻止XSS。当我直接设置html属性时(例如,通过使用jquery执行.html("我的值")),我似乎没有这个问题,但是当我使用元素而不关闭时会出现问题像INPUT这样的标签。

这是我的情景:

使用ajax的动态客户端Web服务请求,因此我无法使用某种内联代码来构建页面。加载基页后会发生这种情况:

    var data = {
        "key": "value"
    }
    $.ajax({
        type: "POST",
        url: "WebService.asmx/GetData",
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify(data),
        dataType: "json",
        success: function callFunction(result) {
            if (result.d != null) {
                // Building an HTML block
                var preBuiltHtml = "<table style=\"width:100%;\">" +
                    "<tr>" +
                        "<td>Entry 1:</td>" +
                        "<td><input type=\"text\" id=\"txtEntry1\" maxlength=\"100\" value=\"" + result.d.return_value + "\" style=\"width:100%;\" ></td>" +
                    "</tr>" +
                "</table>";
                $('#someDialog').html(preBuiltHtml);
            }
            else {
                showMessageDialog("Permission denied", 1);
            }
        },
        error: function () { showMessageDialog('Error!', 2); }
    });

服务器端(ASP.NET),带有字符编码以防止XSS:

[WebMethod(true)]
public SomeClass GetProjectDetails(string proj_nr)
{
    SomeClass result = new SomeClass();
    result.return_value = Encoder.HtmlEncode("<IMG SRC=\"javascript: alert('XSS');\">");
    return result;
}

在客户端,这将正确填写输入元素,但执行javascript。如果我使用jquery .val()方法来设置值,它会完全混淆元素的html。如果我使用.html()将相同的值设置为div,一切都很好,但我无法对输入元素执行此操作。

如果没有在客户端执行这种值,那么设置这种值的正确方法是什么?

提前多多感谢

编辑:还有一件事,警报框未按预期执行,因此不会显示任何消息框。但是在Chrome的开发模式下查看网络选项卡,您可以看到一个条目: enter image description here

编辑2:从Web服务检索的字符串 enter image description here

1 个答案:

答案 0 :(得分:0)

在渲染用户输入时,您应该设置值而不是内联HTML,例如:

const res = getEdges().reduce(result, edge => {
  const labels = getLabels(edge).sort();
  labels.forEach(label => result.push(`${result.length + 1}-${label}`));
  return result;
}, []);

你说“它完全搞砸了元素的html”你能更具体一点吗?

如果我直接尝试,它会按预期工作......

var preBuiltHtml = "<table style=\"width:100%;\">" +
  "<tr>" +
    "<td>Entry 1:</td>" +
    "<td><input type=\"text\" id=\"txtEntry1\" maxlength=\"100\" style=\"width:100%;\" ></td>" +
  "</tr>" +
"</table>";

var input = $('#someDialog').html(preBuiltHtml).find('#txtEntry1');
input.val(result.d.return_value);
var unescaped = '<IMG SRC="javascript: alert(\'XSS\');">';
var escaped = '&lt;IMG&#32;SRC=&quot;javascript: alert(&#39;XSS&#39;);&quot;&gt;'

// Escaped content is still escaped
var input1 = document.querySelector('#test1');
input1.value = escaped;
 
// Unescaped content is preserved
var input2 = document.querySelector('#test2');
input2.value = unescaped;

// HTML should use the escaped version
var div3 = document.querySelector('#test3');
div3.innerHTML = '<input type="text" value="' + escaped + '">'

网络标签中的错误是因为您使用了<input id=test1> <input id=test2> <div id=test3></div>,它不会执行内联JavaScript,但会尝试检索它(就像您已完成<IMG SRC一样)。