Compare commits
No commits in common. '3421f76628b925ae756b94cbfa51fa6ce889a31c' and '2dc4cc8b8a96bdce4965611b15a72fe24bf3a7a7' have entirely different histories.
3421f76628
...
2dc4cc8b8a
@ -1,38 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.plugins.html.checks.AbstractPageCheck; |
|
||||||
import org.sonar.plugins.html.node.TagNode; |
|
||||||
import org.sonar.plugins.java.api.JavaCheck; |
|
||||||
|
|
||||||
/** |
|
||||||
* <p>规则:用户输入口令时应对口令域进行掩饰。用户输入的每一个字符都应该以星号形式回显。</p> |
|
||||||
* 验证逻辑:当input标签的name或者id包含password时,如果type不是password时,则报告问题 |
|
||||||
* |
|
||||||
* @author GuoXin |
|
||||||
* @date 2024/1/20 |
|
||||||
*/ |
|
||||||
@Rule(key = "PasswordInputTagChecker") |
|
||||||
public class PasswordInputTagChecker extends AbstractPageCheck implements JavaCheck { |
|
||||||
@Override |
|
||||||
public void startElement(TagNode node) { |
|
||||||
if ("input".equalsIgnoreCase(node.getNodeName())) { |
|
||||||
var id = node.getAttribute("id"); |
|
||||||
var name = node.getAttribute("name"); |
|
||||||
var type = node.getAttribute("type"); |
|
||||||
// 当name或者id包含password时,如果type不是password时,则报告问题
|
|
||||||
if ((id != null && id.contains("password")) || (name != null && name.contains("password"))) { |
|
||||||
if (!"password".equalsIgnoreCase(type)) { |
|
||||||
createViolation(node, "密码输入框的type属性不为password"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,9 +0,0 @@ |
|||||||
<h2>用户输入口令时应对口令域进行掩饰,用户输入的每一个字符都应该以星号形式回显。</h2> |
|
||||||
<p>用户输入口令时应对口令域进行掩饰,用户输入的每一个字符都应该以星号形式回显。</p> |
|
||||||
<pre> |
|
||||||
|
|
||||||
</pre> |
|
||||||
<h2>合规解决方案</h2> |
|
||||||
<pre> |
|
||||||
|
|
||||||
</pre> |
|
@ -1,13 +0,0 @@ |
|||||||
{ |
|
||||||
"title": "用户输入口令时应对口令域进行掩饰。用户输入的每一个字符都应该以星号形式回显", |
|
||||||
"type": "CODE_SMELL", |
|
||||||
"status": "ready", |
|
||||||
"remediation": { |
|
||||||
"func": "Constant\/Issue", |
|
||||||
"constantCost": "15min" |
|
||||||
}, |
|
||||||
"tags": [ |
|
||||||
"28suo" |
|
||||||
], |
|
||||||
"defaultSeverity": "Major" |
|
||||||
} |
|
@ -1,14 +0,0 @@ |
|||||||
<html> |
|
||||||
<head><title>Test for PasswordInputTagChecker</title></head> |
|
||||||
<body> |
|
||||||
<h1>Test for PasswordInputTagChecker</h1> |
|
||||||
<h2>Test 1 - FAIL</h2> |
|
||||||
<p> |
|
||||||
<form action="test.html" method="post"> |
|
||||||
<input type="password" name="password" value=""/> |
|
||||||
<input type="text" name="password" value=""/> |
|
||||||
<input type="submit" value="Submit"/> |
|
||||||
</form> |
|
||||||
</p> |
|
||||||
</body> |
|
||||||
</html> |
|
@ -1,35 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. |
|
||||||
* 项目名称:信息安全性设计准则检查插件 |
|
||||||
* 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 |
|
||||||
* 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 |
|
||||||
*/ |
|
||||||
|
|
||||||
package com.keyware.sonar.java.rules.checkers; |
|
||||||
|
|
||||||
import com.keyware.sonar.java.utils.HtmlCheckMessagesVerifierRule; |
|
||||||
import com.keyware.sonar.java.utils.HtmlTestHelper; |
|
||||||
import org.junit.jupiter.api.Test; |
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension; |
|
||||||
import org.sonar.plugins.html.visitor.HtmlSourceCode; |
|
||||||
|
|
||||||
import java.io.File; |
|
||||||
|
|
||||||
/** |
|
||||||
* 测试规则:用户输入口令时应对口令域进行掩饰。用户输入的每一个字符都应该以星号形式回显 |
|
||||||
* |
|
||||||
* @author GuoXin |
|
||||||
* @date 2024/1/20 |
|
||||||
*/ |
|
||||||
public class PasswordInputTagCheckerTest { |
|
||||||
@RegisterExtension |
|
||||||
public HtmlCheckMessagesVerifierRule checkMessagesVerifier = new HtmlCheckMessagesVerifierRule(); |
|
||||||
|
|
||||||
@Test |
|
||||||
public void detected() throws Exception { |
|
||||||
HtmlSourceCode sourceCode = HtmlTestHelper.scan(new File("src/test/files/PasswordInputTagChecker.html"), new PasswordInputTagChecker()); |
|
||||||
|
|
||||||
checkMessagesVerifier.verify(sourceCode.getIssues()) |
|
||||||
.next().atLine(16); |
|
||||||
} |
|
||||||
} |
|
@ -1,113 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. |
|
||||||
* 项目名称:信息安全性设计准则检查插件 |
|
||||||
* 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 |
|
||||||
* 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 |
|
||||||
*/ |
|
||||||
|
|
||||||
package com.keyware.sonar.java.utils; |
|
||||||
|
|
||||||
import org.sonar.plugins.html.checks.HtmlIssue; |
|
||||||
import org.sonar.plugins.html.checks.PreciseHtmlIssue; |
|
||||||
|
|
||||||
import javax.annotation.Nullable; |
|
||||||
import java.util.*; |
|
||||||
|
|
||||||
/** |
|
||||||
* Html检查消息验证器 |
|
||||||
* |
|
||||||
* @author GuoXin |
|
||||||
* @date 2024/1/20 |
|
||||||
*/ |
|
||||||
public final class HtmlCheckMessagesVerifier { |
|
||||||
|
|
||||||
public static HtmlCheckMessagesVerifier verify(Collection<HtmlIssue> messages) { |
|
||||||
return new HtmlCheckMessagesVerifier(messages); |
|
||||||
} |
|
||||||
|
|
||||||
private final Iterator<HtmlIssue> iterator; |
|
||||||
private HtmlIssue current; |
|
||||||
|
|
||||||
private static final Comparator<HtmlIssue> ORDERING = (left, right) -> { |
|
||||||
if (Objects.equals(left.line(), right.line())) { |
|
||||||
return left.message().compareTo(right.message()); |
|
||||||
} else if (left.line() == null) { |
|
||||||
return -1; |
|
||||||
} else if (right.line() == null) { |
|
||||||
return 1; |
|
||||||
} else { |
|
||||||
return left.line().compareTo(right.line()); |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
private HtmlCheckMessagesVerifier(Collection<HtmlIssue> messages) { |
|
||||||
ArrayList<HtmlIssue> messagesList = new ArrayList<>(messages); |
|
||||||
messagesList.sort(ORDERING); |
|
||||||
iterator = messagesList.iterator(); |
|
||||||
} |
|
||||||
|
|
||||||
public HtmlCheckMessagesVerifier next() { |
|
||||||
if (!iterator.hasNext()) { |
|
||||||
throw new AssertionError("\nExpected violation"); |
|
||||||
} |
|
||||||
current = iterator.next(); |
|
||||||
return this; |
|
||||||
} |
|
||||||
|
|
||||||
public void noMore() { |
|
||||||
if (iterator.hasNext()) { |
|
||||||
HtmlIssue next = iterator.next(); |
|
||||||
throw new AssertionError("\nNo more violations expected\ngot: at line " + next.line()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private void checkStateOfCurrent() { |
|
||||||
if (current == null) { |
|
||||||
throw new IllegalStateException("Prior to this method you should call next()"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public HtmlCheckMessagesVerifier atLine(@Nullable Integer expectedLine) { |
|
||||||
checkStateOfCurrent(); |
|
||||||
if (!Objects.equals(expectedLine, current.line())) { |
|
||||||
throw new AssertionError("\nExpected: " + expectedLine + "\ngot: " + current.line()); |
|
||||||
} |
|
||||||
return this; |
|
||||||
} |
|
||||||
|
|
||||||
public HtmlCheckMessagesVerifier atLocation(int startLine, int startColumn, int endLine, int endColumn) { |
|
||||||
checkStateOfCurrent(); |
|
||||||
PreciseHtmlIssue preciseHtmlIssue = (PreciseHtmlIssue) current; |
|
||||||
if (!Objects.equals(startLine, current.line())) { |
|
||||||
throw new AssertionError("\nExpected: " + startLine + "\ngot: " + current.line()); |
|
||||||
} |
|
||||||
if (!Objects.equals(startColumn, preciseHtmlIssue.startColumn())) { |
|
||||||
throw new AssertionError("\nExpected: " + startColumn + "\ngot: " + preciseHtmlIssue.startColumn()); |
|
||||||
} |
|
||||||
if (!Objects.equals(endLine, preciseHtmlIssue.endLine())) { |
|
||||||
throw new AssertionError("\nExpected: " + endLine + "\ngot: " + preciseHtmlIssue.endLine()); |
|
||||||
} |
|
||||||
if (!Objects.equals(endColumn, preciseHtmlIssue.endColumn())) { |
|
||||||
throw new AssertionError("\nExpected: " + endColumn + "\ngot: " + preciseHtmlIssue.endColumn()); |
|
||||||
} |
|
||||||
return this; |
|
||||||
} |
|
||||||
|
|
||||||
public HtmlCheckMessagesVerifier withMessage(String expectedMessage) { |
|
||||||
checkStateOfCurrent(); |
|
||||||
String actual = current.message(); |
|
||||||
if (!actual.equals(expectedMessage)) { |
|
||||||
throw new AssertionError("\nExpected: \"" + expectedMessage + "\"\ngot: \"" + actual + "\""); |
|
||||||
} |
|
||||||
return this; |
|
||||||
} |
|
||||||
|
|
||||||
public HtmlCheckMessagesVerifier withCost(@Nullable Double expectedCost) { |
|
||||||
checkStateOfCurrent(); |
|
||||||
if (!Objects.equals(expectedCost, current.cost())) { |
|
||||||
throw new AssertionError("\nExpected: " + expectedCost + "\ngot: " + current.cost()); |
|
||||||
} |
|
||||||
return this; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,43 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. |
|
||||||
* 项目名称:信息安全性设计准则检查插件 |
|
||||||
* 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 |
|
||||||
* 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 |
|
||||||
*/ |
|
||||||
|
|
||||||
package com.keyware.sonar.java.utils; |
|
||||||
|
|
||||||
import org.junit.jupiter.api.extension.AfterEachCallback; |
|
||||||
import org.junit.jupiter.api.extension.ExtensionContext; |
|
||||||
import org.sonar.plugins.html.checks.HtmlIssue; |
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.Collection; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
/** |
|
||||||
* Html规则校验 |
|
||||||
* |
|
||||||
* @author GuoXin |
|
||||||
* @date 2024/1/20 |
|
||||||
*/ |
|
||||||
public class HtmlCheckMessagesVerifierRule implements AfterEachCallback { |
|
||||||
private final List<HtmlCheckMessagesVerifier> verifiers = new ArrayList<>(); |
|
||||||
|
|
||||||
public HtmlCheckMessagesVerifier verify(Collection<HtmlIssue> messages) { |
|
||||||
HtmlCheckMessagesVerifier verifier = HtmlCheckMessagesVerifier.verify(messages); |
|
||||||
verifiers.add(verifier); |
|
||||||
return verifier; |
|
||||||
} |
|
||||||
|
|
||||||
protected void verify() { |
|
||||||
for (HtmlCheckMessagesVerifier verifier : verifiers) { |
|
||||||
verifier.noMore(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void afterEach(ExtensionContext extensionContext) throws Exception { |
|
||||||
verify(); |
|
||||||
} |
|
||||||
} |
|
@ -1,66 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. |
|
||||||
* 项目名称:信息安全性设计准则检查插件 |
|
||||||
* 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 |
|
||||||
* 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 |
|
||||||
*/ |
|
||||||
|
|
||||||
package com.keyware.sonar.java.utils; |
|
||||||
|
|
||||||
import org.sonar.api.batch.fs.InputFile; |
|
||||||
import org.sonar.api.batch.fs.internal.TestInputFileBuilder; |
|
||||||
import org.sonar.plugins.html.analyzers.ComplexityVisitor; |
|
||||||
import org.sonar.plugins.html.analyzers.PageCountLines; |
|
||||||
import org.sonar.plugins.html.api.HtmlConstants; |
|
||||||
import org.sonar.plugins.html.lex.PageLexer; |
|
||||||
import org.sonar.plugins.html.lex.VueLexer; |
|
||||||
import org.sonar.plugins.html.visitor.DefaultNodeVisitor; |
|
||||||
import org.sonar.plugins.html.visitor.HtmlAstScanner; |
|
||||||
import org.sonar.plugins.html.visitor.HtmlSourceCode; |
|
||||||
|
|
||||||
import java.io.File; |
|
||||||
import java.io.FileNotFoundException; |
|
||||||
import java.io.FileReader; |
|
||||||
import java.nio.charset.StandardCharsets; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
/** |
|
||||||
* Html测试工具类 |
|
||||||
* |
|
||||||
* @author GuoXin |
|
||||||
* @date 2024/1/20 |
|
||||||
*/ |
|
||||||
public class HtmlTestHelper { |
|
||||||
|
|
||||||
private HtmlTestHelper() { |
|
||||||
} |
|
||||||
|
|
||||||
public static HtmlSourceCode scan(File file, DefaultNodeVisitor visitor) { |
|
||||||
FileReader fileReader; |
|
||||||
try { |
|
||||||
fileReader = new FileReader(file); |
|
||||||
} catch (FileNotFoundException e) { |
|
||||||
throw new IllegalStateException(e); |
|
||||||
} |
|
||||||
|
|
||||||
HtmlSourceCode result = new HtmlSourceCode( |
|
||||||
new TestInputFileBuilder("key", file.getPath()) |
|
||||||
.setLanguage(HtmlConstants.LANGUAGE_KEY) |
|
||||||
.setType(InputFile.Type.MAIN) |
|
||||||
.setModuleBaseDir(new File(".").toPath()) |
|
||||||
.setCharset(StandardCharsets.UTF_8) |
|
||||||
.build() |
|
||||||
); |
|
||||||
|
|
||||||
HtmlAstScanner walker = new HtmlAstScanner(List.of(new PageCountLines(), new ComplexityVisitor())); |
|
||||||
PageLexer lexer = file.getName().endsWith(".vue") ? new VueLexer() : new PageLexer(); |
|
||||||
walker.addVisitor(visitor); |
|
||||||
walker.scan( |
|
||||||
lexer.parse(fileReader), |
|
||||||
result |
|
||||||
); |
|
||||||
|
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
Loading…
Reference in new issue