我在刚学习JDBC的时候,在学习视频里记住了一句话:在执行SQL的时候,要使用preparedStatement代替Statement防止sql注入。这可能是第一次接触到关于web防护的问题,只不过那时候初学计算机,只记住了这句话,而没有理解其中的意思。
多年以后,在《白帽子讲web安全》这本书中,学习到了一些关于web安全的知识,例如DDoS攻击、SQL注入、xss攻击等概念,同时也学习了一些简单的防护。但是在学习防护手段的时候,不论是SQL注入还是DDoS,都需要开发者从代码层面去实现的,例如之前提到预防SQL注入的preparedStatement、以及限制访问频率预防DDoS。
但是并不是每个开发者都有web安全开发意识,更多的精力可能花在了应用架构设计和代码开发上。况且人力终有限,难免会有疏漏的地方,所以有没有能一键开启安全防护的产品,能帮助我们解决这些复杂的安全问题。所以,今天针对于我们对于web安全的需求,来测试腾讯提供安全解决方案产品:EdgeOne。
EdgeOne,全名Tencent cloud EdgeOne,是基于腾讯边缘计算节点提供加速和安全的解决方案。在加速方面,提供了动静态数据加速,跨国加速,智能路由优化等加速特性,降低了数据访问时间延迟,避免数据传输抖动,保障大量数据传输的稳定性和有效性。
在安全方面,提供 WAF,DDoS 安全防护服务。节点识别并拦截 L3/L4/L7层各类攻击请求,对 DDoS 攻击流量进行清洗,智能 AI 引擎、BOT 策略引擎对 Web、BOT、CC 类型攻击进行行为分析并更新拦截策略,阻断恶意请求到达用户网站。
今天暂时先抛开加速不谈,主要了解一下EdgeOne在安全防护的应用效果。
进入EdgeOne购买页。
针对于不同的业务需求,EdgeOne提供了不同的套餐类型。对于个人用户而言,选择个人版就足够使用,而且9.9元/月的价格极具性价比。
因为在EdgeOne领取一个3800元的代金券,所以这里我体验的是标准版,点击立即购买。
确认产品信息,选择代金券。
点击支付,完成付款。
点击进入控制台,跳转EdgeOne的控制台,在套餐管理中我们可以看到刚刚购买的EdgeOne套餐。
在购买完套餐之后,选择站点列表添加站点。
输入个人的站点域名,这个域名就是你服务使用的域名。
选择之前购买的EdgeOne套餐完成绑定。
下一步再选择加速区域和接入模式。
EdgeOne提供了两种接入模式,分别为 NS 接入模式和 CNAME 接入模式
模式 | NS 接入(推荐) | CNAME 接入 |
---|---|---|
适用场景 | 可修改原有域名解析服务商,将域名解析托管至 EdgeOne。 | 当前域名已托管在其他域名解析服务商处,不希望更改原有解析服务商。 |
接入方式 | 只需要去原域名解析服务商修改一次 DNS 服务器,托管域名解析后可针对域名一键开启安全加速。 | 每次新增子域名并开启加速时,都需要去相应的 DNS 解析服务商添加一次 CNAME 记录。 |
验证方式 | 需修改原有 NS 服务器至 EdgeOne 指定的地址。 | 通过添加 DNS 记录或者文本验证的方式验证主域名归属权。 |
调度方式 | 域名开启加速后,可通过 A 记录直接指向最近的 EdgeOne 边缘节点。 | 需通过 Cname 调度至最近的 EdgeOne 边缘节点。 |
从上面来看,选择NS接入是比较简单的。但是NS接入需要域名备案才能生效,在腾讯云搜索ICP备案,根据指引完成备案。
如果想要使用EdgeOne的加速安全防护,需要根据提示修改DNS服务器。
在域名控制台找到自己的域名,点击修改DNS服务器。
修改DNS服务器,点击提交。
最后站点就添加完成。
点击上面的站点进入到EdgeOne的防护页面。
在域名服务下找到DNS记录。
按照我上图的配置,填入域名和你的服务器IP,点击保存。
保存完成之后,在域名管理中,就可以看到新增加的域名已经开启了加速和安全防护。
在EdgeOne的web防护中,开启深度分析,用来防御攻击。
这里我们可以看到托管规则中看起了很多安全防护规则。
例如我们比较熟悉的XSS跨站脚本攻击防护和SQL注入攻击防护,这两个防护也是今天我们要讲的。通过修改防护等级和处置方式,启用的规则也会随之变动。
在EdgeOne中,针对于被托管拦截的请求,我们还可以自定义拦截页面。这里要记住的点是被拦截的页面的响应码是566。
在编辑页面可以指定URL和文件页面。
为了测试EdgeOne安全防护功能,我选择使用DVWA靶场来搭建攻击的环境。因为搭建DVWA既需要apache服务器,又需要PHP环境,所以这里就是用phpStudy面板来完成DVWA环境的搭建。
执行安装命令:
yum install -y wget && wget -O install.sh https://notdocker.xp.cn/install.sh && sh install.sh
等待执行完成之后,就会出现phpStudy访问地址、账号和密码,如果是云服务器还需要在安全组开放9080端口。
通过URL访问PhpStudy,然后输入账号、密码登录。
在软件管理中,我们可以看到PhpStudy已经安装了php5.5和apache服务器,如果主机没有MySQL,还需要安装MySQL,不过需要3G的内存,我在DVWA使用的是自己安装的MySQL。
不过DVWA依赖php7.x,所以需要卸载php5.5再安装php7。
这里要注意的是,PhpStudy会默认修改/usr/bin/中已有的mysql修改为mysql~,然后重新创建一个软链接指向自己的mysql。但是这里我服务器上已经安装了MySQL,所以执行mysql就报错(因为没有安装PhpStudy的MySQL)。
这里只需要将mysql~重命名为mysql即可。
php和MySQL准备好之后,就要启动apache服务器。首先需要完成站点配置,在网站菜单栏中选择添加站点,输入我之前在EdgeOne配置的域名。
然后apache会根据域名分配一个应用目录,我们可以在linux中看到这个目录。
记住这个目录,然后回到首页启动apache。
默认使用80端口,这也就意味着在浏览器中输入IP或者域名,直接就能访问到服务。
后台也可以看到apache服务器进程。
在github上下载DVWA的源码。
wget https://github.com/digininja/DvWA/archive/master.zip
解压源码之后,将目录重新命名成dvwa。进入config目录,将config.inc.php.dist去掉后面dist重命名为config.inc.php。
mv config.inc.php.dist config.inc.php
然后vi修改配置文件。
配置文件中主要修改的是MySQL连接信息,因为DVWA靶场攻击有一些依赖于MySQL,例如SQL注入等。这里修改的是db_user和db_password。
修改完配置之后,将dvwa目录放入到Apache服务器应用目录中。
mv dvwa /www/admin/lzys522.cn_80/wwwroot
这时候通过http://lzys522.cn/dvwa就可以访问到dvwa。这里的域名一定要使用EdgeOne中配置的域名。
点击下方的Create/Rest DataBase来初始化DVW。
登录MySQL查看数据库,可以发现自动创建了一个dvwa数据库。
初始化完成之后点击下面的login,跳转到登录页面。初始账号为:admin,密码:password。在dvwa数据库中,通过下面sql可以修改密码。
UPDATE users SET password=md5('new_password') WHERE user='admin';
登录admin账号,就进入到了DVWA的首页。
在首页我们可以看到有很多攻击的手段。例如CSRF(跨站点请求伪造攻击)、File Inclusion(文件包含漏洞)、SQL Injection(SQL注入)、XSS(跨站脚本攻击)等。我们从最简单的SQL注入开始测试EdgeOne的安全强度。
DVWA Security一共分为四个安全强度。从low最低到Impossible最高。
这里先将安全强度调至最低low。
什么是SQL注入?简而言之SQL注入就是用户在输入的字符串条件中,加入额外的SQL语句。
举个例子:
$id = $_REQUEST[ 'id' ];
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';"
这是个根据用户输入的id,查询某用户的语句。通常情况下,普通用户会输入1、2、3这种用户id,当我们输入1时,sql就变成了:
SELECT first_name, last_name FROM users WHERE user_id = '1';
会查到id为1的用户信息。
如果此时输入1' or 1=1# ,整个sql就变成了:
SELECT first_name, last_name FROM users WHERE user_id = '1' or 1=1#';
可以看到,最后的单引号被#注释掉了,由输入的单引号来闭合第一个条件开始的单引号。原本只有一个指定user_id的查询条件,但是后面被恶意拼接了or 1=1条件,这样就成了查询所有的用户信息了。
根据上面的原理,如果输入1' union select user,password from users # 。
SELECT first_name, last_name FROM users WHERE user_id = '1' union select user,password from users #;
这就相当于查询了MySQL的用户表的所有用户和密码。
虽然MySQL中被加密了,但是如果简单密码通过撞库还是会被破解的。
在low安全等级下,SQL注入的发生,是对于用户的输入不做检查导致的,所以在DVWA的medium安全等级下,直接将用户输入变成了选项框。
我们知道,在前端向后台请求数据的时候,前台表单数据会作为url的参数,这里我们先按照low的方式注入。
如图,我们只要自己构造这个url,传入之前的参数1' or 1==1# ,结果报错。
You have an error in your SQL syntax; check the manual that corresponds
to your MySQL server version for the right syntax to use near '\' or 1==1 #' at line 1
根据报错信息,考虑大概率是条件无法闭合直接报错。这时候我们考虑user_id是int类型,是否在后端sql中这个条件没有加单引号。
于是我用了最简单的方法,修改表单值为1的value为1 union select user,password from users# (也可以构造url请求),然后submit。
如图,成功获取了MySQL用户名和密码。我们查看DVWA关于SQL注入medium等级的后端代码。
$id = $_POST[ 'id' ];
$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);
$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
果然,不仅由GET转换成了POST,而且调用mysqli_real_escape_string对用户输入的特殊字符进行转义。所以我再输入'就无法构造成一个有效的sql,就会报错。但是这里sql中user_id指向的$id没有用引号,这就存在一个明显数字型SQL注入。
在high等级下,点击”here to change your ID”,页面自动跳转,防御了自动化的SQL注入。
在页面中,我输入1' union select user,password from users# ,同样也是获取到了MySQL的用户名和密码。
DVAWSQL注入high安全等级代码如下:
$id = $_SESSION[ 'id' ];
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
impossible,顾名思义就是不可能的,这里就是
$id = $_GET[ 'id' ];
// Was a number entered?
if(is_numeric( $id )) {
$id = intval ($id)
$data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
}
首先判断输入的id是否为数字,只有数字才能执行后面语句,然后使用intval()函数来对id进行下一步的数字转换,这两步确保输入一定是数字。
接着使用了prepare预编译,数据库不会将参数的内容视为SQL执行的一部分,而是作为一个字段的属性值来处理,这样就避免了上面的字符拼接的SQL注入。
EdgeOne提供了85条托管规则来防护SQL注入,根据防护场景标注了宽松、正常、严格、超严格等级,这里的处置方式一律选择为拦截。
我把DVWA接入到EdgeOne中,将DVWA的安全等级设置为low,然后进行sql注入,我输入1' or 1=1#* 之后点击提交,页面就被拦截了。
从响应可以看到,响应码为566,这是EdgeOne托管规则拦截后的响应。
而且返回服务的地址是43.175.237.123,这个是EdgeOne的加速地址。
在EdgeOne的Web安全分析页面,可以看到刚才的SQL注入都被成功拦截。
而且还会显示每条SQL注入请求匹配到的拦截规则。
xss,跨站脚本攻击,攻击者通过在网页中注入恶意script脚本,进而在用户浏览该网页时执行恶意脚本,从而窃取用户信息、篡改网页内容等。
常见的XSS一共分为三种:
反射性XSS通常是将用户输入的内容直接插入到网页中。
$name = htmlspecialchars( $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello {$name}</pre>";
在上面php代码中,将用户输入直接在网页输出,正常情况下我输入一个字符串。
页面上就会显示。而当输入的内容包含script代码块时,网页就会执行这个代码。
<script>alert("XSS");</script>
这段alert就是我的恶意代码,通过反射性xss就注入到了网页上,点击submit就被执行。
这里演示的是一个简单的script代码块,通常的攻击使用src属性指定远程服务器上的脚本,例如
<script src='http://ip/xss.js></script>
存储型XSS,顾名思义和存储有关。例如留言板,留言内容写入了一个script代码块,然后没做检查就存储到了MySQL中,当刷新页面,这个留言就会被展示在留言板,里面包含的script就会执行,影响到其他的用户。
我在留言板中输入包含script代码的留言。
然后点击提交到留言板。
在将留言从数据库渲染到网页的时候,其中包含的script代码就会被执行。从上图中可以看到,每次进入留言板页面,里面的script就会被执行。而留言板是对于所有用户开放的,所以每个用户进入到留言板,也会执行里面的script。
DOM,即document对象。DOM型XSS指定是利用document对象的接口,例如write()、innerHTML、cookie、url等,实现XSS攻击。
如图,在DVWA的DOM型XSS靶场页面,使用document的write()构造html元素。这段代码中if的意思就是说href如果存在default,则取出 default的值赋值给变量lang,并写到网页中。
如图所示,url中的default的值此时是English,我们修改成一个script脚本试一下。
<script>alert(document.cookie)</script>
在script中利用document获取cookie。
这就是比较典型的DOM型的XSS。除了上面举的例子,eval()、setTimeout()和setInterval()使用不当,都可能会被注入恶意代码,所以这对于开发人员是个挑战。
上面虽然是三种不同类型的xss攻击,但是可以看到其实都是最简单在url中拼接script脚本的攻击。
为了预防这种攻击,medium等级下是替换了用户输入的'script'。
$name = str_replace( '<script>', '', $_GET[ 'name' ] );
可以看到,是对script标签进行了替换,但是如果我将script改成大写呢。
可以看到一样完成了XSS攻击。
在high安全等级下,做了替换升级,针对于大小写的script、双写script都做了一层过滤替换。
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
但是对于其他html元素没有进行过滤,这里我直接添加一个img标签,src指向错误的地址,然后添加onerror回调。
<img src=x onerror=alert('XSS');>
如下图,通过img标签完成了xss攻击。
$name = htmlspecialchars( $_GET[ 'name' ] );
使用htmlspecialchars()函数将特殊字符转换为HTML实体,例如
&:转换为&
":转换为"
<:转换为<
>:转换为>
这样就无法进行XSS攻击。
我们可以看到,对于普通的开发者来说,想要预防XSS攻击,需要站在攻击者的角度从很多方面考虑。而我们再看EdgeOne,针对于XSS攻击,提供了35条托管规则。
同样将DVWA接入到EdgeOne中,然后开始进行XSS攻击。
针对于反射型XSS,同样输入XSS脚本,可以看到最后被EdgeOne拦截。
这里使用大写的Script来XSS攻击。
被EdgeOne成功拦截。
这里我输入之前img标签用作XSS攻击。
可以看到img标签的XSS攻击被拦截。同时在EdgeOne控制台的Web安全分析中,也可以看到拦截的XSS攻击详情。
DDoS,分布式拒绝服务攻击。原理就是想方设法与你的服务建立很多的连接,耗费你的资源,让正常的用户无法与你的服务建立连接。常见的攻击手段分为网络层和应用层面。
网络层DDoS攻击就是利用TCP三次握手的漏洞,伪造一个假的源地址发送SYN包,然后在服务端SYN/ACK包的时候,假IP不会响应,服务端就会重试3-5次且等待一个SYN Time(30s ~ 2min),这样就会建立很多无用的连接。
应用层DDoS攻击必将常见的就是CC攻击,通过控制某些主机不停地发大量数据包给服务器,特别是那些需要大量CPU资源处理的页面,让CPU长时间处于高负载状态,从而导致服务器资源耗尽,造成网络拥塞和服务中断,无法处理正常的访问请求。
所以很多网站为了防止无限制访问,通常会对客户端进行请求频率限制或者访问过多弹出验证码,CC通常会使用代理来绕开这些限制。这些都需要在开发时在逻辑代码中实现,设计安全模块来实现。
除了CC攻击之外,还有Slowloris资源耗尽攻击,通过构造畸形的请求头来保持连接不被中断。这里我们主要来看应用层的CC攻击。
DDoS 防护(Anti-DDoS)具有全面、高效、专业的 DDoS 防护能力,为企业组织提供 DDoS 高防包、DDoS 高防 IP 等多种 DDoS 解决方案,应对 DDoS 攻击问题。通过充足、优质的 DDoS 防护资源,结合持续进化的“自研+AI 智能识别”清洗算法,保障用户业务的稳定、安全运行。
CC攻击防护通过速率基线学习、头部特征统计分析和客户端IP情报等方式识别CC攻击,并进行处置。EdgeOne 提供了预设的三种 CC 攻击防护策略:
在自适应频控中,默认频次限制是2000次/5秒,我们可以在编辑中修改请求频次,修改为40次/10秒。
CC攻击就是无限制的网站发起访问,这里我使用shell脚本来简单地模拟CC攻击。
for in in {1..80};
do
curl -XGET 'http://lzys522.cn/dvwa/'
done
在10s内一共发起80次请求,已经超过了40次/10秒的限制,所以EdgeOne将这些访问视为了CC攻击,进行了拦截,从web安全分析中的CC攻击防护可以看到。
上面也讲过网络层的DDoS攻击,利用TCP设计缺陷来完成攻击,而网络层的DDoS攻击对于普通开发者来说,通常很难防御。而EdgeOne基于攻击画像、行为模式分析、AI 智能识别等防护算法,可识别并过滤下列类型的 DDoS 攻击。
EdgeOne除了平台默认的DDoS防护规格之外,还在企业版中提供了独立DDoS防护,提供了更为强大的DDoS防护能力。
在EdgeOne平台的指标分析中,通过分析L7(应用层)访问日志数据,提供了多维度、可视化的流量分析展示。
我在上面对我的域名在EdgeOne开启了加速,所以我在访问我的域名时,EdgeOne 将会把响应的静态文件缓存在边缘节点中。当我再次请求,将会由边缘节点直接响应请求,避免回源请求,这部分就是上图中我们看到EdgeOne命中的响应流量。
因为我的服务器在HK,之前CC攻击测试就是在上面发起的,所以可以在区域分布页面可以看到这部分请求也被区分了出来。
鼠标悬停,可以点击加入筛选,将区域的维度作为筛选条件。除此之外,还会从Host、URL、资源类型、客户端IP、referer、客户端设备、状态码的维度进行流量分析。
针对于每一个指标分析,通过点击右上角的下载按钮,都可以将数据/图表下载到本地。
Web防护除了对访问进行特征匹配,有效抵御 SQL 注入、XSS 攻击、本地文件包含等各类 Web 攻击,实时保护用户源站之外,还有一些其他功能。
我们可以在Web防护中针对于客户端IP、区域、Referer等类型来添加规则。
这样就可以对一些没有refferer的请求进行过滤,也可以通过这个功能实现黑白名单。
在EdgeOne中,针对于被托管拦截的请求,我们还可以自定义拦截页面。
在编辑页面可以指定URL和文件页面。
本篇文章主要从SQL注入、XSS攻击以及DDoS来普及了一下常见的web安全知识,同时也利用这些攻击手段,对EdgeOne的防护能力有了一个新的认知。除此之外,EdgeOne还有很多安全防护的功能,例如文件上传攻击、Idap注入攻击的防护等。
EdgeOne的存在,让开发者除了在代码中实现基本的web安全防护之外,也有了更多的选择。
最后特别感谢社区大佬杨不易的域名(lzys522.cn)支持.
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。