很久没有写博客了,这两天遇到一个关于url编码的问题,作一个记录 java
需求是这样的;spring
系统遭受不法人员攻击,老大系统系统写一个过滤器,当有安全攻击的时候,直接经过配置的方式禁止该接口的使用浏览器
原本觉得很简单 ,直接写了一个定时加载的功能,读取配置,而后与请求过来的url进行对比便可,用浏览器测试都没有问题,可是通过安全的时候,问题来了,在浏览器中会url自动的解析,可是在当在抓起工具中输入如下地址,仍然能请求道相应的请求,安全
/product/./queryChannelProductInfo
/product/123/../queryChannelProductInfo
/product%2fqueryChannelProductInfo服务器
从表面现象能够看出,服务器底层还有一个层与浏览器作了一样的规则处理 mvc
一开始处理的方式 , 获取器Dispatcher,经过反射而后获取器url,而后在进行比较 app
RequestDispatcher dispatcher = arg0.getRequestDispatcher(reqUrl); @SuppressWarnings("deprecation") Field path = arg0.getRequestDispatcher(URLDecoder.decode(reqUrl)).getClass().getDeclaredFields()[16]; path.setAccessible(true); path.get(dispatcher); String dispatcherUrl =(String) path.get(dispatcher); if (new AntPathMatcher().match(strUrl,dispatcherUrl)) { logger.warn(reqUrl + "have no authority for rquest"); return; }
这种方法解决了./ ../这种方式,可是url编码的格式仍然能够绕过 框架
一时分析,框架用的是springmvc 应该是在内容的处理致使的 ,因而开始分析spring mvc 的源码 async
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { try { ModelAndView mv = null; Exception dispatchException = null; try { processedRequest = this.checkMultipart(request); multipartRequestParsed = processedRequest != request; mappedHandler = this.getHandler(processedRequest, false); if (mappedHandler == null || mappedHandler.getHandler() == null) { this.noHandlerFound(processedRequest, response); return; } ...... }
@Deprecated protected HandlerExecutionChain getHandler(HttpServletRequest request, boolean cache) throws Exception { return this.getHandler(request); } protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { Iterator i$ = this.handlerMappings.iterator(); HandlerExecutionChain handler; do { if (!i$.hasNext()) { return null; } HandlerMapping hm = (HandlerMapping)i$.next(); if (this.logger.isTraceEnabled()) { this.logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name '" + this.getServletName() + "'"); } handler = hm.getHandler(request); } while(handler == null); return handler; }
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { Object handler = getHandlerInternal(request); if (handler == null) { handler = getDefaultHandler(); } if (handler == null) { return null; } if (handler instanceof String) { String handlerName = (String) handler; handler = getApplicationContext().getBean(handlerName); } return getHandlerExecutionChain(handler, request); }
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) { HandlerExecutionChain chain = new HandlerExecutionChain(handler); chain.addInterceptors(getAdaptedInterceptors()); String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); for (MappedInterceptor mappedInterceptor : this.mappedInterceptors) { if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) { chain.addInterceptor(mappedInterceptor.getInterceptor()); } } return chain; }