From c1078242e199cad1c61de116142e3897c5de1d7b Mon Sep 17 00:00:00 2001 From: dushitaoyuan Date: Mon, 4 May 2020 23:35:22 +0800 Subject: [PATCH] fix:bug --- Readme.md | 24 +++++++++---------- pom.xml | 7 +++--- .../securitydemo/config/GlobalConfig.java | 12 +++++++--- .../controller/BussinessController.java | 16 ++++++------- .../TokenAuthHandlerIntercepter.java | 2 +- .../ratelimit/AbstractRateLimiter.java | 22 ++++++++++------- .../security/ratelimit/GuavaRateLimiter.java | 16 ++++++------- src/main/resources/application.properties | 14 ----------- .../SecurityDemoApplicationTests.java | 2 +- 9 files changed, 55 insertions(+), 60 deletions(-) diff --git a/Readme.md b/Readme.md index b13e655..ca82d6d 100644 --- a/Readme.md +++ b/Readme.md @@ -2,55 +2,55 @@ ## 常见漏洞及解决方案 -1. sql 注入 +- sql 注入 解决方案:参数检测,拦截非法入参,后端使用druid 连接池的sql防火墙 参见:com.taoyuanx.securitydemo.web -2. xss攻击 +- xss攻击 解决方案:参数检测,拦截非法入参,转义html字符,参见com.taoyuanx.securitydemo.web -3. 跨站请求 +- 跨站请求 解决方案:设置允许跨站的header信息 -4. 文件,图片等非站内请求 +- 文件,图片等非站内请求 解决方案:防盗链处理(Http Rerfer头部,nginx可设置) -5. 接口暴力访问 +- 接口暴力访问 解决方案:系统限流,全局限流,单个ip限流,黑名单等,参见:com.taoyuanx.securitydemo.security.RateLimitAspect,com.taoyuanx.securitydemo.web.BlackListFilter -7. 文件未授权访问 +- 文件未授权访问 解决方案:上传的文件,展示时后端返回签名的文件,访问时,走一次后端,方便做权限验证,参见,/api/upload,/api/file 文件存储时,去除可执行权限,尽量和应用服务器进行物理隔离 -8. 文件不安全类型上传 +- 文件不安全类型上传 解决方案:校验文件类型,校验流信息,校验文件真实类型,参见/api/upload -9. 密码泄露风险 +- 密码泄露风险 密码加密传输,参见login.html -10. 越权访问 +- 越权访问 解决方案:权限控制,参见SimpleAuthHandlerIntercepter 如果通过tomcat发布静态文件,可通过过滤器禁止非授权访问,如采用其他静态资源服务器,可严格控制后台权限,保证数据不被越权访问 ,静态资源越权访问,可通过client端js控制location -11. 中间人攻击 +- 中间人攻击 解决方案:采用https协议,参数签名,返回值签名,防止参数或返回值被篡改 -12. slowhttp 攻击 +- slowhttp 攻击 -解决方案:限制恶意访问,有钱的买防护工具,(阿里云盾,知道创宇等),没钱的多部署几台机器,修改连接超时时间,事后分析ip,封禁 +解决方案:限制恶意访问,有钱的买防护工具,(阿里云盾,知道创宇等),没钱的多部署几台机器,修改连接超时时间,事后分析非法ip封禁, 协议漏洞,没啥好防护的策略,没钱的事后防范吧 diff --git a/pom.xml b/pom.xml index c74d927..2157989 100644 --- a/pom.xml +++ b/pom.xml @@ -6,13 +6,12 @@ org.springframework.boot spring-boot-starter-parent 2.1.7.RELEASE - + com.taoyuanx - security-demo + javaweb_security_handle 0.0.1-SNAPSHOT - security-demo - java security demo + javaweb_security_handle UTF-8 diff --git a/src/main/java/com/taoyuanx/securitydemo/config/GlobalConfig.java b/src/main/java/com/taoyuanx/securitydemo/config/GlobalConfig.java index abb0298..c6fd5d3 100644 --- a/src/main/java/com/taoyuanx/securitydemo/config/GlobalConfig.java +++ b/src/main/java/com/taoyuanx/securitydemo/config/GlobalConfig.java @@ -1,6 +1,7 @@ package com.taoyuanx.securitydemo.config; import com.taoyuanx.securitydemo.security.ratelimit.AbstractRateLimiter; +import com.taoyuanx.securitydemo.security.ratelimit.GuavaRateLimiter; import com.taoyuanx.securitydemo.security.ratelimit.RedisRateLimiter; import com.taoyuanx.securitydemo.utils.RSAUtil; import lombok.Data; @@ -62,13 +63,18 @@ public class GlobalConfig implements InitializingBean { * @param redisTemplate * @return */ - @Bean + /* @Bean @Autowired - public AbstractRateLimiter rateLimiter(StringRedisTemplate redisTemplate) { + public AbstractRateLimiter redisRateLimiter(StringRedisTemplate redisTemplate) { RedisRateLimiter redisRateLimiter = new RedisRateLimiter(redisTemplate); return redisRateLimiter; - } + }*/ + @Bean + public AbstractRateLimiter guavaRateLimiter() { + GuavaRateLimiter guavaRateLimiter = new GuavaRateLimiter(); + return guavaRateLimiter; + } @Override public void afterPropertiesSet() throws Exception { diff --git a/src/main/java/com/taoyuanx/securitydemo/controller/BussinessController.java b/src/main/java/com/taoyuanx/securitydemo/controller/BussinessController.java index a859409..d8e1e1c 100644 --- a/src/main/java/com/taoyuanx/securitydemo/controller/BussinessController.java +++ b/src/main/java/com/taoyuanx/securitydemo/controller/BussinessController.java @@ -158,11 +158,7 @@ public class BussinessController { } - /** - * 登录安全控制 - * - * @return - */ + @PostMapping("loginOut") @ResponseBody public void loginOut(HttpServletResponse response, HttpServletRequest request) throws Exception { @@ -171,7 +167,7 @@ public class BussinessController { } /** - * 黑名单测试 + * 文件上传 * * @return */ @@ -206,9 +202,11 @@ public class BussinessController { public void upload(HttpServletRequest request, HttpServletResponse response) throws Exception { fileHandler.handleFile(response, request); } - @RateLimit(type = RateLimitType.TOTAL_COUNT,key = "rate_count",totalCount = 100) + @RateLimit(type = RateLimitType.TOTAL_COUNT,key = "rate_count",totalCount = 10) @GetMapping("rate_count") - public void rateCount(int index) throws Exception { - System.out.println("rate_count\t"+index); + @ResponseBody + public Result rateCount() throws Exception { + System.out.println("rate_count\t"); + return ResultBuilder.success("ok"); } } diff --git a/src/main/java/com/taoyuanx/securitydemo/interceptor/TokenAuthHandlerIntercepter.java b/src/main/java/com/taoyuanx/securitydemo/interceptor/TokenAuthHandlerIntercepter.java index db11412..ac9ed19 100644 --- a/src/main/java/com/taoyuanx/securitydemo/interceptor/TokenAuthHandlerIntercepter.java +++ b/src/main/java/com/taoyuanx/securitydemo/interceptor/TokenAuthHandlerIntercepter.java @@ -69,7 +69,7 @@ public class TokenAuthHandlerIntercepter implements HandlerInterceptor { } Map tokenData = toeknHelper.vafy(token); Long tokenAccountId = toeknHelper.getAccountId(tokenData); - if (tokenAccountId != accountId) { + if (!tokenAccountId.equals(accountId) ) { return false; } diff --git a/src/main/java/com/taoyuanx/securitydemo/security/ratelimit/AbstractRateLimiter.java b/src/main/java/com/taoyuanx/securitydemo/security/ratelimit/AbstractRateLimiter.java index 475d661..7c90a47 100644 --- a/src/main/java/com/taoyuanx/securitydemo/security/ratelimit/AbstractRateLimiter.java +++ b/src/main/java/com/taoyuanx/securitydemo/security/ratelimit/AbstractRateLimiter.java @@ -4,7 +4,6 @@ package com.taoyuanx.securitydemo.security.ratelimit; * @author dushitaoyuan * @desc 抽象限流 * @date 2019/9/5 - * */ public abstract class AbstractRateLimiter { @@ -16,20 +15,27 @@ public abstract class AbstractRateLimiter { * @param limit 限流速率 * @return */ - public boolean tryAcquire(String key, Double limit){ - return doTryAcquire(1,key,limit); + public boolean tryAcquire(String key, Double limit) { + return doTryAcquire(1, key, limit); } + /** + * @param permits 申请令牌数量 + * @param key 限流标识 + * @param limit 速率 + * @return + */ public abstract boolean doTryAcquire(int permits, String key, Double limit); /** - * 增加资源访问次数 用户可自行持久化记录 - * @param count - * @param key - * @param totalCount + * 增加资源访问次数 用户可自行持久化记录 + * @param count (申请资源数量) + * @param key (资源key) + * @param totalCount (资源总量) * @return */ - public abstract boolean tryCount(int count,String key,Long totalCount); + public abstract boolean tryCount(int count, String key, Long totalCount); + } diff --git a/src/main/java/com/taoyuanx/securitydemo/security/ratelimit/GuavaRateLimiter.java b/src/main/java/com/taoyuanx/securitydemo/security/ratelimit/GuavaRateLimiter.java index 799391f..fb7df47 100644 --- a/src/main/java/com/taoyuanx/securitydemo/security/ratelimit/GuavaRateLimiter.java +++ b/src/main/java/com/taoyuanx/securitydemo/security/ratelimit/GuavaRateLimiter.java @@ -42,6 +42,9 @@ public class GuavaRateLimiter extends AbstractRateLimiter { @Override public boolean tryCount(int count, String key, Long totalCount) { + if (count > totalCount) { + return false; + } //标记后,直接返回false if (TOTAL_LIMIT_ZERO_FLAG.mightContain(key)) { return false; @@ -53,18 +56,15 @@ public class GuavaRateLimiter extends AbstractRateLimiter { LongAdder longAdder = null; if (countHolder.containsKey(key)) { longAdder = countHolder.get(key); - longAdder.add(-count); - //资源总数用完后,标记 - if (longAdder.longValue() <= 0) { + if (longAdder.longValue() >=totalCount) { TOTAL_LIMIT_ZERO_FLAG.put(key); countHolder.remove(key); - return true; + return false; } - return false; - } - if (count > totalCount) { - return false; + longAdder.add(count); + return true; } + longAdder = new LongAdder(); countHolder.putIfAbsent(key, longAdder); countHolder.get(key).add(count); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8adb1cd..041dee5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,17 +1,3 @@ - -#数据库连接池 -#spring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true -#spring.datasource.username:root -#spring.datasource.password:root -#spring.datasource.driver-class-name=com.mysql.jdbc.Driver -#spring.datasource.type=com.alibaba.druid.pool.DruidDataSource -#spring.datasource.initialSize=10 -#spring.datasource.minIdle=10 -#spring.datasource.maxActive=100 -#spring.datasource.maxWait=60000 -#spring.datasource.timeBetweenEvictionRunsMillis=60000 -#spring.datasource.filters=wall - spring.profiles.active=@profiles.active@ spring.redis.database=2 diff --git a/src/test/java/com/taoyuanx/securitydemo/SecurityDemoApplicationTests.java b/src/test/java/com/taoyuanx/securitydemo/SecurityDemoApplicationTests.java index 25ec02e..23bef84 100644 --- a/src/test/java/com/taoyuanx/securitydemo/SecurityDemoApplicationTests.java +++ b/src/test/java/com/taoyuanx/securitydemo/SecurityDemoApplicationTests.java @@ -34,7 +34,7 @@ public class SecurityDemoApplicationTests { public void reateLimitCount() throws Exception { int batch=101; for(int i=0;i