新增准则:应使用盐值计算口令

wuhaoyang
RenFengJiang 11 months ago
parent 55e2e5eb77
commit 1925387259
  1. 93
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HashSaltPassWordChecker.java
  2. 3
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SecurityCookieChecker.java
  3. 9
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/HashSaltPassWordChecker.html
  4. 13
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/HashSaltPassWordChecker.json
  5. 11
      sonar-keyware-plugins-java/src/test/files/HashSaltPassWordRule.java
  6. 31
      sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/HashSaltPassWordCheckerTest.java

@ -0,0 +1,93 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称Java 信息安全性设计准则
* 项目描述用于检查Java源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule;
import org.sonar.java.ast.parser.ArgumentListTreeImpl;
import org.sonar.java.ast.visitors.SubscriptionVisitor;
import org.sonar.java.model.declaration.VariableTreeImpl;
import org.sonar.java.model.expression.IdentifierTreeImpl;
import org.sonar.java.model.expression.MemberSelectExpressionTreeImpl;
import org.sonar.java.model.expression.MethodInvocationTreeImpl;
import org.sonar.plugins.java.api.tree.*;
import java.util.Collections;
import java.util.List;
/**
* TODO HashSaltPassWordChecker
*
* @author RenFengJiang
* @date 2024/1/11
*/
@Rule(key = "HashSaltPassWordChecker")
public class HashSaltPassWordChecker extends SubscriptionVisitor {
@Override
public List<Tree.Kind> nodesToVisit() {
/**
* Tree.Kind.METHOD方法节点
* Tree.Kind.BLOCK方法的代码块节点
* Tree.Kind.METHOD_INVOCATION 方法的调用节点
*/
return Collections.singletonList(Tree.Kind.METHOD);
}
@Override
public void visitNode(Tree tree) {
MethodTree node = (MethodTree) tree;
var bodyVisitor = new MethodeBodyVisitor(this);
node.block().accept(bodyVisitor);
}
static class MethodeBodyVisitor extends BaseTreeVisitor {
// 存放盐值后的密码
public String strPassWord = "";
private final HashSaltPassWordChecker checker;
MethodeBodyVisitor(HashSaltPassWordChecker checker) {
this.checker = checker;
}
@Override
public void visitMethodInvocation(MethodInvocationTree tree) {
// 获取到方法调用
ExpressionTree expressionTree = tree.methodSelect();
if (expressionTree instanceof MemberSelectExpressionTreeImpl) {
// 获取到调用的方法
MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree;
if ("setPassWord".equals(memberSelectExpressionTree.identifier().name())) {
Tree parent = tree.arguments();
if (parent instanceof ArgumentListTreeImpl) {
for (ExpressionTree expressionTree1 : (ArgumentListTreeImpl) parent) {
if (expressionTree1 instanceof IdentifierTreeImpl) {
IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) expressionTree1;
// 判断set中使用的参数
if(!identifierTree.name().equals(strPassWord)){
checker.context.reportIssue(checker, identifierTree, "应使用盐值计算口令");
}
}
}
}
// 判断是否是生成的加盐后的密码
}else if("BCrypt".equals(memberSelectExpressionTree.expression().toString()) && "hashpw".equals(memberSelectExpressionTree.identifier().name())){
Tree parent = memberSelectExpressionTree.parent();
if(parent instanceof MethodInvocationTreeImpl){
MethodInvocationTreeImpl methodInvocationTree = (MethodInvocationTreeImpl) parent;
Tree parent1 = methodInvocationTree.parent();
if(parent1 instanceof VariableTreeImpl){
VariableTreeImpl variableTree = (VariableTreeImpl) parent1;
// 加盐后的参数名称
strPassWord = variableTree.simpleName().name();
}
}
}
}
}
}
}

@ -48,8 +48,6 @@ public class SecurityCookieChecker extends SubscriptionVisitor {
if(!(bodyVisitor.booAge && bodyVisitor.booCure)){
context.reportIssue(this,node.simpleName(),"设置HTTPS会话中cookie的安全属性");
}
}else {
}
}
}
@ -70,7 +68,6 @@ public class SecurityCookieChecker extends SubscriptionVisitor {
@Override
public void visitMethodInvocation(MethodInvocationTree tree) {
ExpressionTree expressionTree = tree.methodSelect();
System.out.println(expressionTree);
if(expressionTree instanceof MemberSelectExpressionTree){
MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree;
switch (memberSelectExpressionTree.identifier().name()){

@ -0,0 +1,9 @@
<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,11 @@
class HashSaltPassWordRule{
public static void cs(Student studnet){
// 结合盐值和口令进行散列计算
// String hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt());
studnet.setPassWord(hashedPassword);// Noncompliant {{应使用盐值计算口令}}
}
}

@ -0,0 +1,31 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称Java 信息安全性设计准则
* 项目描述用于检查Java源代码的安全性设计准则的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;
/**
* TODO HashSaltPassWordCheckerTest
*
* @author RenFengJiang
* @date 2024/1/11
*/
public class HashSaltPassWordCheckerTest {
@Test
void detected() {
HashSaltPassWordChecker rule = new HashSaltPassWordChecker();
CheckVerifier.newVerifier()
.onFile("src/test/files/HashSaltPassWordRule.java")
.withCheck(rule)
.withClassPath(FilesUtils.getClassPath("target/test-jars"))
.verifyIssues();
}
}
Loading…
Cancel
Save