简体   繁体   English

Javascript XSS 预防

[英]Javascript XSS Prevention

There is a Node.js project that sanitizes data and there is an OWASP library for JavaScript that handles sanitization to prevent XSS.有一个 Node.js 项目可以清理数据,还有一个用于处理清理以防止 XSS 的 JavaScript 的 OWASP 库。

I have been benchmarking these libraries, and they are pretty intensive and maybe an overkill, my application does not need any dynamic HTML (submitted by users, bbtags or what ever, not required at all) so why not do it like this:我一直在对这些库进行基准测试,它们非常密集,可能有点矫枉过正,我的应用程序不需要任何动态 HTML(由用户、bbtags 或其他任何东西提交,根本不需要)所以为什么不这样做:

  1. Disable " < " and " > " characters, don't replace them or anything, just disable them, if the user submits these, give them a warning that these are disabled (client- and server-side validation)禁用“ < ”和“ > ”字符,不要替换它们或任何东西,只是禁用它们,如果用户提交这些,给他们一个警告,这些被禁用(客户端和服务器端验证)
  2. & => &amp; & => &amp;
  3. " => &quot; " => &quot;
  4. ' => &#x27; ' => &#x27;
  5. / => / / => /
  6. Encode submitted URLs (GET parameters etc.)对提交的 URL 进行编码(GET 参数等)
  7. DOM based XSS is covered since my application uses HTML5 PushState and the backend is fully separated from the frontend.由于我的应用程序使用 HTML5 PushState 并且后端与前端完全分离,因此涵盖了基于 DOM 的 XSS。

Would this be enough to protect myself, as I said, my application does not require any HTML submitted by users, so I don't need the < and > tags at all.这是否足以保护我自己,正如我所说,我的应用程序不需要用户提交任何 HTML,所以我根本不需要<>标签。

Thanks for all the feedback, this is what I use right now:感谢所有反馈,这是我现在使用的:

var pattern = /<(.*)>/;

function hasHtmlTags(string) {
    return pattern.test(string);
};

if (hasHtmlTags(userData)) {
    // Do something?
} else {
    // Create entity.
}

So users can still use their emoticons :< and such, and the function only gets triggered if a combination of < and > is found.所以用户仍然可以使用他们的表情符号 :< 等,并且只有在找到 < 和 > 的组合时才会触发该功能。 So no expensive regular expressions and such, just disable < and > in combination and we should be fine.所以没有昂贵的正则表达式之类的,只需禁用 < 和 > 组合,我们应该没问题。

Here is a general encode procedure:这是一个通用的编码过程:

var lt = /</g, 
    gt = />/g, 
    ap = /'/g, 
    ic = /"/g;
value = value.toString().replace(lt, "&lt;").replace(gt, "&gt;").replace(ap, "&#39;").replace(ic, "&#34;");

If your user doesn't submit anything to your server you don't even need the above.如果您的用户没有向您的服务器提交任何内容,您甚至不需要上述内容。 If the user submits and you are using the user input then the above should be safe.如果用户提交并且您正在使用用户输入,则上述内容应该是安全的。 As long as the '<' and '>' are globally sanitized and the parenthesis also are you are good to go.只要 '<' 和 '>' 是全局消毒的并且括号也是你的好去处。

why not use encodeURIComponent before sending the data to the client?为什么不在将数据发送到客户端之前使用encodeURIComponent呢?

var string="<script>...</script>";
string=encodeURIComponent(string); // %3Cscript%3E...%3C/script%3

Considering https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html考虑到https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html

Here is an implementation of their recommendations :这是他们建议的实施:

function escapeOutput(toOutput){
    return toOutput.replace(/\&/g, '&amp;')
        .replace(/\</g, '&lt;')
        .replace(/\>/g, '&gt;')
        .replace(/\"/g, '&quot;')
        .replace(/\'/g, '&#x27')
        .replace(/\//g, '&#x2F');
}

Also make sure you use this function only when necessary or you might break some stuff.还要确保仅在必要时使用此功能,否则可能会破坏某些东西。

But I suggest you to take a look at already made libraries for sanatizing output :但我建议您查看已制作的用于清理输出的库:

https://github.com/ecto/bleach https://github.com/ecto/bleach

You can use a function like您可以使用类似的功能

 function htmlEncode(str){
  return String(str).replace(/[^\w. ]/gi, function(c){
     return '&#'+c.charCodeAt(0)+';';
  });
}

You would then use this function as follows:然后,您将按如下方式使用此函数:

<script>document.body.innerHTML = htmlEncode(untrustedValue)</script>

If your input is inside a JavaScript string, you need an encoder that performs Unicode escaping.如果您的输入在 JavaScript 字符串中,则需要一个执行 Unicode 转义的编码器。 Here is a sample Unicode-encoder:这是一个示例 Unicode 编码器:

function jsEscape(str){
  return String(str).replace(/[^\w. ]/gi, function(c){
     return '\\u'+('0000'+c.charCodeAt(0).toString(16)).slice(-4);
  });

}

You would then use this function as follows:然后,您将按如下方式使用此函数:

<script>document.write('<script>x="'+jsEscape(untrustedValue)+'";<\/script>')</script> 

More info: https://portswigger.net/web-security/cross-site-scripting/preventing更多信息: https : //portswigger.net/web-security/cross-site-scripting/preventing

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM