我正在进行与正在进行的“项目学生”系列相关的研究,并意识到我犯了最常见的错误,也最容易纠正的错误之一。 我并没有利用我对Web应用程序了解的所有知识来向外扩展我的安全范围。

我正在专门考虑UUID参数。 我知道每个有效的外部可见ID都是UUID。 我知道UUID的形式。 那么,为什么不进一步检查我的“ uuid”参数是否是潜在的有效UUID?

的确,数据库层不会识别出错误的“ uuid”值-但这可能不是攻击者的意图。 也许这是SQL注入攻击的一部分。 也许这是XSS攻击的一部分。 也许这是对我的日志的攻击的一部分(例如,通过包含一个很长的值可能会导致缓冲区溢出)。 也许这是我从未听说过的东西的一部分。 没关系–通过尽快消除已知无效的数据,我将永远变得更强大。

效用方法

确定一个值是否可能是UUID的实用方法使用简单的正则表达式模式。

public final class StudentUtil {private static final Pattern UUID_PATTERN = Pattern.compile("^\\p{XDigit}{8}+-\\p{XDigit}{4}+-\\p{XDigit}{4}-\\p{XDigit}{4}+-\\p{XDigit}{12}$");/*** Private constructor to prevent instantiation.*/private StudentUtil() {}public static boolean isPossibleUuid(String value) {return value != null && UUID_PATTERN.matcher(value).matches();}
}

如果我们要积极进取,我们可以仔细选择我们的UUID,以便它们具有我们可以检查的其他属性。 例如,对应的BigInteger始终可以保留3 mod 17的余数。攻击不太可能知道这一点,并且当有人探测我们的系统时,我们会发出警告。 甚至更复杂的方法将为每个类的UUID使用不同的属性,例如,“课程” UUID可能是3 mod 17,而“学生” UUID是5 mod 17。

单元测试

进行测试很容易,但是最少的设置是检查非十六进制数字,
值太多或太少,一个空字符串和一个空值。

public class StudentUtilTest {@Testpublic void testValidUuid() {assertTrue(StudentUtil.isPossibleUuid("63c7d688-705c-4374-937c-6628952b41e1"));}@Testpublic void testInvalidUuid() {assertTrue(!StudentUtil.isPossibleUuid("63c7d68x-705c-4374-937c-6628952b41e1"));assertTrue(!StudentUtil.isPossibleUuid("63c7d68-8705c-4374-937c-6628952b41e1"));assertTrue(!StudentUtil.isPossibleUuid("63c7d688-705c4-374-937c-6628952b41e1"));assertTrue(!StudentUtil.isPossibleUuid("63c7d688-705c-43749-37c-6628952b41e1"));assertTrue(!StudentUtil.isPossibleUuid("63c7d688-705c-4374-937c6-628952b41e1"));assertTrue(!StudentUtil.isPossibleUuid("63c7d688-705c-4374-937c-6628952b41e1a"));assertTrue(!StudentUtil.isPossibleUuid("63c7d688-705c-4374-937c-6628952b41e"));assertTrue(!StudentUtil.isPossibleUuid(""));assertTrue(!StudentUtil.isPossibleUuid(null));}
}

REST服务器

REST服务器应检查所有需要一种方法的UUID值。 在我们确认它是格式正确的UUID之后,可以安全地记录请求参数,但是仍然需要注意在请求中记录未过滤的值。

@Path("/{courseId}")@GET@Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML })public Response getCourse(@PathParam("courseId") String id) {Response response = null;if (!StudentUtil.isPossibleUuid(id)) {response = Response.status(Status.BAD_REQUEST).build();LOG.info("attempt to use malformed UUID");} else {LOG.debug("CourseResource: getCourse(" + id + ")");try {Course course = finder.findCourseByUuid(id);response = Response.ok(scrubCourse(course)).build();} catch (ObjectNotFoundException e) {response = Response.status(Status.NOT_FOUND).build();LOG.debug("course not found: " + id);} catch (Exception e) {if (!(e instanceof UnitTestException)) {LOG.info("unhandled exception", e);}response = Response.status(Status.INTERNAL_SERVER_ERROR).build();}}return response;}

一个明显的改进是将该检查(和异常处理包)移到所有服务方法的AOP包装器中。 这将简化代码,并在保证始终执行检查方面大有帮助。 (由于Web服务服务器层当前不具有Spring依赖关系,因此我目前不在Project Student中使用它。)

您可以提出一个强有力的opsec参数,即REST方法应返回NOT_FOUND响应而不是BAD_REQUEST响应,以减少信息泄漏。

网络应用

细节有所不同,但即使webapp只是REST服务的浅层前端,我们也应该对它们进行相同的处理。 只要有UUID,无论其来源是什么,都应在使用前对其进行检查。

筛选器

有一种流派认为,安全性应与应用程序分开处理–最好的安全性是在部署时(通过过滤器和AOP)结合在一起的,而不是嵌入到应用程序中。 没有人建议应用程序开发人员应该忽略安全性考虑因素,就像我上面所讨论的那样,检查很混乱,分散了开发人员的注意力,并且不可靠,因为开发人员很容易忽略。 他们建议改用AOP或过滤器。

编写与上述代码具有相同功能的过滤器很简单:

public class RestParameterFilter implements Filter {private static final Logger LOG = Logger.getLogger(RestParameterFilter.class);private static final Set<String> validNouns = new HashSet<>();/*** @see javax.servlet.Filter#init(javax.servlet.FilterConfig)*/@Overridepublic void init(FilterConfig cfg) throws ServletException {// learn valid nounsfinal String nouns = cfg.getInitParameter("valid-nouns");if (nouns != null) {for (String noun : nouns.split(",")) {validNouns.add(noun.trim());}}}/*** @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,*      javax.servlet.ServletResponse, javax.servlet.FilterChain)*/@Overridepublic void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException,ServletException {HttpServletRequest hreq = (HttpServletRequest) req;HttpServletResponse hresp = (HttpServletResponse) resp;// verify the noun + uuidif (!checkPathInfo(hreq, hresp)) {return;}// do additional tests, e.g., inspect payloadchain.doFilter(req, resp);}/*** @see javax.servlet.Filter#destroy()*/@Overridepublic void destroy() {}/*** Check the pathInfo. We know that all paths should have the form* /{noun}/{uuid}/...* * @param req* @return*/public boolean checkPathInfo(HttpServletRequest req, HttpServletResponse resp) {// this pattern only handles noun and UUID, no additional parameters.Pattern pattern = Pattern.compile("^/([\\p{Alpha}]+)(/?([\\p{XDigit}-]+)?)?");Matcher matcher = pattern.matcher(req.getPathInfo());matcher.find();// verify this is a valid noun.if ((matcher.groupCount() >= 1) && !validNouns.contains(matcher.group(1))) {// LOG.info("unrecognized noun");LOG.info("unrecognized noun: '" + matcher.group(1) + "'");resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);return false;}// verify this is a valid verb.if ((matcher.groupCount() >= 4) && !StudentUtil.isPossibleUuid(matcher.group(4))) {LOG.info("invalid UUID");resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);return false;}return true;}
}

没有理由我们也不能检查有效载荷。 例如,我们可以验证日期,电话号码和信用卡号的格式是否正确; 或名称仅包含字母(包括非拉丁字符,如ñ),空格和撇号。 (想想“ Anne-MariePeñaO'Brien”。)重要的是要记住,这些检查不是针对“有效”数据的,而是要消除“无效”数据。

我们必须将过滤器添加到我们的web.xml文件中。

web.xml

<filter><filter-name>REST parameter filter</filter-name><filter-class>com.invariantproperties.sandbox.student.webservice.security.RestParameterFilter</filter-class><init-param><param-name>valid-nouns</param-name><param-value>classroom,course,instructor,section,student,term,testRun</param-value></init-param>
</filter><filter-mapping><filter-name>REST parameter filter</filter-name><servlet-name>REST dispatcher</servlet-name>
</filter-mapping>

ModSecurity

为电话号码和姓名之类的简单元素编写过滤器很容易,但是纯文本字段是另一回事。 这些字段需要最大的灵活性,同时我们希望将XSS和其他攻击的风险降至最低。

这些方面的一个很好的资源是ModSecurity。 这最初是一个Apache模块,但已被Trustwave Spider Labs采用。 它位于Web服务器上,而不是Webapp上,并检查通过它的数据。 最近的端口(2013年夏季)允许使用Servlet过滤器而不是外部反向代理来进行设置。 (它使用JNI来检测包含的应用服务器。)

  • 有关更多信息,请参见ModSecurity for Java 。
参考: 检查您的REST参数! 来自Invariant Properties博客的JCG合作伙伴 Bear Giles。

翻译自: https://www.javacodegeeks.com/2014/01/check-your-rest-parameters.html

检查您的REST参数!相关推荐

  1. php判断参数_php检查函数必传参数是否存在的实例详解

    php检查函数必传参数是否存在的实例详解 在php实际编程中,接口经常会接收到前端传来的参数,其中有些参数不是必传的,有些参数是必传的,如何"检查函数必传参数是否存在"呢?为了解决 ...

  2. python函数参数类型检查_Python中实现参数类型检查的简单方法

    Python是一门弱类型语言,很多从C/C++转过来的朋友起初不是很适应.比如,在声明一个函数时,不能指定参数的类型.用C做类比,那就是所有参数都是void*类型!void类型强制转换在C++中被广泛 ...

  3. 通过Validation框架检查请求参数的基本格式

    通过Validation框架检查请求参数的基本格式 1.1. 添加依赖 Spring Validation框架可用于在服务器端检查请求参数的基本格式(例如是否提交了请求参数.字符串的长度是否正确.数字 ...

  4. 深入理解javascript函数系列第二篇——函数参数

    前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型,甚至可以不传参数.本文是深入理解javascript函数 ...

  5. fusioncompute中cpu可以设置的qos参数有哪些?_kubernetes 中 Qos 的设计与实现

    kubernetes 中的 Qos QoS(Quality of Service) 即服务质量,QoS 是一种控制机制,它提供了针对不同用户或者不同数据流采用相应不同的优先级,或者是根据应用程序的要求 ...

  6. linux脚本外输入参数,shell 脚本中关于用户输入参数的处理

    1.命令行参数 向shell脚本传递数据的最基本方式是使用命令行参数. (1) 读取参数 读取输入的参数的变量为位置参数,位置参数通过标准数字表示, 其中$0为程序名称,$1为第一个参数,$2为第二个 ...

  7. 如何检查Bash中是否设置了变量?

    我如何知道是否在Bash中设置了变量? 例如,如何检查用户是否将第一个参数赋予函数? function a {# if $1 is set ? } #1楼 检查是否设置了变量 var="&q ...

  8. MYSQL连接字符串参数详细解析(大全参考)

    Connector/Net Connection String Options Reference Database=dbname;Data Source=192.168.1.1;Port=3306; ...

  9. python3 函数签名简介 验证函数参数

    一个函数或方法,它使用*args和**kwargs作为参数,这样使得它比较通用, 但有时候你想检查传递进来的参数是不是某个你想要的类型.可以使用函数签名来做验证 函数签名对象,表示调用函数的方式,即定 ...

最新文章

  1. 47. 对数组进行冒泡排序,实现冒泡排序的基础版与优化版
  2. 数组不能将数值传给int_java数组查找常见情况
  3. sql serve 数据库游标的使用
  4. Vue+G2:Please specify the container for the chart! + Cannot read property ‘appendChild‘ of null
  5. 最新互助盘模式_【爆料】“鸿运之都”抢单互助资金盘是“侏罗纪世界”的重启盘,操盘手疯狂抽水几百万马上崩盘!...
  6. 控制DIV内容滚动的方法,实现不用拖滚动条就可以看到最新消息
  7. uiwebview 编辑html5,【iOS】UIWebView HTML5 扩展
  8. A*算法(一)算法导言
  9. linux面试题_2019年常见的Linux面试题及答案解析,哪些你还不会?
  10. Asterisk 11 chan_sip.c: Failed to authenticate device 看不到IP的问题
  11. ipad录屏软件_如何在 Mac 上优雅的截图和录屏
  12. 阿里云SFTP配置方法及故障排查
  13. Softing dataFEED系列--将现场设备集成到西门子工业物联网解决方案
  14. FCSAN存储与服务器关联映射 在Linux系统中如何识别操作
  15. 一个关于家具的横幅广告
  16. 表观转录组学-m6A简介
  17. 迭代器(list迭代器的实现)
  18. 基于DEM的坡度坡向分析
  19. 微信小程序开发实现登陆教程
  20. jsp连接sqlserver数据库

热门文章

  1. cs1.5 linux服务端,Linux下架设CS1.5服务器
  2. mysql外键引用语法_mysql – 外键语法
  3. java内部类选择题_java内部类详解(附相关面试题)
  4. 转:Spring Boot 获取 HttpServletRequest 的方法
  5. 静态工具类注入service的方法
  6. fork/join和线程池_从fork-join /线程池调用的Singelton bean中的访问spring请求范围缓存...
  7. java设计模式适配器模式_Java中的适配器设计模式
  8. red hat 4.1.2_安装Red Hat Container Development Kit 2.2版本
  9. java ee编译器_Java EE 8 MVC:控制器的详细介绍
  10. java ee各类组件_在Java EE组件中使用骆驼路线