如果用Node.JS做Web服务,很多时候是会选择Express的。

本文,将展示如何如何实现一个WAF中间件。

WAF有什么用?

WAF即Web Application Firewall,Web应用防火墙,防攻击、防黑客的。

小提示:npm上,目前还没有专业的express中间件WAF,这可是稀缺的技术!

先看完整示例代码:

var express = require('express');var app = express();

//当访问根目录时触发app.get('/', function (req, res) {   res.send('Hello Jshaman.com');})

//WAF中间件app.use(function(req, res, next) {    var path = req.url;    console.log(path);    if(waf_detect(path) == false){        next();    }    //console.log(req.cookies);    //console.log(req.headers['user-agent']);});

//使用正则表达式,检测字符串是否含有攻击特征,检测到攻击特征返回true,没检测到返回falsefunction waf_detect(str_to_detect){

    var regexp_rule =[        /select.+(from|limit)/i,        /(?:(union(.*?)select))/i,        /sleep\((\s*)(\d*)(\s*)\)/i,        /group\s+by.+\(/i,        /(?:from\W+information_schema\W)/i,        /(?:(?:current_)user|database|schema|connection_id)\s*\(/i,        /\s*or\s+.*=.*/i,        /order\s+by\s+.*--$/i,        /benchmark\((.*)\,(.*)\)/i,        /base64_decode\(/i,        /(?:(?:current_)user|database|version|schema|connection_id)\s*\(/i,        /(?:etc\/\W*passwd)/i,        /into(\s+)+(?:dump|out)file\s*/i,        /xwork.MethodAccessor/i,        /(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(/i,        /\<(iframe|script|body|img|layer|div|meta|style|base|object|input)/i,        /(onmouseover|onmousemove|onerror|onload)\=/i,        /javascript:/i,        /\.\.\/\.\.\//i,        /\|\|.*(?:ls|pwd|whoami|ll|ifconfog|ipconfig|&&|chmod|cd|mkdir|rmdir|cp|mv)/i,        /(?:ls|pwd|whoami|ll|ifconfog|ipconfig|&&|chmod|cd|mkdir|rmdir|cp|mv).*\|\|/i,        /(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\//i    ];

    for(i=0; i< regexp_rule.length; i++){        if(regexp_rule[i].test(str_to_detect) == true){			console.log("attack detected, rule number:", "("+i+")", regexp_rule[i]);			return true;        }    }    return false;}

var server = app.listen(8000, function () {   var host = server.address().address   var port = server.address().port   console.log(host, port);}) 

本示例,是一个带有WAF功能的Web应用。

内置的中间件部分,实现WAF的防护功能:

//WAF中间件app.use(function(req, res, next) {    var path = req.url;    console.log(path);    if(waf_detect(path) == false){        next();    }    //console.log(req.cookies);    //console.log(req.headers['user-agent']);});

即,对发起的请求进行过滤,判断请求中是否有恶意行为。如果有,则不让中件间进行next(),请求也就被中断,达到防止攻击者入侵的目的。

WAF防护规则

攻击检测使用的是正则表达式,这是WAF常用的攻击检测方式。

这套规则来自ShareWAF,ShareWAF是专业、强大的WAF商业产品。

//This rule from:www.sharewaf.comvar regexp_rule =[        /select.+(from|limit)/i,        /(?:(union(.*?)select))/i,        /sleep\((\s*)(\d*)(\s*)\)/i,        /group\s+by.+\(/i,        /(?:from\W+information_schema\W)/i,        /(?:(?:current_)user|database|schema|connection_id)\s*\(/i,        /\s*or\s+.*=.*/i,        /order\s+by\s+.*--$/i,        /benchmark\((.*)\,(.*)\)/i,        /base64_decode\(/i,        /(?:(?:current_)user|database|version|schema|connection_id)\s*\(/i,        /(?:etc\/\W*passwd)/i,        /into(\s+)+(?:dump|out)file\s*/i,        /xwork.MethodAccessor/i,        /(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(/i,        /\<(iframe|script|body|img|layer|div|meta|style|base|object|input)/i,        /(onmouseover|onmousemove|onerror|onload)\=/i,        /javascript:/i,        /\.\.\/\.\.\//i,        /\|\|.*(?:ls|pwd|whoami|ll|ifconfog|ipconfig|&&|chmod|cd|mkdir|rmdir|cp|mv)/i,        /(?:ls|pwd|whoami|ll|ifconfog|ipconfig|&&|chmod|cd|mkdir|rmdir|cp|mv).*\|\|/i,        /(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\//i    ];

规则逻辑暂且不详细探讨,因为它是正则表达式,如果详细讲述起来,恐怕得另多写三五篇文章了。

执行效果:

模拟访问发起攻击:

http://127.0.0.1:8000/index.html

即在url中传入select*from admin语句,这是一句常见的SQL注入攻击语句。

可以看到,网站无法打开。在后台输出了拦截信息,并提示出触发了哪条WAF防护规则。

本文只做演示,仅检测了url路径。

那么本代码是可以括展的,可以检测cookie、user-agent、post数据等常见攻击点。

写成一个Express模块是完全可以的。

更多本系列文章:

http://www.fairysoftware.com/node.js_in_practice.html

Node.JS实战36:写一个WAF中间件!防黑客,防攻击的更多相关文章

  1. 用node.js从零开始去写一个简单的爬虫

    如果你不会Python语言,正好又是一个node.js小白,看完这篇文章之后,一定会觉得受益匪浅,感受到自己又新get到了一门技能,如何用node.js从零开始去写一个简单的爬虫,十分钟时间就能搞定, ...

  2. 使用Node.js原生API写一个web服务器

    Node.js是JavaScript基础上发展起来的语言,所以前端开发者应该天生就会一点.一般我们会用它来做CLI工具或者Web服务器,做Web服务器也有很多成熟的框架,比如Express和Koa.但 ...

  3. 用node.js给C#写一个数据表的实体类生成工具

    虽然微软提供了T4模板,但是我感觉非常难用.哪儿比得上直接用脚本来写模板来的爽. 因为要给一个老项目做周边的工具,需要连接到数据库. 我习惯性用EntityFrameworkCore来做,因为毕竟从出 ...

  4. Node.js实战14:一个简单的TCP服务器。

    本文,将会展示如何用Nodejs内置的net模块开发一个TCP服务器,同时模拟一个客户端,并实现客户端和服务端交互. net模块是nodejs内置的基础网络模块,通过使用net,可以创建一个简单的tc ...

  5. iKcamp团队制作|基于Koa2搭建Node.js实战(含视频)☞ 中间件用法

    中间件用法--讲解 Koa2 中间件的用法及如何开发中间件

  6. Node.js实战项目学习系列(1) 初识Node.js

    前言 一直想好好学习node.js都是半途而废的状态,这次沉下心来,想好好的学习下node.js.打算写一个系列的文章大概10几篇文章,会一直以实际案例作为贯穿的学习. 什么是node Node.js ...

  7. iKcamp团队制作|基于Koa2搭建Node.js实战项目教学(含视频)☞ 环境准备

    安装搭建项目的开发环境 视频地址:https://www.cctalk.com/v/15114357764004 文章 Koa 起手 - 环境准备 由于 koa2 已经开始使用 async/await ...

  8. iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 记录日志

    沪江CCtalk视频地址:https://www.cctalk.com/v/15114923883523 log 日志中间件 最困难的事情就是认识自己. 在一个真实的项目中,开发只是整个投入的一小部分 ...

  9. iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 视图Nunjucks

    视频地址:https://www.cctalk.com/v/15114923888328 视图 Nunjucks 彩虹是上帝和人类立的约,上帝不会再用洪水灭人. 客户端和服务端之间相互通信,传递的数据 ...

随机推荐

  1. CentOS7升级gcc

    CentOS7.5升级gcc到8.3.0版本 1.下载源码包 cd /usr/local/src wget http://ftp.tsukuba.wide.ad.jp/software/gcc/rel ...

  2. C#基础知识之依赖注入

    目录 1 IGame游戏公司的故事 1.1 讨论会 1.2 实习生小李的实现方法 1.3 架构师的建议 1.4 小李的小结 2 探究依赖注入 2.1 故事的启迪 2.2 正式定义依赖注入 3 依赖注入 ...

  3. python基础练习题2

    01:python九九乘法表 for i in range(1,10): for j in range(1,i+1): print('{}*{}={}'.format(j,i,i*j),end='\t ...

  4. Flask【第5篇】:用Falsk实现的分页

    用flask实现的分页 一.flask实现的分页组件 from urllib.parse import urlencode,quote,unquote class Pagination(object) ...

  5. Java面试之集合框架篇(3)

    21.ArrayList和Vector的区别 这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态 ...

  6. 前端面试题常考&必考之--http中的post和get的区别

    从字面上看,post是发送,则是提交数据,get是获得,则是获取数据,没毛病,我们可以就按字面来理解 具体就看图吧 吐槽:插入的表格不好用,不知道是自己不会用还是真不好用,变成了截图,修饰了下子

  7. STM32内部硬核的认识

    STM32内部含有硬核,对于一些协议(例如:UART,SPI,IIC,CRC等)我们只要调用硬核就可以了,同时我们也可以自己写通信协议. 这些硬核最终肯定是要有引脚输出的,这就是为什么STM32的引脚 ...

  8. php array_push()函数 语法

    php array_push()函数 语法 作用:向第一个参数的数组尾部添加一个或多个元素(入栈),然后返回新数组的长度.博智达 语法:array_push(array,value1,value2.. ...

  9. vue路由传参并跳转页面

    在vue项目中参数的传递可以使用本地缓存或者Vuex,那么vue能不能像小程序一样路由传参呢,显然是可以的而且非常简单 方式一:query传参 //传参 go(){ that.$router.push ...

  10. CF F. Royal Questions kruskal

    每一个 $A$ 必须和指定的唯一的 $B$ 匹配,转化成图论关系就是 $A$ 和 $B$ 之间有若干条连边,每个边有一个边权,而该边权只能代表一对 $A,B$. 这其实就是一个基环树的结构. 所以只需 ...