diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyChecker.java new file mode 100644 index 0000000..dc854c1 --- /dev/null +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyChecker.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. + * 项目名称:信息安全性设计准则检查插件 + * 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 + * 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 + */ + +package com.keyware.sonar.java.rules.checkers; + +import org.sonar.check.Rule; +import org.sonar.java.ast.parser.ArgumentListTreeImpl; +import org.sonar.java.model.DefaultModuleScannerContext; +import org.sonar.java.model.expression.LiteralTreeImpl; +import org.sonar.java.model.expression.MemberSelectExpressionTreeImpl; +import org.sonar.java.model.expression.MethodInvocationTreeImpl; +import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; +import org.sonar.plugins.java.api.ModuleScannerContext; +import org.sonar.plugins.java.api.internal.EndOfAnalysis; +import org.sonar.plugins.java.api.tree.Arguments; +import org.sonar.plugins.java.api.tree.ExpressionTree; +import org.sonar.plugins.java.api.tree.Tree; + +import java.util.Collections; +import java.util.List; + +/** + * 应设置X-Frame-Options的值为deny + * 1.获取所有方法调用节点 + * 2.判断方法中的参数是否否和要求 + * + * @author RenFengJiang + * @date 2024/1/22 + */ +@Rule(key = "OptionsVerifyChecker") +public class OptionsVerifyChecker extends IssuableSubscriptionVisitor implements EndOfAnalysis { + + private boolean boo = true; + @Override + public List nodesToVisit() { + /** + * Tree.Kind.METHOD:方法节点 + * Tree.Kind.BLOCK:方法的代码块节点 + * Tree.Kind.METHOD_INVOCATION: 方法的调用节点 + */ + return Collections.singletonList(Tree.Kind.METHOD_INVOCATION); + } + + @Override + public void visitNode(Tree tree) { + //判断项目是否配置 + if(boo){ + MethodInvocationTreeImpl methodInvocationTree = (MethodInvocationTreeImpl) tree; + ExpressionTree expressionTree = methodInvocationTree.methodSelect(); + if(expressionTree instanceof MemberSelectExpressionTreeImpl){ + MemberSelectExpressionTreeImpl selectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree; + //获取到调用方法判断是否是设置配置方法 + if("addHeader".equals(selectExpressionTree.identifier().name()) || "setHeader".equals(selectExpressionTree.identifier().name())){ + //获取方法参数 + Arguments arguments = methodInvocationTree.arguments(); + if(arguments instanceof ArgumentListTreeImpl){ + boolean one = false; + boolean two = false; + for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) { + if(argument instanceof LiteralTreeImpl){ + LiteralTreeImpl literalTree = (LiteralTreeImpl) argument; + //判断参数 + if("\"X-Frame-Options\"".equals(literalTree.token().text())){ + one = true; + }else if("\"DENY\"".equals(literalTree.token().text())){ + two = true; + } + } + } + if(one && two){ + boo = false; + } + } + } + } + } + } + + @Override + public void endOfAnalysis(ModuleScannerContext context) { + var defaultContext = (DefaultModuleScannerContext) context; + if(boo){ + defaultContext.addIssueOnProject(this, "应设置X-Frame-Options的值为deny"); + } + } +} diff --git a/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/OptionsVerifyChecker.html b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/OptionsVerifyChecker.html new file mode 100644 index 0000000..7cb1467 --- /dev/null +++ b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/OptionsVerifyChecker.html @@ -0,0 +1,16 @@ + + +

应设置X-Frame-Options的值为deny(表示页面不允许在frame中展示)或SAMEORIGIN(表示页面可以在相同域名页面的frame中展示),禁止网页被未信任源加载。

+

应设置X-Frame-Options的值为deny

+
+
+
+

合规解决方案

+
+
+
diff --git a/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/OptionsVerifyChecker.json b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/OptionsVerifyChecker.json new file mode 100644 index 0000000..f0f29b4 --- /dev/null +++ b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/OptionsVerifyChecker.json @@ -0,0 +1,13 @@ +{ + "title": "应设置X-Frame-Options的值为deny", + "type": "CODE_SMELL", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + "28suo" + ], + "defaultSeverity": "Minor" +} \ No newline at end of file diff --git a/sonar-keyware-plugins-java/src/test/files/OptionsVerifyRule.java b/sonar-keyware-plugins-java/src/test/files/OptionsVerifyRule.java new file mode 100644 index 0000000..f0addf4 --- /dev/null +++ b/sonar-keyware-plugins-java/src/test/files/OptionsVerifyRule.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. + * 项目名称:信息安全性设计准则检查插件 + * 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 + * 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 + */ + +import javax.servlet.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class OptionsVerifyChecker implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException {} + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + HttpServletResponse res = (HttpServletResponse) response; + res.addHeader("X-Frame-Options", "DENY"); + chain.doFilter(request, response); + } + + @Override + public void destroy() {} + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + response.setHeader("X-Frame-Options", "DENY"); // 或者使用SAMEORIGIN,ALLOW-FROM等其他策略 + filterChain.doFilter(request, response); + } +} \ No newline at end of file diff --git a/sonar-keyware-plugins-java/src/test/files/options/OptionsVerifyOneRule.java b/sonar-keyware-plugins-java/src/test/files/options/OptionsVerifyOneRule.java new file mode 100644 index 0000000..0ce0cf2 --- /dev/null +++ b/sonar-keyware-plugins-java/src/test/files/options/OptionsVerifyOneRule.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. + * 项目名称:信息安全性设计准则检查插件 + * 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 + * 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 + */ + +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 XFrameOptionsFilter extends OncePerRequestFilter { + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { +// response.setHeader("X-Frame-Options", "DENY"); // 或者使用SAMEORIGIN,ALLOW-FROM等其他策略 + filterChain.doFilter(request, response); + } +} + +// 注册过滤器 +public class WebConfig implements WebApplicationInitializer { + + @Override + public void onStartup(ServletContext servletContext) throws ServletException { + // ...其他配置... + Dynamic registration = servletContext.addFilter("xFrameOptionsFilter", new XFrameOptionsFilter()); + registration.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*"); + } +} \ No newline at end of file diff --git a/sonar-keyware-plugins-java/src/test/files/options/OptionsVerifyTwoRule.java b/sonar-keyware-plugins-java/src/test/files/options/OptionsVerifyTwoRule.java new file mode 100644 index 0000000..f1aced2 --- /dev/null +++ b/sonar-keyware-plugins-java/src/test/files/options/OptionsVerifyTwoRule.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. + * 项目名称:信息安全性设计准则检查插件 + * 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 + * 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 + */ + +import javax.servlet.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class XFrameOptionsFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException {} + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + HttpServletResponse res = (HttpServletResponse) response; +// res.addHeader("X-Frame-Options", "DENY"); + chain.doFilter(request, response); + } + + @Override + public void destroy() {} +} \ No newline at end of file diff --git a/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyCheckerTest.java b/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyCheckerTest.java new file mode 100644 index 0000000..60a3d64 --- /dev/null +++ b/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyCheckerTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. + * 项目名称:信息安全性设计准则检查插件 + * 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 + * 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 + */ + +package com.keyware.sonar.java.rules.checkers; + +import com.keyware.sonar.java.utils.FilesUtils; +import org.junit.jupiter.api.Test; +import org.sonar.java.checks.verifier.CheckVerifier; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * TODO OptionsVerifyCheckerTest + * + * @author RenFengJiang + * @date 2024/1/22 + */ +public class OptionsVerifyCheckerTest { + Collection lists = new ArrayList(){ + { + add("src/test/files/options/OptionsVerifyOneRule.java"); + add("src/test/files/options/OptionsVerifyTwoRule.java"); + } + }; + @Test + void detected() { + + CheckVerifier.newVerifier() + .onFiles(lists) + .withCheck(new OptionsVerifyChecker()) + .withClassPath(FilesUtils.getClassPath("target/test-jars")) + .verifyIssueOnProject("应设置X-Frame-Options的值为deny"); + } +}