在将用户输入添加到DOM中之前,将其消除 [英] Sanitizing user input before adding it to the DOM in Javascript

查看:122
本文介绍了在将用户输入添加到DOM中之前,将其消除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我在空闲时间工作的聊天应用程序编写JS,而且我需要根据用户提交的数据改变HTML标识符。这通常是一些概念上摇摇欲坠的东西,我甚至不会尝试,但是这次我看不到自己有很多选择。那么我需要做的就是转义HTML代码,以确保不允许XSS或破解HTML。



这里是代码:

  var user_id = escape(id)
var txt ='< div class =chut>'+
'< div class =logid =chut _'+ user_id +'>< / div>'+
'< textarea id =chut _'+ user_id +'_ msg>< / textarea>'+
'< label for =chut _'+ user_id +'_ to> To:< / label>'+
'< input type =textid =chut_ '+ user_id +'_ tovalue ='+ user_id +'readonly =readonly/>'+
'< input type =submitid =chut _'+ user_id +'_ sendvalue =Message />'+
'< / div>';

逃避什么是最好的方法 id 以避免上述任何类型的问题?正如你所看到的,现在我正在使用内置的 escape()函数,但我不知道这应该比其他的多么好备择方案。我主要用于在输入文本节点之前对输入进行消毒,而不是id本身。

解决方案

使用 escape()。这与HTML编码无关。它更像是URL编码,但是甚至不正确。这是一个奇怪的非标准编码仅在JavaScript中可用。



如果你想要一个HTML编码器,你必须自己写,因为JavaScript不给你一个。例如:

  function encodeHTML(s){
return s.replace(/& / g,'& ;);替换(/< / g,'& lt;'')替换(// g,'& quot;');
}

然而,这足以将您的 user_id 放在像$ $ c>输入值,这对于 id 是不够的,因为ID只能使用有限的字符选择(而不在其中,所以 escape()甚至 encodeURIComponent()没有好的。)



您可以创建自己的编码方案,将任何字符放在ID中,例如:

  function encodeID(s){
if(s ==='')return'_';
return s.replace(/ [^ a-zA -Z0-9 .-] / g,function(match){
return'_'+ match [0] .charCodeAt(0).toString(16)+'_';
});
}

但是如果相同的 USER_ID 发生两次,说实话,扔在HTML字符串的整个事情通常是一个坏主意。使用DOM方法,并保留对每个元素的JavaScript引用,所以您不必继续调用 getElementById ,或担心如何将任意字符串插入到ID中。 p>

例如:

  function addChut(user_id){
var log = document.createElement('div');
log.className ='log';
var textarea = document.createElement('textarea');
var input = document.createElement('input');
input.value = user_id;
input.readonly = True;
var button = document.createElement('input');
button.type ='button';
button.value ='Message';

var chut = document.createElement('div');
chut.className ='chut';
chut.appendChild(log);
chut.appendChild(textarea);
chut.appendChild(input);
chut.appendChild(button);
document.getElementById('chuts')。appendChild(chut);

button.onclick = function(){
alert('Send'+ textarea.value +'to'+ user_id);
};

return chut;
}

您还可以使用方便功能或JS框架来缩短长度的创建集追加调用。



ETA:


我''现在使用jQuery作为框架


确定,然后考虑jQuery 1.4创建快捷方式,例如:

  var log = $('< div>',{className:'log'}); 
var input = $('< input>',{readOnly:true,val:user_id});
...




现在我遇到的问题是我使用JSONP将元素和事件添加到页面,因此在显示消息之前,我不知道这些元素是否已经存在。


您可以在JavaScript中将元素节点(或包装对象)的 user_id 查找,以将该信息保存在DOM本身中,哪些字符可以 id 被限制。

  var chut_lookup = {}; 
...

function getChut(user_id){
var key ='_map _'+ user_id;
if(key in chut_lookup)
return chut_lookup [key];
return chut_lookup [key] = addChut(user_id);
}

_map _ 前缀是因为JavaScript对象不能用作任意字符串的映射,空字符串和IE中的一些 Object 成员名称,混淆它。)


I'm writing the JS for a chat application I'm working on in my free time, and I need to have HTML identifiers that change according to user submitted data. This is usually something conceptually shaky enough that I would not even attempt it, but I don't see myself having much of a choice this time. What I need to do then is to escape the HTML id to make sure it won't allow for XSS or breaking HTML.

Here's the code:

var user_id = escape(id)
var txt = '<div class="chut">'+
            '<div class="log" id="chut_'+user_id+'"></div>'+
            '<textarea id="chut_'+user_id+'_msg"></textarea>'+
            '<label for="chut_'+user_id+'_to">To:</label>'+
            '<input type="text" id="chut_'+user_id+'_to" value='+user_id+' readonly="readonly" />'+
            '<input type="submit" id="chut_'+user_id+'_send" value="Message"/>'+
          '</div>';

What would be the best way to escape id to avoid any kind of problem mentioned above? As you can see, right now I'm using the built-in escape() function, but I'm not sure of how good this is supposed to be compared to other alternatives. I'm mostly used to sanitizing input before it goes in a text node, not an id itself.

解决方案

Never use escape(). It's nothing to do with HTML-encoding. It's more like URL-encoding, but it's not even properly that. It's a bizarre non-standard encoding available only in JavaScript.

If you want an HTML encoder, you'll have to write it yourself as JavaScript doesn't give you one. For example:

function encodeHTML(s) {
    return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;');
}

However whilst this is enough to put your user_id in places like the input value, it's not enough for id because IDs can only use a limited selection of characters. (And % isn't among them, so escape() or even encodeURIComponent() is no good.)

You could invent your own encoding scheme to put any characters in an ID, for example:

function encodeID(s) {
    if (s==='') return '_';
    return s.replace(/[^a-zA-Z0-9.-]/g, function(match) {
        return '_'+match[0].charCodeAt(0).toString(16)+'_';
    });
}

But you've still got a problem if the same user_id occurs twice. And to be honest, the whole thing with throwing around HTML strings is usually a bad idea. Use DOM methods instead, and retain JavaScript references to each element, so you don't have to keep calling getElementById, or worrying about how arbitrary strings are inserted into IDs.

eg.:

function addChut(user_id) {
    var log= document.createElement('div');
    log.className= 'log';
    var textarea= document.createElement('textarea');
    var input= document.createElement('input');
    input.value= user_id;
    input.readonly= True;
    var button= document.createElement('input');
    button.type= 'button';
    button.value= 'Message';

    var chut= document.createElement('div');
    chut.className= 'chut';
    chut.appendChild(log);
    chut.appendChild(textarea);
    chut.appendChild(input);
    chut.appendChild(button);
    document.getElementById('chuts').appendChild(chut);

    button.onclick= function() {
        alert('Send '+textarea.value+' to '+user_id);
    };

    return chut;
}

You could also use a convenience function or JS framework to cut down on the lengthiness of the create-set-appends calls there.

ETA:

I'm using jQuery at the moment as a framework

OK, then consider the jQuery 1.4 creation shortcuts, eg.:

var log= $('<div>', {className: 'log'});
var input= $('<input>', {readOnly: true, val: user_id});
...

The problem I have right now is that I use JSONP to add elements and events to a page, and so I can not know whether the elements already exist or not before showing a message.

You can keep a lookup of user_id to element nodes (or wrapper objects) in JavaScript, to save putting that information in the DOM itself, where the characters that can go in an id are restricted.

var chut_lookup= {};
...

function getChut(user_id) {
    var key= '_map_'+user_id;
    if (key in chut_lookup)
        return chut_lookup[key];
    return chut_lookup[key]= addChut(user_id);
}

(The _map_ prefix is because JavaScript objects don't quite work as a mapping of arbitrary strings. The empty string and, in IE, some Object member names, confuse it.)

这篇关于在将用户输入添加到DOM中之前,将其消除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆