hibernate規避SQL注入例項
阿新 • • 發佈:2018-12-17
專案被檢測出SQL注入,注入url如:http://127.0.0.1:8080/Test/wlf/getServiceInfo.html?province=%25E6%25B5%2599%25E6%25B1%259F50760358&timeType=1
利用常用SQL注入工具可獲取資料庫詳細情況如下所示:
sqlmap命令:
注入漏洞資訊:
針對SQL注入漏洞,一般的應對方式是在伺服器端加強HTTP請求字元過濾,防範注入攻擊,但這裡是用hibernate作為ORM操作資料庫,更為徹底的方式是引數的處理。先看原來的查詢操作:
public List<ProvinceListVO> getServiceInfo(String province,String timeType) { List<ProvinceListVO> listVO = new ArrayList<ProvinceListVO>(); StringBuffer sb =new StringBuffer(); sb.append("select * from v_wlf_info t where t.province='") .append(province).append("' and time_type='").append(timeType).append("'") .append(" and t.total>0");try { listVO = this.queryByJdbcForBean2(sb.toString(), ProvinceListVO.class); } catch (Exception e) { e.printStackTrace(); } return listVO; }
問題就出在標紅那一行,明明是兩個引數,非得搞成字串,讓人家有機可乘。修改後的程式碼:
public List<ProvinceListVO> getServiceInfo(String province,String timeType) { List<ProvinceListVO> listVO = new ArrayList<ProvinceListVO>(); StringBuffer sb =new StringBuffer(); sb.append("select * from v_wlf_info t where t.province=? and t.time_type=?") // .append(province).append("' and time_type='").append(timeType).append("'") .append(" and t.total>0"); try { listVO = this.queryByJdbcForBean2(sb.toString(), ProvinceListVO.class, province, timeType); } catch (Exception e) { e.printStackTrace(); } return listVO; }
我們看下queryByJdbcForBean2幹了啥:
public <T> List<T> queryByJdbcForBean2(String sql,Class c,final Object... values){ List<T> list= new ArrayList<T>(); Session session = null; try { session = this.getSession(); Query query = this.getSession().createSQLQuery(sql); if (values != null) { for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } } List<Object> rlist = query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list(); for (Object object : rlist) { Map map = (Map) object; T t = (T) Map2BeanUtils.map2Bean(map, c, Map2BeanUtils.DB_COLUMN_TYPE); list.add(t); } } catch (DataAccessResourceFailureException e) { e.printStackTrace(); } catch (HibernateException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); }finally{ if(session != null) this.releaseSession(session); } return list; }
上面使用的是利用setParameter方法來防止在引數上做手腳。