范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

08。如何保证API接口的安全性问题01

  1.互联网Api接口到底如何保证安全性问题?
  2.代码落地实战防御XSS、CSRF攻击
  3.代码落地如何防御接口数据被黑客抓包篡改?
  4.接口数据加密对称还是非对称加密好安全架构设计方案如何防御xss攻击
  XSS攻击通常指的是通过利用 网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括 Java、  VBScript、 ActiveX、 Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。 [1]
  脚本攻击:利用JavaScript 注入 到后台数据库中,在通过展示数据加载该脚本 该脚本中(
  1.使用js获取cookie信息(jwt)
  2.将该jwt数据 上传黑客服务器(ajax)
  )
  获取jwt---用户会话信息 让后模拟请求形式使用该jwt登录。
  xss攻击典型网站:论坛、评论区
  http://127.0.0.1:8080/getUserInfo?userName=
  http://127.0.0.1:8080/getUserInfo?userName=模拟xss攻击
  前端传递 js 脚本到服务器端{   "channel": "",   "equipment": "",   "password": "123456",   "phoneNumber": "15921009758" }
  后端接口将该脚本存放数据库中
  package com.mayikt.main.api.impl;  import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.mayikt.common.core.api.BaseApiService; import com.mayikt.common.core.api.BaseResponse; import com.mayikt.main.api.UserLoginLogService; import com.mayikt.main.api.dto.res.UserLoginLogResDto; import com.mayikt.main.api.impl.entity.SysUserLoginLog; import com.mayikt.main.api.impl.mapper.SysUserLoginLogMapper; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RestController;  import java.util.ArrayList; import java.util.List;  /**  * @ClassName UserLoginLogImpl  */ @RestController @CrossOrigin public class UserLoginLogImpl extends BaseApiService> implements UserLoginLogService {     @Autowired     private SysUserLoginLogMapper sysUserLoginLogMapper;      @Override     public BaseResponse> getUserLoginLog() {         // 模拟查询登录的日志记录         List sysUserLoginLogs = sysUserLoginLogMapper.selectList(new QueryWrapper<>());         List userLoginLogResDtos = new ArrayList<>();         for (int i = 0; i < sysUserLoginLogs.size(); i++) {             UserLoginLogResDto userLoginLogResDto = new UserLoginLogResDto();             BeanUtils.copyProperties(sysUserLoginLogs.get(i), userLoginLogResDto);             userLoginLogResDtos.add(userLoginLogResDto);         }         return setResultSuccessData(userLoginLogResDtos);     } } package com.mayikt.main.api;  import com.mayikt.common.core.api.BaseResponse; import com.mayikt.main.api.dto.res.UserLoginLogResDto; import org.springframework.web.bind.annotation.GetMapping;  import java.util.List;  /**  * @ClassName UserLoginLogService  */ public interface UserLoginLogService {      @GetMapping("/getUserLoginLog")     BaseResponse> getUserLoginLog();  }
  前端html            xss模拟攻击           
  防御xss方式1
  将用户前端所提交的参数进行过滤。
  html 大于> 小于号 <
  <>
  String equipment = loginUserReqDto.getEquipment();         loginUserReqDto.setEquipment(StringUtils.isEmpty(equipment) ? null : StringEscapeUtils.escapeHtml(equipment));         SysUserLoginLog sysUserLoginLog = new SysUserLoginLog(sysUser.getId(), IPUtils.getIpAddr(request),                 new Date(), token,                 loginUserReqDto.getChannel(), loginUserReqDto.getEquipment());
  该方式的缺陷:每个参数都需要像这样写 代码非常冗余
  String str = "";         String s = StringEscapeUtils.escapeHtml(str);         System.out.println(s);
  方式2
  接口接受参数 ?传递参数形式---
  传递参数都是json数据形式
  spring mvc 接受 json数据提供 api回调
  package com.mayikt.main.security;  import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.google.common.net.MediaType; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;  import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.ListIterator;  /**  * 解决post 请求传递json数据 防御xss攻击  */ @Configuration public class WebMvcConfig extends WebMvcConfigurationSupport {      @Override     public void addResourceHandlers(ResourceHandlerRegistry registry) {         registry.addResourceHandler("swagger-ui.html")                 .addResourceLocations("classpath:/META-INF/resources/");          registry.addResourceHandler("/webjars/**")                 .addResourceLocations("classpath:/META-INF/resources/webjars/");     }       @Override     protected void extendMessageConverters(List> messageConverters) {         /**          * 替换默认的MappingJackson2HttpMessageConverter,过滤(json请求参数)xss          */         ListIterator> listIterator = messageConverters.listIterator();         while (listIterator.hasNext()) {             HttpMessageConverter<?> next = listIterator.next();             if (next instanceof MappingJackson2HttpMessageConverter) {                 listIterator.remove();                 break;             }         }         messageConverters.add(getMappingJackson2HttpMessageConverter());      }      public MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() {         // 创建自定义ObjectMapper         SimpleModule module = new SimpleModule();         module.addDeserializer(String.class, new JsonHtmlXssDeserializer(String.class));         ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().applicationContext(this.getApplicationContext()).build();         objectMapper.registerModule(module);         // 创建自定义消息转换器         MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();         mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);         return mappingJackson2HttpMessageConverter;     }  }  /**  * 对入参的json进行转义  */ class JsonHtmlXssDeserializer extends JsonDeserializer {      public JsonHtmlXssDeserializer(Class string) {         super();     }      @Override     public Class handledType() {         return String.class;     }      @Override     public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)             throws IOException, JsonProcessingException {         String value = jsonParser.getValueAsString();         if (!StringUtils.isEmpty(value)) {             return StringEscapeUtils.escapeHtml(value);         }         return value;     } } 抓包如何防止篡改数据Fiddler抓包工具的使用
  1.可以使用第三方抓包工具,对请求前后实现代理,可以修改参数请求内容和参数响应内容,抓包工具http调试工具
  2.Fiddler4下载地址:https://pc.qq.com/detail/10/detail_3330.html
  使用Fiddler4篡改请求之前:
  防御篡改数据
  使用MD5可以直接验证签名参数 MD5 属于单向加密,只能够暴力破解。
  MD5应用场景 在nacos分布式配置中心中,使用MD5 比对文件内容是否发生改变
  HasherPro比对文件内容是否发生改变。
  MD5在线暴力破解地址:https://www.cmd5.com/
  String userName= "123456" ;
  System. out .println( DigestUtils. md5Hex (userName));
  黑客如何破解?自己需要根据参数内容 生成签名
  如果只是改了参数内容---没有用的 所以我们需要该签名
  {"password":"123456","phoneNumber":"phoneNumber","channel":"安卓","equipment":""}
  {sign=325ab041d4889825a46d1e1e802ab5de, timestamp=1652537015771}
  package com.mayikt.main.security;  import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONPObject; import org.apache.commons.codec.digest.DigestUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory;  import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.*;  /**  * 参数验证签名  */ public class SignUtil {      private static Logger logger = LoggerFactory.getLogger(SignUtil.class);      /**      * 加密密钥      */     private final static String APP_KEY = "mykey123456";      public final static String SECRET_KEY = "mysecret123456";      /**      * 字符编码      */     private final static String INPUT_CHARSET = "UTF-8";      /**      * 超时时间      */     private final static int TIME_OUT = 30 * 60 * 1000;      /**      * 请求参数Map转换验证Map      *      * @param requestParams 请求参数Map      * @param charset       是否要转utf8编码      * @return      * @throws UnsupportedEncodingException      */     public static Map toVerifyMap(Map requestParams, boolean charset) {         Map params = new HashMap<>();         for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {             String name = (String) iter.next();             String[] values = requestParams.get(name);             String valueStr = "";             for (int i = 0; i < values.length; i++) {                 valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";             }             // 乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化             if (charset)                 valueStr = getContentString(valueStr, INPUT_CHARSET);             params.put(name, valueStr);         }         return params;     }      /**      * 除去数组中的空值和签名参数      *      * @param sArray 签名参数组      * @return 去掉空值与签名参数后的新签名参数组      */     public static Map paraFilter(Map sArray) {         Map result = new HashMap<>();         if (sArray == null || sArray.size() <= 0) {             return result;         }         for (String key : sArray.keySet()) {             String value = sArray.get(key);             if (value == null || value.equals("") || key.equalsIgnoreCase("sign")) {                 continue;             }             result.put(key, value);         }         return result;     }      /**      * 把数组所有元素排序,并按照"参数=参数值"的模式用"&"字符拼接成字符串      *      * @param params 需要排序并参与字符拼接的参数组      * @return 拼接后字符串      */     public static String createLinkString(Map params) {         return createLinkString(params, false);     }      /**      * 把数组所有元素排序,并按照"参数=参数值"的模式用"&"字符拼接成字符串      *      * @param params 需要排序并参与字符拼接的参数组      * @param encode 是否需要UrlEncode      * @return 拼接后字符串      */     public static String createLinkString(Map params, boolean encode) {         List keys = new ArrayList<>(params.keySet());         Collections.sort(keys);         String prestr = "";         for (int i = 0; i < keys.size(); i++) {             String key = keys.get(i);             String value = params.get(key);             if (encode)                 value = urlEncode(value, INPUT_CHARSET);             if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符                 prestr = prestr + key + "=" + value;             } else {                 prestr = prestr + key + "=" + value + "&";             }         }         return prestr;     }      /**      * 编码转换      *      * @param content      * @param charset      * @return      * @throws UnsupportedEncodingException      */     private static byte[] getContentBytes(String content, String charset) {         if (charset == null || "".equals(charset)) {             return content.getBytes();         }         try {             return content.getBytes(charset);         } catch (UnsupportedEncodingException e) {             throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);         }     }      /**      * 编码转换      *      * @param content      * @param charset      * @return      */     private static String getContentString(String content, String charset) {         if (charset == null || "".equals(charset)) {             return new String(content.getBytes());         }         try {             return new String(content.getBytes("ISO-8859-1"), charset);         } catch (UnsupportedEncodingException e) {             throw new RuntimeException("指定的编码集不对,您目前指定的编码集是:" + charset);         }     }      /**      * URL转码      *      * @param content      * @param charset      * @return      */     private static String urlEncode(String content, String charset) {         try {             return URLEncoder.encode(content, charset);         } catch (UnsupportedEncodingException e) {             throw new RuntimeException("指定的编码集不对,您目前指定的编码集是:" + charset);         }     }       /**      * 生成要请求的签名参数数组      *      * @return 要请求的签名参数数组      */     public static Map signJson(String json) {         // 时间戳加入签名参数组中         HashMap sParaTemp = new HashMap<>();         sParaTemp.put("timestamp", String.valueOf(System.currentTimeMillis()));         // 生成签名结果         String mysign = DigestUtils.md5Hex(getContentBytes(json, INPUT_CHARSET));         // 签名结果加入请求提交参数组中         sParaTemp.put("sign", mysign);         return sParaTemp;     }      public static boolean verifyJson(String json, String sign, String timestamp) {         // 将json数据做一个格式化         JSONObject data = JSONObject.parseObject(json);         // 获得签名验证结果         String mysign = DigestUtils.md5Hex(getContentBytes(json, INPUT_CHARSET));         if (mysign.equals(sign)) {             // 是否超时             long curr = System.currentTimeMillis();             if ((curr - Long.valueOf(timestamp)) > TIME_OUT) {                 logger.info("api is time out");                 return false;             }             return true;         } else {             return false;         }     }      public static void main(String[] args) {         JSONObject jsonObject = new JSONObject();         jsonObject.put("channel", "ios");         jsonObject.put("equipment", "

杨紫私下里还挺嘻哈的,黑色T恤叠穿透视打底,戴墨镜好帅气春天已经到了,那么夏天还会远吗?在夏天里,相信很多人都知道最为常见的服装单品是什么了,那就是T恤。用T恤去搭配自己不仅仅十分清凉,还会打造出非常随性的感觉。所以夏天里T恤可以说是人如何准备季后赛?库里多看录像看不同组合如何碰撞出火花直播吧4月7日讯近日,勇士球星库里参加了播客节目95。7theGame,其中谈到对季后赛的期待。对于核心阵容一起打球时间较少,库里说道我们可以看以往的比赛录像,看看不同的组合能碰撞红极一时如今难以合体的7个组合,有的被队友拖累,有的两败俱伤还有一个多月,Twins就出道21年了。2001年5月18日,在英皇的重金打造之下,阿Sa和阿娇以女子组合的形式出道。一面世就大红大紫,不仅专辑大卖夺得多个大奖,而且广告代言不断,刘雪华优雅老去的样子穿黑色超短连衣裙63岁也照样美丽动人这段时间,拥有琼瑶女神之称的演员刘雪华,在社交平台上发文并晒出一组美照,照片一经发出引来无数网友的热议和关注。从照片中,可以看到已是奔7的刘雪华身穿一袭黑色套装搭配黑色皮靴,第一张手机芯片性能排行榜前3名全是苹果芯,华为麒麟9000排第9对于大部分消费者而言,买手机是一定要看芯片的,也就是Soc,因为它一定程度上就决定了手机的性能,是真正核心的东西。但Soc数量众多,有不同的厂家,也有不同的型号,一般人容易看蒙圈,腾讯旗下游戏电竞直播平台宣布6月7日停运企鹅电竞是腾讯旗下的移动电竞内容平台,为玩家提供移动电竞的一站式体验,手游赛事直播视频内容应有尽有。玩家可以参加官方组织的各级比赛获得荣誉,还有最多的职业选手直播内容与丰富的电竞资韩德君今天又发火了,其实是好事!大韩真着急了,对胜利充满渴望韩德君今天又发火了,其实是好事!大韩真着急了,对胜利充满渴望北京时间2022年4月7日星期四消息。CBA今天进入精彩激烈时刻,14决赛开打。辽宁VS山西,一上来就是重头戏,就是一盘企鹅电竞退市,腾讯仍是最大玩家企鹅电竞退市,野蛮生长下的直播行业也踩下了刹车。4月7日,腾讯旗下的游戏直播平台企鹅电竞发布退市公告,宣布将于2022年6月7日23时59分终止运营,并已于昨日(4月7日)停止新用邢台家长称9岁女儿用华为手机充值游戏8万,为何华为回复拒绝退款养不教父之过,教不严师之惰。却没有想到生生见了河北一老乡的骚操作,打游戏充的钱甩锅到了自己女儿的头上,然后以女儿的名义要求华为赔付。没想到却收到了华为拒绝赔付的消息。不知道这位仁兄一部手机最长可以用几年?遇到以下4种情况,就赶紧换了吧哈喽!大家好,我是小易,欢迎来到我的知识分享站!很多朋友都问一部手机到底能够用几年?其实针对这点行业内没有明确的规定,现在手机的性能越来越完善,用个三四年都不是问题。当然,根据个人魔力乌龟潭乌龟潭因峡谷围绕着一潭形似乌龟的碧水而得名。在太子湾和花港观鱼的附近,是一个外地游客不大来的地方。但,跟太子湾一样,是真正的西湖明珠,是随便你用什么语言来描绘都不为过的地方。一年四
传家聂远成为最大惊喜,他的清醒,打脸无戏可演的演员这段时间,很多的中年男演员无戏可演,而聂远,却出现在很多的热门影视剧中。在于正的电视剧传家中,聂远出演的是大姐夫席维安。这个人物是一个军阀世家,看起来铁血彪悍,实则心细如发。他为了黄晓明离婚后首个父亲节,获儿子祝福视频,意外曝光与杨颖关系饿了吗?戳右边关注我们,每天给您送上最新出炉的娱乐硬核大餐!6月20日,据港媒报道,昨日是黄晓明离婚后首个父亲节,虽然目前儿子小海绵主要由杨颖(Angelababy)照顾,但在父亲首播4小时就拿下飙升榜第二名,悬疑片远山淡影凭啥这么横?今年,国产悬疑剧势头很猛。就这两个月,从影帝王景春和欧豪的对决,到李易峰宋轶的暗夜行者,再到新一届悬疑剧大女主邓家佳和张新成的回廊亭,你放播罢我登场,接连拿下不错的收视和讨论度,就最惨秦明!他曾出演少年的你,但双男主古装探案新剧却最让人期待法医秦明之读心者已经是播出一段时间了,至于这个剧情嘛,真的只能说是见仁见智了,当然了,要说好看的法医秦明系列,那一定是张若昀焦俊艳李现版本,第一部往往是最经典的。法医秦明之读心者的泰国博物馆干尸黄利辉罪恶与倍受争论的一生阅读本文前,麻烦您点击一下关注,既方便您进行讨论与分享,又给您带来不一样的参与感,感谢您的支持!在泰国西里拉吉医院博物馆,有一具注射了福尔马林后干腌的尸体,全身被涂上了蜡层密封,防阿里新规换掉UUID,NanoID更快更安全文章来源httpsc1n。cnWcAl0目录前言了解NanoID及其用法局限性和未来的重点在将来前言UUID是软件开发中最常用的通用标识符之一。然而,在过去的几年里,其他的竞品挑战岚图FREE增程式车型,起售价31。36万,4。5秒破百,配比亚迪电芯电动汽车行业不断发展壮大,量产车型纷纷粉墨登场。今天我们来体验岚图FREE,东风集团旗下中高度电动车品牌岚图的第一款量产车型。岚图FREE是一款中大型SUV,有BEV也有增程式车型程序开发数据库版本控制必备Flyway背景在我们日常产品发布的过程中,代码的版本控制可以使用gitsvn工具实现。对于数据库每当发布时会出现手动执行sql脚本进行升级数据库,中间经常出现一些漏写错写情况,对数据库的版本为何中国不怕苹果停用ApplePay?全球手机支付Top5给你答案最近,苹果遇到了不小的麻烦。一方面,受到苹果对俄断供的影响,不少国内消费者也产生了恐慌,不再敢继续使用苹果设备,甚至不少果粉已经转而使用国产电子设备。另一方面,苹果终于妥协,在荷兰中国电信最新公告5月移动用户数3。81亿中国电信公告,5月移动用户数3。81亿,其中5G套餐用户数2。24亿。截至2022年6月20日收盘,中国电信(601728)报收于3。75元,上涨0。0,换手率1。03,成交量55第五届全球跨境电商节,蚂蚁雄兵助力跨境物流行业合规化建设2022年6月19日,第5届全球跨境电商节展会于深圳市国际跨境电商贸易博览会圆满落幕!深圳市蚂蚁雄兵跨境物流科技有限公司受邀参加展会,展示了为跨境物流行业打造标准化数字化解决方案。