parent
d2271ff4fb
commit
d302ca7340
@ -0,0 +1,258 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. |
||||||
|
* 项目名称:信息安全性设计准则检查插件 |
||||||
|
* 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 |
||||||
|
* 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.sonar.cxx.squidbridge; // cxx: in use
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull; |
||||||
|
import static com.google.common.base.Preconditions.checkState; |
||||||
|
import com.google.common.base.Throwables; |
||||||
|
import com.google.common.collect.Lists; |
||||||
|
import com.sonar.cxx.sslr.api.AstNode; |
||||||
|
import com.sonar.cxx.sslr.api.Grammar; |
||||||
|
import com.sonar.cxx.sslr.api.RecognitionException; |
||||||
|
import com.sonar.cxx.sslr.impl.Parser; |
||||||
|
import com.sonar.cxx.sslr.impl.ast.AstWalker; |
||||||
|
import java.io.File; |
||||||
|
import java.io.InterruptedIOException; |
||||||
|
import java.util.Collection; |
||||||
|
import java.util.List; |
||||||
|
import javax.annotation.Nullable; |
||||||
|
import org.sonar.api.batch.fs.InputFile; |
||||||
|
import org.sonar.api.utils.log.Logger; |
||||||
|
import org.sonar.api.utils.log.Loggers; |
||||||
|
import org.sonar.cxx.squidbridge.api.AnalysisException; |
||||||
|
import org.sonar.cxx.squidbridge.api.SourceCodeSearchEngine; |
||||||
|
import org.sonar.cxx.squidbridge.api.SourceCodeTreeDecorator; |
||||||
|
import org.sonar.cxx.squidbridge.api.SourceProject; |
||||||
|
import org.sonar.cxx.squidbridge.indexer.SquidIndex; |
||||||
|
import org.sonar.cxx.squidbridge.measures.MetricDef; |
||||||
|
|
||||||
|
public class AstScanner<G extends Grammar> { |
||||||
|
|
||||||
|
private static final Logger LOG = Loggers.get(AstScanner.class); |
||||||
|
|
||||||
|
private final List<SquidAstVisitor<G>> visitors; |
||||||
|
private final Parser<G> parser; |
||||||
|
private final SquidAstVisitorContextImpl<G> context; |
||||||
|
|
||||||
|
private final SquidIndex indexer = new SquidIndex(); |
||||||
|
private final MetricDef[] metrics; |
||||||
|
private final MetricDef filesMetric; |
||||||
|
|
||||||
|
protected AstScanner(Builder<G> builder) { |
||||||
|
this.visitors = Lists.newArrayList(builder.visitors); |
||||||
|
this.parser = builder.baseParser; |
||||||
|
this.context = builder.context; |
||||||
|
|
||||||
|
this.context.setGrammar(parser.getGrammar()); |
||||||
|
this.context.getProject().setSourceCodeIndexer(indexer); |
||||||
|
this.context.setCommentAnalyser(builder.commentAnalyser); |
||||||
|
this.metrics = builder.metrics; |
||||||
|
this.filesMetric = builder.filesMetric; |
||||||
|
indexer.index(context.getProject()); |
||||||
|
} |
||||||
|
|
||||||
|
public SourceCodeSearchEngine getIndex() { |
||||||
|
return indexer; |
||||||
|
} |
||||||
|
|
||||||
|
public void scanFile(File file) { |
||||||
|
scanFiles(java.util.List.of(file)); |
||||||
|
} |
||||||
|
|
||||||
|
public void scanInputFile(InputFile inputFile) { |
||||||
|
scanInputFiles(java.util.List.of(inputFile)); |
||||||
|
} |
||||||
|
|
||||||
|
public void scanFiles(Collection<File> files) { |
||||||
|
initVisitors(); |
||||||
|
|
||||||
|
var astWalker = new AstWalker(visitors); |
||||||
|
|
||||||
|
for (var file : files) { |
||||||
|
checkCancel(); |
||||||
|
context.setFile(file, filesMetric); |
||||||
|
|
||||||
|
Exception parseException = null; |
||||||
|
AstNode ast = null; |
||||||
|
try { |
||||||
|
try { |
||||||
|
ast = parser.parse(file); |
||||||
|
} catch (Exception e) { |
||||||
|
parseException = handleParseException(file, e); |
||||||
|
} |
||||||
|
walkAndVisit(astWalker, ast, parseException); |
||||||
|
} catch (Throwable e) { |
||||||
|
throw new AnalysisException("Unable to parse file: " + file.getAbsolutePath(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
destroyVisitors(); |
||||||
|
decorateSquidTree(); |
||||||
|
} |
||||||
|
|
||||||
|
public void scanInputFiles(Iterable<InputFile> inputFiles) { |
||||||
|
initVisitors(); |
||||||
|
|
||||||
|
var astWalker = new AstWalker(visitors); |
||||||
|
|
||||||
|
for (var inputFile : inputFiles) { |
||||||
|
var file = new File(inputFile.uri().getPath()); |
||||||
|
checkCancel(); |
||||||
|
context.setInputFile(inputFile, filesMetric); |
||||||
|
|
||||||
|
Exception parseException = null; |
||||||
|
AstNode ast = null; |
||||||
|
try { |
||||||
|
try { |
||||||
|
ast = parser.parse(inputFile.contents()); |
||||||
|
} catch (Exception e) { |
||||||
|
parseException = handleParseException(file, e); |
||||||
|
} |
||||||
|
walkAndVisit(astWalker, ast, parseException); |
||||||
|
} catch (Throwable e) { |
||||||
|
LOG.error("Unable to parse file: " + file.getAbsolutePath(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
destroyVisitors(); |
||||||
|
decorateSquidTree(); |
||||||
|
} |
||||||
|
|
||||||
|
private static Exception handleParseException(File file, Exception e) { |
||||||
|
checkInterrupted(e); |
||||||
|
if (e instanceof RecognitionException) { |
||||||
|
LOG.error("Unable to parse file: " + file.getAbsolutePath()); |
||||||
|
LOG.error(e.getMessage()); |
||||||
|
} else { |
||||||
|
LOG.error("Unable to parse file: " + file.getAbsolutePath(), e); |
||||||
|
} |
||||||
|
return e; |
||||||
|
} |
||||||
|
|
||||||
|
private void walkAndVisit(AstWalker astWalker, AstNode ast, @Nullable Exception parseException) throws Throwable { |
||||||
|
if (parseException == null) { |
||||||
|
astWalker.walkAndVisit(ast); |
||||||
|
} else { |
||||||
|
// process parse error
|
||||||
|
for (var visitor : visitors) { |
||||||
|
visitor.visitFile(ast); |
||||||
|
} |
||||||
|
for (var visitor : visitors) { |
||||||
|
if (visitor instanceof AstScannerExceptionHandler) { |
||||||
|
if (parseException instanceof RecognitionException) { |
||||||
|
((AstScannerExceptionHandler) visitor) |
||||||
|
.processRecognitionException((RecognitionException) parseException); |
||||||
|
} else { |
||||||
|
((AstScannerExceptionHandler) visitor).processException(parseException); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
for (var visitor : visitors) { |
||||||
|
visitor.leaveFile(ast); |
||||||
|
} |
||||||
|
} |
||||||
|
context.popTillSourceProject(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initVisitors() { |
||||||
|
for (var visitor : visitors) { |
||||||
|
visitor.init(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void destroyVisitors() { |
||||||
|
for (var visitor : visitors) { |
||||||
|
visitor.destroy(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Checks if the root cause of the thread is related to an interrupt. |
||||||
|
* Note that when such an exception is thrown, the interrupt flag is reset. |
||||||
|
*/ |
||||||
|
private static void checkInterrupted(Exception e) { |
||||||
|
Throwable cause = Throwables.getRootCause(e); |
||||||
|
if (cause instanceof InterruptedException || cause instanceof InterruptedIOException) { |
||||||
|
throw new AnalysisException("Analysis cancelled", e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void checkCancel() { |
||||||
|
if (Thread.interrupted()) { |
||||||
|
throw new AnalysisException("Analysis cancelled"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected void decorateSquidTree() { |
||||||
|
if (metrics != null && metrics.length > 0) { |
||||||
|
SourceProject project = context.getProject(); |
||||||
|
var decorator = new SourceCodeTreeDecorator(project); |
||||||
|
decorator.decorateWith(metrics); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static <G extends Grammar> Builder<G> builder(SquidAstVisitorContextImpl<G> context) { |
||||||
|
return new Builder<>(context); |
||||||
|
} |
||||||
|
|
||||||
|
public static class Builder<G extends Grammar> { |
||||||
|
|
||||||
|
private Parser<G> baseParser; |
||||||
|
private final List<SquidAstVisitor<G>> visitors = Lists.newArrayList(); |
||||||
|
private final SquidAstVisitorContextImpl<G> context; |
||||||
|
private CommentAnalyser commentAnalyser; |
||||||
|
private MetricDef[] metrics; |
||||||
|
private MetricDef filesMetric; |
||||||
|
|
||||||
|
public Builder(SquidAstVisitorContextImpl<G> context) { |
||||||
|
checkNotNull(context, "context cannot be null"); |
||||||
|
this.context = context; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder<G> setBaseParser(Parser<G> baseParser) { |
||||||
|
checkNotNull(baseParser, "baseParser cannot be null"); |
||||||
|
this.baseParser = baseParser; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder<G> setCommentAnalyser(CommentAnalyser commentAnalyser) { |
||||||
|
checkNotNull(commentAnalyser, "commentAnalyser cannot be null"); |
||||||
|
this.commentAnalyser = commentAnalyser; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder<G> withSquidAstVisitor(SquidAstVisitor<G> visitor) { |
||||||
|
checkNotNull(visitor, "visitor cannot be null"); |
||||||
|
visitor.setContext(context); |
||||||
|
visitors.add(visitor); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder<G> withMetrics(MetricDef... metrics) { |
||||||
|
for (var metric : metrics) { |
||||||
|
checkNotNull(metric, "metrics cannot be null"); |
||||||
|
} |
||||||
|
this.metrics = metrics.clone(); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Builder<G> setFilesMetric(MetricDef filesMetric) { |
||||||
|
checkNotNull(filesMetric, "filesMetric cannot be null"); |
||||||
|
this.filesMetric = filesMetric; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public AstScanner<G> build() { |
||||||
|
checkState(baseParser != null, "baseParser must be set"); |
||||||
|
checkState(commentAnalyser != null, "commentAnalyser must be set"); |
||||||
|
checkState(filesMetric != null, "filesMetric must be set"); |
||||||
|
return new AstScanner<>(this); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,81 @@ |
|||||||
|
/* |
||||||
|
* 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.model.expression.IdentifierTreeImpl; |
||||||
|
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; |
||||||
|
import org.sonar.plugins.java.api.tree.*; |
||||||
|
|
||||||
|
import java.util.Collections; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* 通过用户名口令、数据证书等其他手段对主机身份进行鉴别 |
||||||
|
* |
||||||
|
* @author RenFengJiang |
||||||
|
* @date 2024/7/3 |
||||||
|
*/ |
||||||
|
@Rule(key = "HostIdentityChecker") |
||||||
|
public class HostIdentityChecker extends IssuableSubscriptionVisitor { |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<Tree.Kind> nodesToVisit() { |
||||||
|
return Collections.singletonList(Tree.Kind.METHOD); |
||||||
|
} |
||||||
|
@Override |
||||||
|
public void visitNode(Tree tree) { |
||||||
|
MethodTree methodTree = (MethodTree) tree; |
||||||
|
List<VariableTree> parameters = methodTree.parameters(); |
||||||
|
// 盘带是否是文件上传类
|
||||||
|
boolean boo = parameters.stream().anyMatch(type -> "HttpServletRequest".equals(type.type().toString())); |
||||||
|
if(boo){ |
||||||
|
NodeIf nodeIf = new NodeIf(); |
||||||
|
methodTree.block().accept(nodeIf); |
||||||
|
if(nodeIf.getNameBoolean() || nodeIf.getPasswordBoolean()){ |
||||||
|
context.reportIssue(this,methodTree.simpleName(),"通过用户名口令、数据证书等其他手段对主机身份进行鉴别"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public class NodeIf extends BaseTreeVisitor { |
||||||
|
|
||||||
|
public boolean nameBoolean = true; |
||||||
|
private boolean passwordBoolean = true; |
||||||
|
boolean getNameBoolean(){ |
||||||
|
return nameBoolean; |
||||||
|
} |
||||||
|
boolean getPasswordBoolean(){ |
||||||
|
return passwordBoolean; |
||||||
|
} |
||||||
|
@Override |
||||||
|
public void visitIfStatement(IfStatementTree tree) { |
||||||
|
//获取到if表达式
|
||||||
|
ExpressionTree condition = tree.condition(); |
||||||
|
if (condition instanceof BinaryExpressionTree) { |
||||||
|
BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) condition; |
||||||
|
//判断是否进行if判断
|
||||||
|
if ("username".equals(binaryExpressionTree.leftOperand().toString())) { |
||||||
|
nameBoolean = false; |
||||||
|
} else if ("password".equals(binaryExpressionTree.rightOperand().toString())) { |
||||||
|
passwordBoolean = false; |
||||||
|
} |
||||||
|
} |
||||||
|
if (condition instanceof IdentifierTreeImpl) { |
||||||
|
IdentifierTreeImpl identifierTreeImpl = (IdentifierTreeImpl) condition; |
||||||
|
//判断是否进行if判断
|
||||||
|
if ("username".equals(identifierTreeImpl.name())) { |
||||||
|
nameBoolean = false; |
||||||
|
} else if ("password".equals(identifierTreeImpl.name())) { |
||||||
|
passwordBoolean = false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,89 @@ |
|||||||
|
/* |
||||||
|
* 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.model.expression.NewClassTreeImpl; |
||||||
|
import org.sonar.java.model.statement.BlockTreeImpl; |
||||||
|
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; |
||||||
|
import org.sonar.plugins.java.api.semantic.Symbol; |
||||||
|
import org.sonar.plugins.java.api.tree.*; |
||||||
|
|
||||||
|
import java.util.Collections; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Locale; |
||||||
|
|
||||||
|
/** |
||||||
|
* 用户输入口令时应对口令域进行掩饰。用户输入的每一个字符都应该以星号形式回显。 |
||||||
|
* |
||||||
|
* @author RenFengJiang |
||||||
|
* @date 2024/7/3 |
||||||
|
*/ |
||||||
|
@Rule(key = "PasswordInputTagJavaChecker") |
||||||
|
public class PasswordInputTagJavaChecker extends IssuableSubscriptionVisitor { |
||||||
|
@Override |
||||||
|
public List<Tree.Kind> nodesToVisit() { |
||||||
|
/** |
||||||
|
* Tree.Kind.METHOD:方法节点 |
||||||
|
* Tree.Kind.BLOCK:方法的代码块节点 |
||||||
|
* Tree.Kind.METHOD_INVOCATION: 方法的调用节点 |
||||||
|
*/ |
||||||
|
return Collections.singletonList(Tree.Kind.BLOCK); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void visitNode(Tree tree) { |
||||||
|
BlockTreeImpl node = (BlockTreeImpl) tree; |
||||||
|
MethodeBodyVisitor methodeBodyVisitor = new MethodeBodyVisitor(this, node); |
||||||
|
node.accept(methodeBodyVisitor); |
||||||
|
} |
||||||
|
|
||||||
|
static class MethodeBodyVisitor extends BaseTreeVisitor { |
||||||
|
private BlockTreeImpl blockTree; |
||||||
|
private PasswordInputTagJavaChecker checker; |
||||||
|
public MethodeBodyVisitor(PasswordInputTagJavaChecker checker, BlockTreeImpl blockTree){ |
||||||
|
this.checker = checker; |
||||||
|
this.blockTree = blockTree; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void visitNewClass(NewClassTree tree) { |
||||||
|
String name = tree.identifier().toString(); |
||||||
|
if("JTextField".equals(name)){ |
||||||
|
MethodeCall methodeCall = new MethodeCall(); |
||||||
|
blockTree.accept(methodeCall); |
||||||
|
if(methodeCall.getEchoBoolean()){ |
||||||
|
checker.context.reportIssue(checker, tree, "Java用户输入口令时应对口令域进行掩饰,用户输入的每一个字符都应该以星号形式回显"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static class MethodeCall extends BaseTreeVisitor { |
||||||
|
//是否存在JTextField输入
|
||||||
|
private boolean echoBoolean = true; |
||||||
|
|
||||||
|
public boolean getEchoBoolean() { |
||||||
|
return echoBoolean; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void visitMethodInvocation(MethodInvocationTree tree) { |
||||||
|
//获取到方法调用
|
||||||
|
ExpressionTree expressionTree = tree.methodSelect(); |
||||||
|
if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) { |
||||||
|
MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree; |
||||||
|
if ("setEchoChar".equals(memberSelectExpressionTree.identifier().name())) { |
||||||
|
echoBoolean = false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
<!-- |
||||||
|
~ Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. |
||||||
|
~ 项目名称:信息安全性设计准则检查插件 |
||||||
|
~ 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 |
||||||
|
~ 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 |
||||||
|
--> |
||||||
|
|
||||||
|
<p>通过用户名口令、数据证书等其他手段对主机身份进行鉴别</p> |
||||||
|
<h2>通过用户名口令、数据证书等其他手段对主机身份进行鉴别</h2> |
||||||
|
<pre> |
||||||
|
|
||||||
|
</pre> |
||||||
|
<h2>合规解决方案</h2> |
||||||
|
<pre> |
||||||
|
|
||||||
|
</pre> |
@ -0,0 +1,13 @@ |
|||||||
|
{ |
||||||
|
"title": "通过用户名口令、数据证书等其他手段对主机身份进行鉴别", |
||||||
|
"type": "CODE_SMELL", |
||||||
|
"status": "ready", |
||||||
|
"remediation": { |
||||||
|
"func": "Constant\/Issue", |
||||||
|
"constantCost": "5min" |
||||||
|
}, |
||||||
|
"tags": [ |
||||||
|
"28suo" |
||||||
|
], |
||||||
|
"defaultSeverity": "Minor" |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
<!-- |
||||||
|
~ Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. |
||||||
|
~ 项目名称:信息安全性设计准则检查插件 |
||||||
|
~ 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 |
||||||
|
~ 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 |
||||||
|
--> |
||||||
|
|
||||||
|
<h2>Java用户输入口令时应对口令域进行掩饰,用户输入的每一个字符都应该以星号形式回显</h2> |
||||||
|
<p>Java用户输入口令时应对口令域进行掩饰,用户输入的每一个字符都应该以星号形式回显</p> |
||||||
|
<pre> |
||||||
|
|
||||||
|
</pre> |
||||||
|
<h2>合规解决方案</h2> |
||||||
|
<pre> |
||||||
|
|
||||||
|
</pre> |
@ -0,0 +1,13 @@ |
|||||||
|
{ |
||||||
|
"title": "Java用户输入口令时应对口令域进行掩饰,用户输入的每一个字符都应该以星号形式回显", |
||||||
|
"type": "CODE_SMELL", |
||||||
|
"status": "ready", |
||||||
|
"remediation": { |
||||||
|
"func": "Constant\/Issue", |
||||||
|
"constantCost": "15min" |
||||||
|
}, |
||||||
|
"tags": [ |
||||||
|
"28suo" |
||||||
|
], |
||||||
|
"defaultSeverity": "Major" |
||||||
|
} |
@ -1,22 +1,38 @@ |
|||||||
public class FileCheck{ |
public class FileCheck { |
||||||
|
|
||||||
public String FileName(){ |
public String FileName() { |
||||||
String fileName = ""; |
String fileName = ""; |
||||||
String fileExt = ""; |
String fileExt = ""; |
||||||
String fileSuffix = ""; |
String fileSuffix = ""; |
||||||
|
|
||||||
if(fileName.endsWith("png") ){// Noncompliant {{在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为}}
|
if (fileName.endsWith("png")) {// Noncompliant {{在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为}}
|
||||||
|
|
||||||
} |
} |
||||||
|
|
||||||
if(fileExt.equals("jpg") ){// Noncompliant {{在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为}}
|
if (fileExt.equals("jpg")) {// Noncompliant {{在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为}}
|
||||||
|
|
||||||
} |
} |
||||||
|
|
||||||
if(fileSuffix.equals("jpg")){// Noncompliant {{在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为}}
|
if (fileSuffix.equals("jpg")) {// Noncompliant {{在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为}}
|
||||||
|
|
||||||
} |
} |
||||||
return null; |
return null; |
||||||
} |
} |
||||||
|
|
||||||
|
public void imageBeauty(HttpServletRequest request) { //处理图像文件
|
||||||
|
DiskFileltemFactory factory = new DiskFileltemFactory(); |
||||||
|
ServletFileUpload upload = new ServletFileUpload(factory); |
||||||
|
List<FileItem> items = upload.parseRequest(request); |
||||||
|
Iterator<Fileltem> iter = items.iterator(); |
||||||
|
while (iter.hasNext()) { |
||||||
|
FileItem item = iter.next(); |
||||||
|
String fileName = item.getName(); |
||||||
|
String fileEnd = fileName.substring(fileName.lastlndexOf(".") + 1).toLowerCase(); |
||||||
|
//依赖文件扩展名进行验证
|
||||||
|
if (fileEnd != null && fileEnd.matches(regex)) {// Noncompliant {{在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为}}
|
||||||
|
//对文件的相关操作
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
} |
} |
||||||
|
@ -0,0 +1,26 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. |
||||||
|
* 项目名称:信息安全性设计准则检查插件 |
||||||
|
* 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 |
||||||
|
* 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 |
||||||
|
*/ |
||||||
|
|
||||||
|
import java.net.*; |
||||||
|
|
||||||
|
public class Example { |
||||||
|
private boolean trusted; |
||||||
|
|
||||||
|
public void getTrust(HttpServletRequest request) {// Noncompliant {{通过用户名口令、数据证书等其他手段对主机身份进行鉴别}}
|
||||||
|
String ip = request.getRemoteAddr(); |
||||||
|
InetAddress address = InetAddress.getByName(ip); |
||||||
|
//攻击者可通过DNS欺骗绕过依赖域名的主机身份鉴别
|
||||||
|
if (address.getCanonicalHostName().endsWith("trustme.com")) { |
||||||
|
trusted = true; |
||||||
|
} |
||||||
|
|
||||||
|
// String username = request.getParameter("username");
|
||||||
|
// String password = request.getParameter("password");
|
||||||
|
// if (username != null &.&.password != null){
|
||||||
|
// }
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. |
||||||
|
* 项目名称:信息安全性设计准则检查插件 |
||||||
|
* 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 |
||||||
|
* 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 |
||||||
|
*/ |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
public class SevneTeen{ |
||||||
|
public void exampleFun(){ |
||||||
|
//口令域使用明文输入的JTextField 控件
|
||||||
|
JTextField passwordfield = new JTextField();// Noncompliant {{Java用户输入口令时应对口令域进行掩饰,用户输入的每一个字符都应该以星号形式回显}}
|
||||||
|
// passwordfield.setEchoChar("*");//设置回显的符号为*’
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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; |
||||||
|
|
||||||
|
/** |
||||||
|
* 通过用户名口令、数据证书等其他手段对主机身份进行鉴别 |
||||||
|
* |
||||||
|
* @author RenFengJiang |
||||||
|
* @date 2024/7/3 |
||||||
|
*/ |
||||||
|
public class HostIdentityCheckerTest { |
||||||
|
|
||||||
|
@Test |
||||||
|
void detected() { |
||||||
|
HostIdentityChecker rule = new HostIdentityChecker(); |
||||||
|
|
||||||
|
|
||||||
|
CheckVerifier.newVerifier() |
||||||
|
.onFile("src/test/files/HostIdentityChecker.java") |
||||||
|
.withCheck(rule) |
||||||
|
.withClassPath(FilesUtils.getClassPath("target/test-jars")) |
||||||
|
.verifyIssues(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
/* |
||||||
|
* 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; |
||||||
|
|
||||||
|
/** |
||||||
|
* Java用户输入口令时应对口令域进行掩饰,用户输入的每一个字符都应该以星号形式回显 |
||||||
|
* |
||||||
|
* @author RenFengJiang |
||||||
|
* @date 2024/7/3 |
||||||
|
*/ |
||||||
|
public class PasswordInputTagJavaCheckerTest { |
||||||
|
@Test |
||||||
|
public void test(){ |
||||||
|
CheckVerifier.newVerifier() |
||||||
|
.onFile("src/test/files/PasswordInputTagJavaChecker.java") |
||||||
|
.withCheck(new PasswordInputTagJavaChecker()) |
||||||
|
.withClassPath(FilesUtils.getClassPath("target/test-jars")) |
||||||
|
.verifyIssues(); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue