一、复杂的需求

WAF (WEB 应用防火墙) 用来保护 WEB 应用免受来自应用层的攻击。作为防护对象的 WEB 应用,其功能和运行环境往往是复杂且千差万别的,这导致即便防御某个特定的攻击方式时,用户需求也可能是细致而多样的。

以最基本的 SQL 注入 (以下简称注入) 为例。注入攻击当然是要防范的,但用户可能还有以下需求:

  • 某个域名或某些特定的 URL 不需要注入检查
  • 对来自外网的注入访问进行拦截,来自内网的注入访问只记录不拦截
  • 对特定的请求参数名或特定特征的请求参数不进行注入检查
  • 非工作时段不仅拦截还阻止该用户一段时间访问
  • 对 admin 等管理账号登录后的访问不进行注入检查
  • 对于只记录不拦截的请求,附加一个特别的请求头发往应用
  • 对某些 URL 的注入访问记录下 HTTP 请求的全部报文
  • 将 HTTP 响应码为 500 的注入的日志紧急度设为 alert
  • ...

以上需求,用户可能只提出一项,也可能提出多项,还可能是不同的逻辑组合或更多的条件和动作。这还仅仅是防注入这项基本功能,如果有更多的应用防护需求,比如:

一个已登录的非内网用户在 10 秒钟连续访问 POST 方法的页面 (非 AJAX 数据) 达到 5 次,则在 10 秒内延迟这个用户的响应时间 0.5 秒;如果在未来 10 秒内继续访问 POST 方法页面 3 次,则强制用户登出并阻止登录 30 秒;如果一个用户 1 天内这种情形发生 5 次,则产生一条严重级别的告警。

我们该如何描述满足这些需求的功能呢?

WAF是否能够设计得足够灵活,使得实施人员通过现场配置就能实现这个需求?

二、规则的局限性

大部分应用防火墙的配置以规则为核心。

传统意义上的规则,其实质形式是独立的一行行文本,每行文本有固定的结构/字段,可以独立地描述出一个功能。对用户而言,书写规则就是设置其中的参数和选项。这种规则的好处是简单明了,用户甚至可以在图形化界面中完成规则的配置,但其弱点是不足以描述复杂的情形。

以防注入功能为例,如果它只有一个开启或关闭的开关选项,或只能简单地以区分站点来使用不同策略,显然不能满足前述的复杂需求。而企图打造一个预先设定又包罗万象的规则,则完全超出了“规则”的范畴,是不可能完成的任务。

追溯一下,用规则来描述防护功能始自于网络防火墙。网络防火墙的检查对象是 TCP / IP 协议诸元,三/四层网络协议相对来说是简单清晰的,用五元组就可以概括它们,以五元组为对象写一些规则就能够很好地实现防护。

但是,WEB 应用是怎么写成的?WEB 应用是用 Java / PHP / Python 等编程语言写成的。就像不可能用“规则"来书写 WEB 应用一样,试图良好地对应用进行防护,也不可能通过传统的“规则"来实现——无论写多少条规则。

三、大家一起来编程?

既然应用是编程的,那么应用防火墙的配置可否也用编程的方式来实现?

以下是一个通用语言实现的例子,它的主功能是对请求参数进行注入检查,检查时会排除指定名字的参数,而且对不同来源访问者 (外网或内网) 产生不同的日志和动作:

for arg in ARGS:
if arg['name'] in ['__utm', '__token']:
return PASS if detect_sqli(remove_comment(url_decode(arg['value']))):
if is_private_address(REMOTE_ADDRESS):
log('SQLi and PASS')
return PASS
else:
log('SQLi and BLOCK')
return BLOCK
return PASS

功能是实现了,但看上去有点复杂。让非程序员去写这样一段代码难免强人所难 (比如对集合类型数据的遍历获取),而且完全不可能做到可视化。更重要的是,这仅是代码片段 (其实就是函数),真的要整合起来使用,还面临很多编程方面的问题,如:

  • 除错和容错:

    各种语法错误和链接错误,比如使用了不存在的变量或方法。
  • 批量控制:

    怎样实现全局和批量的改变,比如想让 WAF 全局进入只记录模式。
  • 作用域:

    每个代码片段有自己的作用域,如果想影响其他代码片段应该怎么做?如何定义变量作用域?
  • 与预置防护集的关系:

    WAF 必然自带预置的防护集,用户书写的代码与预置防护集的关系。
  • 参数的设置:

    应用相关的可配置参数怎么处理,是作为常量写在程序里 (难以维护) 还是另作一个配置文件 (程序变得更复杂)?

以上问题,如果都通过临时修改代码 (全局替换或加注释) 来实现,则代码将变得不可维护。事实上,由于代码的无限可能性,甲写的代码乙很难理解。为解决上述问题,必须要有一套程序框架,而框架本身的编写、配置和使用又成了问题。

有没有一种方法,不需要使用编程语言,而又能灵活满足复杂的需求呢?

四、类编程的WAF

天存信息的类编程 WAF,用数据结构来表达程序思想,让普通的技术支持人员也能够写出足够复杂和灵活的安全策略。

{
"if": {
"variables": "ARGS",
"transform": "urlDecodeUni",
"operator": "detectSQLi"
},
"then": {
"verdict": {
"action": "block",
"log": true
}
}
}

可见,这时的“规则”已经不是一行文本了,而是具有代码特征的一个函数实现 。

类编程的 WAF 具有以下与编程语言相似的特性:

  • 无限嵌套的 if / the / else 条件判断
  • 完整的 and / or / not 逻辑运算符
  • 对集合 / 数组成员的遍历运算
  • 变量包含多种数据类型
  • 支持变量的宏扩展引用
  • 用户自定义变量和表达式赋值
  • 预置及可设置不同生命期的全局变量
  • 用户书写任意多样的动作
  • 函数返回值灵活控制流程
  • 运行时改变其他函数行为

而这灵活内涵的表面,却能够用规范的模式 (schema) 来约束,使得写出的类程序易读且统一,甚至做到可视化呈现。

类编程的WAF(上)的更多相关文章

  1. 类编程的WAF(下)

    一.编程语言的要素 天存信息的iWall3应用防火墙是一种创新式的类编程 WAF,它包含了编程语言的一些基本要素. 1. 变量 iWall3 中广义的变量包括报文变量.环境变量和用户变量:报文变量和环 ...

  2. PythonI/O进阶学习笔记_7.python动态属性,__new__和__init__和元类编程(上)

    content: 上: 1.property动态属性 2.__getattr__和__setattr__的区别和在属性查找中的作用 3.属性描述符 和属性查找过程 4.__new__和__init__ ...

  3. Android利用网络编程HttpClient批量上传(两)AsyncTask+HttpClient监测进展情况,并上传

    请尊重别人的劳动.转载请注明出处: Android网络编程之使用HttpClient批量上传文件(二)AsyncTask+HttpClient并实现上传进度监听 执行效果图: 我曾在<Andro ...

  4. Python进阶开发之元类编程

    系列文章 √第一章 元类编程,已完成 ; 本文目录 类是如何产生的如何使用type创建类理解什么是元类使用元类的意义元类实战:ORM . 类是如何产生的 类是如何产生?这个问题肯定很傻.实则不然,很多 ...

  5. js中的行为委托和无类编程

    概述 <你不知道的JavaScript>中有这么一段话:不幸的是,将类和继承的设计模式思维带入Javascript的想法是你所做的最坏的事情,因为语法可能会让你迷惑不已,让你以为真的有类这 ...

  6. 【转】Shell编程基础篇-上

    [转]Shell编程基础篇-上 1.1 前言 1.1.1 为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应 ...

  7. Python元类编程

    来源:http://python.jobbole.com/88582/ @property装饰器,是将类中的函数当做属性调用 Python类中定义的属性,如果属性名前面只有一个下划线,那么就是一种规范 ...

  8. AOP切面编程在android上的应用

    代码地址如下:http://www.demodashi.com/demo/12563.html 前言 切面编程一直是一个热点的话题,这篇文章讲讲一个第三方aop库在android上的应用.第三方AOP ...

  9. JavaEE-实验一 Java常用工具类编程

    该博客仅专为我的小伙伴提供参考而附加,没空加上代码具体解析,望各位谅解 1.  使用类String类的分割split 将字符串  “Solutions to selected exercises ca ...

随机推荐

  1. TortoiseGit:拉代码密码错误remote: Coding 提示: Authentication failed! 认证失败,请确认您输入了正确的账号密码

    问题 在控制面板里找到凭据管理器 修改密码之后拉取密码

  2. 一文带你详细介绍c++中的std::move函数

    前言 在探讨c++11中的Move函数前,先介绍两个概念(左值和右值) 左值和右值 首先区分左值和右值 左值是表达式结束后依然存在的持久对象(代表一个在内存中占有确定位置的对象) 右值是表达式结束时不 ...

  3. FileInfo & DirectoryInfo

    这节讲两个实例类,FileInfo和DirectoryInfo两个类,用于操作某个具体的文件或者目录. FileInfo:     FileInfo不同于File,它是一个实例类,有一个string类 ...

  4. 云空调来自 GitHub 的冷气——GitHub 热点速览 v.21.20

    作者:HelloGitHub-小鱼干 万物皆可上云,air-conditioner 是上周火爆小鱼干朋友圈和公众号信息流的云空调项目.第一眼的时候,你会觉得和这个云空调还挺别致的,第二眼,si~~感到 ...

  5. 痞子衡嵌入式:在i.MXRT启动头FDCB里使能串行NOR Flash的Continuous read模式

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是在FDCB里使能串行NOR Flash的Continuous read模式. 前面关于串行Flash传输时序的文章 <Fast R ...

  6. 利用实体bean对象批量数据传输处理

    利用实体bean对象批量数据传输处理 需求 现在有两方数据库表结构相同,一方A.另一个方B,现想从A处查询出多个表的数据,传输到B地保存起来. 解决方案1 最简单粗暴的方法就是,查询出A处相关表的数据 ...

  7. 『动善时』JMeter基础 — 19、JMeter配置元件【随机变量】

    目录 1.随机变量介绍 2.随机变量界面详解 3.随机变量的使用 (1)测试计划内包含的元件 (2)线程组界面内容 (3)随机变量界面内容 (4)HTTP请求界面内容 (5)查看结果 1.随机变量介绍 ...

  8. 山东浪潮超越3B4000申泰RM5120-L

    龙芯解决方案 首页 > 龙芯业务 > 龙芯解决方案和产品生态 > 整机产品 > 服务器 > 详情 超越申泰RM5120-L 服务器 超越申泰RM5120-L 服务器 20 ...

  9. MergingSort

    递归排序的两种实现 <script type="text/javascript"> //归并排序(递归实现) //思想:堆排序利用了完全二叉树的性质,但是比较麻烦 // ...

  10. HAProxy与LVS综合----搭建LNMP源码编译结合HAProxy或LVS负载均衡

    实战一:实现LNMP与Keepalived.HAProxy做反向代理 框架图: 实现原理: 1.当A用户访问网站时,此时需要经过防火墙,防火墙将用户访问的IP地址处理后,如果允许访问,则就访问到HAr ...