记录一下网站上线后的(狗屎)相关安全检测报告问题(持续更新)

前言:最近负责维护和迭代一套信息发布平台的网站,这些网站呢,属于一些学校或者是机构下面在使用,可能是为了某些需要吧,时不时的反馈一下操蛋的安全漏洞上的问题,这里整理罗列了一些出来,方便以后查找,毕竟,好记性不如烂笔头

1、一些不知道算不算漏洞的漏洞,反正看着很紧急

1.1、检测到目标站点存在javascript框架库漏洞

处理:将jquery版本升级到最新的版本

1.2、jQuery 存在 XSS 漏洞

处理:将jquery版本升级到最新的版本,同时通过隐藏jquery版本号的形式进行处理

2、Nginx上代理配置漏洞

分别是:

  • 检测到目标X-Content-Type-Options响应头缺失
  • 检测到目标X-XSS-Protection响应头缺失
  • 检测到目标Content-Security-Policy响应头缺失
  • 检测到目标X-Permitted-Cross-Domain-Policies响应头缺失
  • 检测到目标X-Download-Options响应头缺失
  • 检测到目标Strict-Transport-Security响应头缺失

看看,这不看不知道,原来网络上还有这些请求头配置,好在,这些都可以在Nginx上配置解决,Nginx配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
location / {
。。。。
## nginx代理配置
。。。。

# 相关安全漏洞响应头
# 检测到目标 X-Content-Type-Options响应头缺失 这个暂时不开启,不然部分banner无法使用
#add_header X-Content-Type-Options "nosniff";
# 检测到目标 X-XSS-Protection响应头缺失
add_header X-XSS-Protection "1; mode=block";
# 检测到目标 Content-Security-Policy响应头缺失
add_header Content-Security-Policy "default-src 'self' http: https://* data: blob: 'unsafe-eval' 'unsafe-inline';child-src 'none' " always;
# 检测到目标 Referrer-Policy响应头缺失
add_header Referrer-Policy "no-referrer-when-downgrade" always;
# 检测到目标 X-Permitted-Cross-Domain-Policies响应头缺失
add_header X-Permitted-Cross-Domain-Policies none;
# 检测到目标 X-Download-Options响应头缺失
add_header X-Download-Options noopen;
# 检测到目标 Strict-Transport-Security响应头缺失
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
}

3、Tomcat相关配置漏洞提示

3.1、检测到Apache Tomcat应用服务器后台管理程序

这种是在Tomcatwebapps文件中除了ROOT文件还有别的文件导致的,因此删除非ROOT文件夹的所有文件夹即可,如:

图片中所有框选的文件夹都删除掉,只留ROOT文件夹

image-20220707154242171

4、Web服务漏洞

4.1、HTML 表单没有 CSRF 保护

这种是网站与服务端通信时没有进行安全校验的一种漏洞,此漏洞有两种解决方案:

  • 基于过滤器Filter来实现,过滤当前请求进来的网络请求是否是允许访问的请求

    • 如果项目安全框架使用的是SpringSecurity,security默认开启了CSRF保护,如果禁用了,查找如下代码删除或注视掉接口,因为有些security配置时喜欢禁用CSRF保护

      1
      http.csrf().disable();
    • 如果项目安全框架使用的是Apache Shiro,需要通过如下配置实现CSRF保护

      • 1、创建如下Filter

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        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;
        import java.util.Arrays;
        import java.util.Collection;
        import java.util.HashSet;

        public class CsrfFilter extends OncePerRequestFilter {
        private Collection<String> domains = new HashSet<>();

        public CsrfFilter(Collection<String> domains) {
        this.domains = domains;
        }

        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // GET 等方式不用提供Token,自动放行,不能用于修改数据。修改数据必须使用 POST、PUT、DELETE、PATCH 方式并且Referer要合法。
        if (Arrays.asList("GET", "HEAD", "TRACE", "OPTIONS").contains(request.getMethod()) || domains.isEmpty()) {
        filterChain.doFilter(request, response);
        return;
        }
        // 从 HTTP 头中取得 Referer 值
        String referer = request.getHeader("Referer");
        // 判断 Referer 是否以 合法的域名 开头。
        if (referer != null) {
        // 如 http://mysite.com/abc.html https://www.mysite.com:8080/abc.html
        if (referer.indexOf("://") > 0) {
        referer.substring(referer.indexOf("://") + 3);
        }
        // 如 mysite.com/abc.html
        if (referer.indexOf("/") > 0) {
        referer.substring(0, referer.indexOf("/"));
        }
        // 如 mysite.com:8080
        if (referer.indexOf(":") > 0) {
        referer.substring(0, referer.indexOf(":"));
        }
        // 如 mysite.com
        for (String domain : domains) {
        if (referer.endsWith(domain)) {
        filterChain.doFilter(request, response);
        return;
        }
        }
        }
        response.sendError(HttpServletResponse.SC_FORBIDDEN, "CSRF Protection: Referer Illegal");
        }
        }

      • 2、将创建的Filter配置在Shiro框架下

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        /**
        * 配置CSRF保护
        * 获取项目配置文件下是否有csrf.domains拦截配置,如果有,则进行拦截配置地址,如果没有
        */
        @Bean
        public FilterRegistrationBean csrfFilter() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        String csrfDomains = properties().getProperty("csrf.domains");
        if (StringUtils.isNotBlank(csrfDomains)) {
        filterRegistration.setFilter(new CsrfFilter(Arrays.asList(csrfDomains.split(","))));
        } else {
        filterRegistration.setFilter(new CsrfFilter(Collections.<String>emptyList()));
        }
        filterRegistration.setEnabled(true);
        filterRegistration.addUrlPatterns("/*");
        return filterRegistration;
        }
      • 项目环境配置下的CSRF地址:

        1
        2
        # csrf referer 验证。填写允许的域名,如www.mysite.com,localhost,127.0.0.1。多个域名用逗号分隔,填写顶级域名则次级域名均允许访问(如mysite.com,则abc.mysite.com、www.mysite.com都可以访问)。为空则不开启。
        csrf.domains=
    • 其他语言请查阅相关技术框架的配置

  • 基于身份令牌的形式进行安全校验

5、Cookie中缺少Secure属性

如果使用nginx

1
2
3
4
5
6
7
# nginx.conf 文件中设置 http{ } 或 server{ }
add_header Set-Cookie "HttpOnly";
add_header Set-Cookie "Secure";

// 貌似这种方式需要结合HTTPS证书使用才行
proxy_cookie_path / "/; httponly; secure; SameSite=Lax";

如果是Tomcat,在web.xml文件中添加如下配置:

1
2
3
4
5
<session-config>
<cookie-config>
<secure>true</secure>
</cookie-config>
</session-config>

6、Cookie 没有 HttpOnly 标志设置

在 Tomcat 8.0 及以上版本中,你可以通过修改 context.xml 文件来设置全局的 Cookie 属性。在 context.xml 文件中,找到 <Context> 元素,然后添加 useHttpOnly="true" 属性。

示例:

1
2
3
4
<Context useHttpOnly="true">
<!-- 其他配置项 -->
</Context>

配置后重启服务,即可在浏览器控制台中看见HttpOnly打钩了

image-20240112170755146

如果你只想为特定的 Cookie 添加 HttpOnly 标志,而不是全局设置,你可以在代码中手动设置 Cookie 的属性。

示例(Java Servlet):

1
2
3
Cookie cookie = new Cookie("cookieName", "cookieValue");
cookie.setHttpOnly(true);
response.addCookie(cookie);

示例(JSP):

1
2
3
4
5
<%
Cookie cookie = new Cookie("cookieName", "cookieValue");
cookie.setHttpOnly(true);
response.addCookie(cookie);
%>

通过以上方法,你可以确保 Tomcat 在发送响应时为 Cookie 添加 HttpOnly 标志。这有助于减少跨站点脚本攻击(XSS)的风险,提高应用程序的安全性。

请注意,修改 Tomcat 的配置文件或代码时,建议在生产环境之前进行充分的测试,以确保没有引入其他问题或影响现有功能。

7、HTML 表单没有 CSRF 保护

8、跨站脚本 (content-sniffing)

跨站脚本(XSS)中的另一种变体是内容嗅探(Content Sniffing)漏洞。内容嗅探漏洞发生在浏览器尝试解析和显示响应内容时,如果服务器未正确设置响应的内容类型(Content-Type),浏览器可能会根据内容的实际格式进行猜测。这种猜测可能导致浏览器错误地将内容解析为不同的类型,从而引发安全问题。

内容嗅探漏洞的修复方法包括以下几点:

  1. 设置正确的 Content-Type:确保服务器在响应中正确设置适当的 Content-Type 头部。根据内容的实际类型,明确指定正确的 MIME 类型,例如 text/html、application/json、image/png 等。这样可以帮助浏览器正确解析和处理响应内容。
  2. 禁用内容嗅探:通过设置 X-Content-Type-Options 头部为 nosniff,可以告诉浏览器不要进行内容嗅探,严格按照服务器指定的 Content-Type 解析内容。这可以防止浏览器错误地解析和执行恶意内容。
  3. 限制可执行内容:对于用户提供的内容,如文件上传功能,进行严格的验证和过滤,确保只接受符合预期的文件类型,并对上传的文件进行适当的处理和限制。这可以防止恶意文件被误解析和执行。
  4. 安全的编码和解析:在编写和解析代码时,遵循安全的编码实践。对于用户输入的内容,进行适当的编码和转义,以防止恶意内容的执行。使用安全的解析库和函数,避免使用不安全的解析方法。
  5. 安全审计和漏洞扫描:定期进行安全审计和漏洞扫描,以发现和修复潜在的内容嗅探漏洞和其他安全问题。及时更新和修复发现的漏洞,确保应用程序的安全性。

需要注意的是,内容嗅探漏洞是一种浏览器行为,而不是应用程序本身的漏洞。因此,修复内容嗅探漏洞需要在服务器端采取措施来确保正确的响应设置和安全的内容处理。

我这里的解决方法是在nginx上配置禁用内容嗅探:

  1. 打开 Nginx 的配置文件(通常是 /etc/nginx/nginx.conf/etc/nginx/conf.d/default.conf)。
  2. http 块内添加以下配置:
1
2
3
4
5
6
7
8
9
10
11
http {
...
server {
...
location / {
...
add_header X-Content-Type-Options nosniff;
...
}
}
}

这将在响应中添加 X-Content-Type-Options 头部,并设置其值为 nosniff,告诉浏览器禁用内容嗅探。

配置完成后,重新启动 Tomcat 和 Nginx 服务,使配置生效。