mirror of
https://github.com/iflytek/skillhub.git
synced 2026-10-08 03:07:51 +00:00
fix(validation): preserve credential literal boundaries
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
This commit is contained in:
parent
7c62aa218a
commit
9d0431f7d3
2 changed files with 45 additions and 15 deletions
|
|
@ -17,6 +17,7 @@ import java.util.regex.Pattern;
|
|||
@Component
|
||||
public class BasicPrePublishValidator implements PrePublishValidator {
|
||||
|
||||
private static final int MIN_GENERIC_SECRET_LENGTH = 12;
|
||||
private static final Pattern ASSIGNMENT_WITH_SENSITIVE_KEY = Pattern.compile(
|
||||
"(?i)(api[_-]?key|access[_-]?key|secret|password|token)\\s*[:=]\\s*(.+)$"
|
||||
);
|
||||
|
|
@ -111,7 +112,7 @@ public class BasicPrePublishValidator implements PrePublishValidator {
|
|||
|
||||
String quotedLiteral = extractQuotedLiteral(rawValue);
|
||||
if (quotedLiteral != null) {
|
||||
return quotedLiteral;
|
||||
return quotedLiteral.length() >= MIN_GENERIC_SECRET_LENGTH ? quotedLiteral : null;
|
||||
}
|
||||
|
||||
rawValue = stripInlineComment(rawValue);
|
||||
|
|
@ -121,7 +122,7 @@ public class BasicPrePublishValidator implements PrePublishValidator {
|
|||
|
||||
quotedLiteral = extractQuotedLiteral(rawValue);
|
||||
if (quotedLiteral != null) {
|
||||
return quotedLiteral;
|
||||
return quotedLiteral.length() >= MIN_GENERIC_SECRET_LENGTH ? quotedLiteral : null;
|
||||
}
|
||||
|
||||
if (looksLikeExpression(rawValue) || IDENTIFIER.matcher(rawValue).matches()) {
|
||||
|
|
@ -153,24 +154,25 @@ public class BasicPrePublishValidator implements PrePublishValidator {
|
|||
continue;
|
||||
}
|
||||
if (current == quote) {
|
||||
return hasOnlyTrailingSyntax(rawValue, i + 1) ? rawValue.substring(1, i) : null;
|
||||
return hasLiteralTerminator(rawValue, i + 1) ? rawValue.substring(1, i) : null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean hasOnlyTrailingSyntax(String rawValue, int startIndex) {
|
||||
for (int i = startIndex; i < rawValue.length(); i++) {
|
||||
char current = rawValue.charAt(i);
|
||||
if (Character.isWhitespace(current) || isTrailingDelimiter(current)) {
|
||||
continue;
|
||||
}
|
||||
if (current == '#') {
|
||||
return true;
|
||||
}
|
||||
return current == '/' && i + 1 < rawValue.length() && rawValue.charAt(i + 1) == '/';
|
||||
private boolean hasLiteralTerminator(String rawValue, int startIndex) {
|
||||
int index = startIndex;
|
||||
while (index < rawValue.length() && Character.isWhitespace(rawValue.charAt(index))) {
|
||||
index++;
|
||||
}
|
||||
return true;
|
||||
if (index == rawValue.length()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
char current = rawValue.charAt(index);
|
||||
return isTrailingDelimiter(current)
|
||||
|| current == '#'
|
||||
|| (current == '/' && index + 1 < rawValue.length() && rawValue.charAt(index + 1) == '/');
|
||||
}
|
||||
|
||||
private boolean isTrailingDelimiter(char value) {
|
||||
|
|
|
|||
|
|
@ -136,8 +136,10 @@ class BasicPrePublishValidatorTest {
|
|||
github_token = "ghp_abcdefghijklmnopqrstuvwxyz1234"
|
||||
const token = "javascriptcredential123";
|
||||
const config = { token: "objectcredential123", };
|
||||
const options = { token: "multipropertycredential123", endpoint: "/api" };
|
||||
const escaped = { token: "credential\\\"value123" };
|
||||
""".getBytes(StandardCharsets.UTF_8),
|
||||
184,
|
||||
319,
|
||||
"text/javascript"
|
||||
);
|
||||
|
||||
|
|
@ -153,6 +155,32 @@ class BasicPrePublishValidatorTest {
|
|||
assertTrue(result.warnings().stream().anyMatch(warning -> warning.contains("line 2")));
|
||||
assertTrue(result.warnings().stream().anyMatch(warning -> warning.contains("line 3")));
|
||||
assertTrue(result.warnings().stream().anyMatch(warning -> warning.contains("line 4")));
|
||||
assertTrue(result.warnings().stream().anyMatch(warning -> warning.contains("line 5")));
|
||||
assertTrue(result.warnings().stream().anyMatch(warning -> warning.contains("line 6")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotWarnOnEmptyOrShortSensitiveLiterals() {
|
||||
PackageEntry script = new PackageEntry(
|
||||
"scripts/defaults.py",
|
||||
"""
|
||||
token = ""
|
||||
client_secret = "short"
|
||||
password = 'unset'
|
||||
""".getBytes(StandardCharsets.UTF_8),
|
||||
58,
|
||||
"text/x-python"
|
||||
);
|
||||
|
||||
ValidationResult result = validator.validate(new PrePublishValidator.SkillPackageContext(
|
||||
List.of(script),
|
||||
new SkillMetadata("Defaults Skill", "desc", "1.0.0", "body", Map.of()),
|
||||
"user-1",
|
||||
1L
|
||||
));
|
||||
|
||||
assertTrue(result.passed());
|
||||
assertTrue(result.warnings().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue