互联网并发与安全系列教程(05) - 常见的Web安全漏洞(XSS攻击、SQL注入、防盗链)

1. XSS攻击

XSS攻击使用Javascript脚本注入进行攻击
例如在提交表单后,展示到另一个页面,可能会受到XSS脚本注入,读取本地cookie远程发送给黑客服务器端。

<script>alert('sss')</script>
<script>window.location.href='http://www.xxx.com';</script>

对应html源代码:

&lt;script&gt;alert('sss')&lt;/script&gt;
1.1 如何防御XSS攻击?

将脚本特殊字符,转换成html源代码进行展示。

汉字编码:http://www.mytju.com/classcode/tools/encode_gb2312.asp

步骤:编写过滤器拦截所有getParameter参数,重写httpservletwrapp方法
将参数特殊字符转换成html源代码保存。

// 重写HttpServletRequestWrapper 防止XSS攻击
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
	private HttpServletRequest request;

	/**
	 * @param request
	 */
	public XssHttpServletRequestWrapper(HttpServletRequest request) {
		super(request);
		this.request = request;
	}

	@Override
	public String getParameter(String name) {
		// 过滤getParameter参数 检查是否有特殊字符
		String value = super.getParameter(name);
		System.out.println("value:" + value);
		if (!StringUtils.isEmpty(value)) {
			// 将中文转换为字符编码格式,将特殊字符变为html源代码保存
			value = StringEscapeUtils.escapeHtml(value);
			System.out.println("newValue:" + value);
		}
		return value;
	}

}

SpringBoot启动加上 @ServletComponentScan:

@SpringBootApplication
@ServletComponentScan
public class App {

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}

}

2. SQL注入攻击

SQL注入指的是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库执行一些恶意的操作作。

造成SQL注入的原因是因为程序没有有效过滤用户的输入,使攻击者成功的向服务器提交恶意的SQL查询代码,程序在接收后错误的将攻击者的输入作为查询语句的一部分执行,导致原始的查询逻辑被改变,额外的执行了攻击者精心构造的恶意代码。

2.1 如何防御SQL注入?

不要使用拼接SQL语句方式、最好使用预编译方式,在mybatis编写sql语句的时候,最好使用?传参数方式,不要使用#传参数,因为#传参数方式,可能会受到sql语句攻击。

演示案例:
http://127.0.0.1:8080/login?userName=‘liusi’&password=‘123’
http://127.0.0.1:8080/login?userName=‘liusi’&password=‘123’ or 1=1

@RestController
public class LoginController {
	@Autowired
	private UserMapper userMapper;

	@RequestMapping("/login")
	public String login(UserEntity userEntity) {
		System.out.println("账号密码信息:userEntity:" + userEntity.toString());
		UserEntity login = userMapper.login(userEntity);
		return login == null ? "登陆失败!" : "登陆成功!";
	}

}

public interface UserMapper {

	@Select(" SELECT  * FROM user_info where userName=${userName} and password=${password}")
	public UserEntity login(UserEntity userEntity);

}

3.MyBatis #与?区别

  • #{}: 解析为一个 JDBC 预编译语句(prepared statement)的参数标记符,一个 #{ } 被解析为一个参数占位符,可以防止SQL注入问题。
  • ${}: 仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换。

3. HTTP请求防盗链

比如A网站有一张图片,被B网站直接通过img标签属性引入,直接盗用A网站图片展示。

3.1 如何防御防盗链?

判断http请求头Referer域中的记录来源的值,如果和当前访问的域名不一致的情况下,说明该图片可能被其他服务器盗用。

代码实现:

@WebFilter(filterName = "imgFilter", urlPatterns = "/imgs/*")
public class ImgFilter implements Filter {

	@Value("${domain.name}")
	private String domainName;

	public void init(FilterConfig filterConfig) throws ServletException {

	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		String referer = req.getHeader("Referer");
		if (StringUtils.isEmpty(referer)) {
			request.getRequestDispatcher("/imgs/error.png").forward(request, response);
			return;
		}
		String domain = getDomain(referer);
		if (!domain.equals(domainName)) {
			request.getRequestDispatcher("/imgs/error.png").forward(request, response);
			return;
		}
		chain.doFilter(request, response);
	}

	/**
	 * 获取url对应的域名
	 *
	 * @param url
	 * @return
	 */
	public String getDomain(String url) {
		String result = "";
		int j = 0, startIndex = 0, endIndex = 0;
		for (int i = 0; i < url.length(); i++) {
			if (url.charAt(i) == '/') {
				j++;
				if (j == 2)
					startIndex = i;
				else if (j == 3)
					endIndex = i;
			}

		}
		result = url.substring(startIndex + 1, endIndex);
		return result;
	}

	public void destroy() {

	}
}

总结

在这里插入图片描述

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值