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

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@CrossOriginpublic 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攻击 */@Configurationpublic 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 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”, “alert(‘mayikt’)”); jsonObject.put(“password”, “123456”); jsonObject.put(“phoneNumber”, “phoneNumber”); String json = jsonObject.toJSONString(); System.out.println(json); Map stringStringMap = signJson(json); System.out.println(stringStringMap); }}package com.mayikt.main.security;import com.alibaba.fastjson.JSONObject;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Component;import javax.servlet.*;import javax.servlet.annotation.WebFilter;import javax.servlet.http.HttpServletRequest;import java.io.IOException;import java.io.PrintWriter;@Component@WebFilter()@Slf4jpublic class SignFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 拦截请求,验证json数据 签名 RequestWrapper requestWrapper = new RequestWrapper((HttpServletRequest) request); String json = requestWrapper.getBody(); // 验证token HttpServletRequest req = (HttpServletRequest) request; String sign = req.getHeader(“sign”); String timestamp = req.getHeader(“timestamp”); boolean result = SignUtil.verifyJson(json, sign, timestamp); if (!result) { PrintWriter writer = response.getWriter(); JSONObject data = new JSONObject(); data.put(“code”, “500”); data.put(“msg”, “验证签名失败”); writer.println(data.toJSONString()); writer.close(); return; } chain.doFilter(requestWrapper, response); } @Override public void destroy() { }}package com.mayikt.main.security;import lombok.extern.slf4j.Slf4j;import javax.servlet.ReadListener;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStreamReader;@Slf4jpublic class RequestWrapper extends HttpServletRequestWrapper { private final String body; // 报文 public RequestWrapper(HttpServletRequest request) throws IOException { super(request); BufferedReader streamReader = new BufferedReader( new InputStreamReader(request.getInputStream(), “UTF-8”)); StringBuilder responseStrBuilder = new StringBuilder(); String inputStr; while ((inputStr = streamReader.readLine()) != null) { responseStrBuilder.append(inputStr); } body = responseStrBuilder.toString(); log.info(“body:{}”, body); } public String getBody() { return body; } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream bais = new ByteArrayInputStream(body.getBytes(“utf-8”)); return new ServletInputStream() { @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) { } @Override public int read() throws IOException { return bais.read(); } }; }}

相关代码

m5.rar

郑重声明:本文内容及图片均整理自互联网,不代表本站立场,版权归原作者所有,如有侵权请联系管理员(admin#wlmqw.com)删除。
用户投稿
上一篇 2022年7月21日 09:46
下一篇 2022年7月21日 09:46

相关推荐

  • 短视频策划内容的3个要点(短视频策划内容怎么做)

    短视频在制作时,内容框架非常重要。如果直奔主题,然后结束,聚卓告诉你,这样的短视频已经过时了。现在的短视频需要框架的,但不是任何框架,它需要一种易于理解和消化的框架。而且,现在大多…

    2022年11月27日
  • 存储过程语法(sql server存储过程语法)

    今天小编给各位分享存储过程语法的知识,其中也会对sql server存储过程语法进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧! oracle存储过程基本语法…

    2022年11月26日
  • 小红书平台的一些机制及玩法详解(小红书玩法有哪些)

    关于小红书 一:小红书平台的一些机制 1. 笔记内容的CES评分机制 2. 笔记流量入口与长尾效应 二:小红书优质笔记的特点(分维度、类型分析) 1.笔记的本身架构组成 维度 2.…

    2022年11月25日
  • 什么是推广cpa一篇文章带你看懂CPA推广渠道

    CPA渠道 CPA指的是按照指定的行为结算,可以是搜索,可以是注册,可以是激活,可以是搜索下载激活,可以是绑卡,实名认证,可以是付费,可以是浏览等等。甲乙双方可以根据自己的情况来定…

    2022年11月25日
  • 博客营销的3大优势解析(博客营销怎么做)

    不知不觉已经写了24篇文章,加上这篇是第25篇了,都是自己这几年来用过的营销方法,如果遇到有些不懂的,我会咨询我的朋友和同事帮忙,尽量让每一篇有价值,哪怕是对大家有一点点帮助也行,…

    2022年11月25日
  • 什么是内容营销策略如何策划一套成功的内容营销策略

    很多时候,营销人员会在创作营销内容时感到沮丧,这也是很多企业至今没用好数字化营销工具的重要原因之一。 举个例子,您可能会花上数小时期待制作一些令人惊叹的东西,实际却是得到很少的受众…

    2022年11月25日
  • 直播带货详细脚本(直播文案策划怎么写)

    短视频运营策划方案怎么写?涉及哪几个方面? 我在网上看到好多千篇一律的文章,关于【短视频运营策划方案】这一块,基本都是在讲账号的内容本身。 你内容做得再好,却不掌握算法的规律,能有…

    2022年11月25日
  • 闲鱼上怎么卖东西快?闲鱼赚钱必知技巧(怎么在闲鱼里面卖东西)

    自从闲鱼这个平台出现以后,随着这些年的发展,闲鱼也成为了很多人开店赚钱的重要途径。一些新人也想在闲鱼上试试水,看看能不能赚到钱。如今闲鱼上既可以卖二手闲置物品,也可以卖一些新品,那…

    2022年11月25日
  • 抖音直播带货有哪些方法技巧(抖音直播带货有哪些痛点)

    如今抖音这个短视频的变现能力越来越突显了,尤其是在平台上开通直播,更具有超强的带货属性,已经有越来越多的普通人加入到其中了。不过直播带货虽然很火,但是也不是每个人都能做好的,那么在…

    2022年11月24日
  • 淘宝直播带货技巧分享(淘宝直播复制粘贴技巧)

    淘宝是大家喜欢的购物平台,不少人会自己在淘宝选购,也会在主播直播间购买,价格更实惠,现在很多商家都会开通直播带货功能,增加订单量,那么淘宝直播带货有哪些?下面小编为大家带来淘宝直播…

    2022年11月24日

联系我们

联系邮箱:admin#wlmqw.com
工作时间:周一至周五,10:30-18:30,节假日休息