当前位置: 首页 > article >正文

Java-web安全01

文章目录

  • 同源策略-跨站攻击
  • 输入处理
    • 字符串标准化
    • 字符编码校验
    • 校验输入值格式
  • 页面显示
    • XSS攻击
      • 场景1
      • 场景2
    • SQL注入
  • 关键处理
    • CSRF攻击
  • 文件处理
    • 目录遍历攻击
    • OS命令注入
    • 文件上传下载漏洞

学习书籍: Web应用安全权威指南

http请求时对于中文参数或者特殊符号是经过URL编码(英文经过URL编码后不变)后才传输,在Java中可用java.net.URLEncoder类进行编码或者解码,URL编码又称百分号编码

百分号编码是将字符以字节为单位转换成 %xx 的形式。xx 为该字节的十六进制写法。参照如下代码示例

 public static void main(String[] args) throws UnsupportedEncodingException {
        System.out.println(URLEncoder.encode("德", "UTF-8"));
        byte[] bytes = "德".getBytes(StandardCharsets.UTF_8);
        System.out.println(bytesToHex(bytes));
    }

    public static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02X", b));
        }
        return result.toString();
    }

同源策略-跨站攻击

协议,host,端口号3个保持一致即为同源策略,JavaScript的跨域访问受到同源策略的严格限制

如果不存在同源策略,使用JavaScript可以在iframe外层访问内层的数据及其危险

可以进行跨域访问的元素

1.frame和iframe元素可以进行跨域访问,X-FRAME-OPTIONS 被定义在响应头信息中用来限制frame和iframe的跨域访问,值为 DENY(拒绝)或 SAMEORIGIN(仅限同源)

2.img元素

3.script元素

4.form元素的action属性—CSRF攻击

5.CSS元素,高版本浏览器一般都有安全补丁已经解决该问题,

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

输入处理

对输入值做如下处理

字符串标准化

Unicode标准允许同一个字符有多种表示形式,显示是一样,但在计算机内部表示不同,避免比较字符串或者搜索操作出现不正确结果,Java中字符串标准化使用Normalizer

String normalized = Normalizer.normalize(input, Normalizer.Form.NFKC);

字符编码校验

1.检验字符编码有效性

2.必要时转换字符编码

3.校验参数字符串的有效性

校验输入值格式

页面显示

XSS攻击

攻击方式:

1.窃取Cookie,document.getCookie

2.篡改网页-更改原先HTML元素,提交数据跳转到新的url

场景1

产生原因:HTML中字符没有被转义

解决办法

1.元素内容中转义<和&

2.属性值用双引号括起来,转义<和"和&

示例:

前端传入”

24
“ 字符串,后台原样输出,页面就不是预期模样

处理办法:

对字符串进行转义处理-建议使用Apache Common-Text库中StringEscapeUtils.escapeHtml4(userInput);

注意点:

1.@RequestParam 传参 和@RequestBody传参 两种方式 在filter过滤写法不同

2.注意对于文件上传下载接口不要进行xssfilter过滤,否则会功能异常.文件上传和下载请求会使用multipart/form-data内容类型,通过这个区分普通请求和文件上传下载请求

代码:

import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class XssFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        if (isMultipartContent(request)) {
            // 对于文件上传请求不做XSS过滤
            filterChain.doFilter(request, response);
        } else {
            // 对其他类型的请求进行XSS过滤
            XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
            filterChain.doFilter(xssRequest, response);
        }
    }

    private boolean isMultipartContent(HttpServletRequest request) {
        String contentType = request.getContentType();
        return contentType != null && contentType.toLowerCase().startsWith("multipart/");
    }
}
import org.apache.commons.lang3.StringEscapeUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import com.alibaba.fastjson.JSON;

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
    public XssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getParameter(String name) {
        return cleanXss(super.getParameter(name));
    }

    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(name);
        if (values == null || values.length == 0) {
            return values;
        }
        String[] cleanValues = new String[values.length];
        for (int i = 0; i < values.length; i++) {
            cleanValues[i] = cleanXss(values[i]);
        }
        return cleanValues;
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final byte[] body = IOUtils.toByteArray(super.getInputStream());
        String jsonBody = new String(body, StandardCharsets.UTF_8);
        if (jsonBody != null && !jsonBody.trim().isEmpty()) {
            jsonBody = cleanJson(jsonBody);
            return new DelegatingServletInputStream(new ByteArrayInputStream(jsonBody.getBytes(StandardCharsets.UTF_8)));
        }
        return super.getInputStream();
    }

    private String cleanXss(String value) {
        if (value == null || value.isEmpty()) {
            return value;
        }
        return StringEscapeUtils.escapeHtml4(value);
    }

    private String cleanJson(String json) {
        JSON parsedJson = JSON.parseObject(json);
        return JSON.toJSONString(parsedJson, (key, object) -> cleanXss(object.toString()));
    }
}
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WebConfig {

    @Bean
    public FilterRegistrationBean<XssFilter> xssFilter() {
        FilterRegistrationBean<XssFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new XssFilter());
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }
}

场景2

利用JavaScript URI”或“JavaScript URL进行的xss攻击

href和src中url路径中

<body>
<a href="javascript:alert(document.cookie)"> 书签 </a>
</body>

解决办法

校验url仅允许http和https协议,属性值也要进行HTML转义

SQL注入

示例:

select * from A where a = ${param},传入 1; select * from users

执行sql为select * from A where a = 1; select * from users,执行了2个sql

产生原因:一部分参数越过了字面量范围

解决办法:防止指定的参数一部分被排除字面量内

占位符–将 值赋给? 的过程叫绑定变量

select * from A where a = ?

占位符分为静态占位符和动态占位符,前者将包含占位符的sql和变量发到数据库引擎后再进行绑定变量

后者在程序内进行包含占位符的sql和变量绑定后得到完整sql再发到数据库引擎中执行

关键处理

CSRF攻击

举例:

用户A登录平台B,A打开恶意网站C不小心执行脚本,网站C带着A在B平台的认证信息去请求平台B如修改密码等等恶意操作

常用解决办法:

CSRF Token 唯一的随机值返回给用户,用户请求时必须携带Token才有效

文件处理

目录遍历攻击

示例:

外界传入文件名"…/…/etc/a.txt"

访问了不该问路径下文件

解决办法:

1.避免由外界指定文件名

2.文件名中不允许包含目录名

3.限定文件名中仅包含字母和数字

4.校验拼接后路径是否允许访问

5.对文件及文件夹设置访问权限

OS命令注入

满足条件:

1.程序内有调用shell函数的地方

2.将外部传入参数传递给调用shell函数

3.参数中shell的元字符没有被转义

解决办法:

上面三条不满足即可

文件上传下载漏洞

示例:

1.上传巨大文件造成Dos攻击

2.上传脚本文件,诱使用户下载恶意文件,伪装恶意文件为html使浏览器里默认执行JavaScript

3.越权下载

4.上传脚本文件,使其在服务器中执行

防范:

1.限制上传文件大小
2.限制上传文件类型,敏感文件避免保存在公开目录
3.校验上传文件真实文件类型(校验文件头),防止修改后缀
4.拼接后路径是否允许访问
5.对文件及文件夹设置访问权限


http://www.kler.cn/a/448330.html

相关文章:

  • c++--------c++概念
  • 分布式协同 - 分布式事务_TCC解决方案
  • 【计算机网络2】计算机网络的性能能指标
  • 常见的哈希函数构造方法
  • 呼入机器人:24小时客户服务的未来趋势
  • 使用vcpkg安装opencv>=4.9后#include<opencv2/opencv.hpp>#include<opencv2/core.hpp>无效
  • Python小游戏开发:实现带道具加成的经典打砖块游戏
  • 【JetPack】WorkManager笔记
  • Java 集合框架中的 List、ArrayList 和 泛型 实例
  • 数据库的范式
  • 学技术学英文:java CyclicBarrier 和 CountDownLatch用法区别,举例生动看完不会忘
  • Unity中通过代码设置材质HDR颜色的方法参考
  • opencv 项目--图像匹配
  • (13)CT137A- 简易音乐盒设计
  • sentinel学习笔记4-SPI 在 Sentinel 中的应用
  • 本地电脑生成SSH公钥私钥对,用于SSH远程连接服务器
  • 【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
  • 泛型(2)
  • 开源!自制一个桌面宠物(STM32CUBEMX HAL库 PWM波 小项目)
  • 在 CUDA C/C++ 中使用共享內存
  • 路径规划之启发式算法之二十一:禁忌搜索算法(Tabu Search,TS)
  • Linux 端口操作
  • 【游戏设计原理】21 - 解谜游戏的设计
  • 【Mac】安装 PaddleOCR
  • springboot java ffmpeg 视频压缩、提取视频帧图片、获取视频分辨率
  • IntelliJ IDEA Docker集成