mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
Create a .qll file to reuse the code and add check of Spring properties
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
| configuration.properties:6:1:6:25 | ldap.password=mysecpass | Plaintext credentials ldap.password are loaded in getProperty(...) |
|
||||
| configuration.properties:18:1:18:35 | datasource1.password=Passw0rd@123 | Plaintext credentials datasource1.password are loaded in getProperty(...) |
|
||||
| configuration.properties:25:1:25:31 | mail.password=MysecPWxWa@1993 | Plaintext credentials mail.password are loaded in getProperty(...) |
|
||||
| configuration.properties:33:1:33:50 | com.example.aws.s3.access_key=AKMAMQPBYMCD6YSAYCBA | Plaintext credentials com.example.aws.s3.access_key are loaded in getProperty(...) |
|
||||
| configuration.properties:34:1:34:70 | com.example.aws.s3.secret_key=8lMPSfWzZq+wcWtck5+QPLOJDZzE783pS09/IO3k | Plaintext credentials com.example.aws.s3.secret_key are loaded in getProperty(...) |
|
||||
| configuration.properties:6:1:6:25 | ldap.password=mysecpass | Plaintext credentials ldap.password are loaded in Java Properties getProperty(...) |
|
||||
| configuration.properties:18:1:18:35 | datasource1.password=Passw0rd@123 | Plaintext credentials datasource1.password are loaded in Java Properties getProperty(...) |
|
||||
| configuration.properties:25:1:25:31 | mail.password=MysecPWxWa@1993 | Plaintext credentials mail.password are loaded in Spring annotation Value |
|
||||
| configuration.properties:33:1:33:50 | com.example.aws.s3.access_key=AKMAMQPBYMCD6YSAYCBA | Plaintext credentials com.example.aws.s3.access_key are loaded in Java Properties getProperty(...) |
|
||||
| configuration.properties:34:1:34:70 | com.example.aws.s3.secret_key=8lMPSfWzZq+wcWtck5+QPLOJDZzE783pS09/IO3k | Plaintext credentials com.example.aws.s3.secret_key are loaded in Java Properties getProperty(...) |
|
||||
|
||||
@@ -18,98 +18,7 @@
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.configfiles.ConfigFiles
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
|
||||
private string possibleSecretName() {
|
||||
result =
|
||||
[
|
||||
"%password%", "%passwd%", "%account%", "%accnt%", "%credential%", "%token%", "%secret%",
|
||||
"%access%key%"
|
||||
]
|
||||
}
|
||||
|
||||
private string possibleEncryptedSecretName() { result = ["%hashed%", "%encrypted%", "%crypt%"] }
|
||||
|
||||
/** Holds if the value is not cleartext credentials. */
|
||||
bindingset[value]
|
||||
predicate isNotCleartextCredentials(string value) {
|
||||
value = "" // Empty string
|
||||
or
|
||||
value.length() < 7 // Typical credentials are no less than 6 characters
|
||||
or
|
||||
value.matches("% %") // Sentences containing spaces
|
||||
or
|
||||
value.regexpMatch(".*[^a-zA-Z\\d]{3,}.*") // Contain repeated non-alphanumeric characters such as a fake password pass**** or ????
|
||||
or
|
||||
value.matches("@%") // Starts with the "@" sign
|
||||
or
|
||||
value.regexpMatch("\\$\\{.*\\}") // Variable placeholder ${credentials}
|
||||
or
|
||||
value.matches("%=") // A basic check of encrypted credentials ending with padding characters
|
||||
or
|
||||
value.matches("ENC(%)") // Encrypted value
|
||||
or
|
||||
// Could be a message property for UI display or fake passwords, e.g. login.password_expired=Your current password has expired.
|
||||
value.toLowerCase().matches(possibleSecretName())
|
||||
}
|
||||
|
||||
/** The credentials configuration property. */
|
||||
class CredentialsConfig extends ConfigPair {
|
||||
CredentialsConfig() {
|
||||
this.getNameElement().getName().trim().toLowerCase().matches(possibleSecretName()) and
|
||||
not this.getNameElement().getName().trim().toLowerCase().matches(possibleEncryptedSecretName()) and
|
||||
not isNotCleartextCredentials(this.getValueElement().getValue().trim())
|
||||
}
|
||||
|
||||
string getName() { result = this.getNameElement().getName().trim() }
|
||||
|
||||
string getValue() { result = this.getValueElement().getValue().trim() }
|
||||
|
||||
/** Returns a description of this vulnerability. */
|
||||
string getConfigDesc() {
|
||||
exists(
|
||||
LoadCredentialsConfiguration cc, DataFlow::Node source, DataFlow::Node sink, MethodAccess ma
|
||||
|
|
||||
this.getName() = source.asExpr().(CompileTimeConstantExpr).getStringValue() and
|
||||
cc.hasFlow(source, sink) and
|
||||
ma.getArgument(0) = sink.asExpr() and
|
||||
result = "Plaintext credentials " + this.getName() + " are loaded in " + ma
|
||||
)
|
||||
or
|
||||
not exists(LoadCredentialsConfiguration cc, DataFlow::Node source, DataFlow::Node sink |
|
||||
this.getName() = source.asExpr().(CompileTimeConstantExpr).getStringValue() and
|
||||
cc.hasFlow(source, sink)
|
||||
) and
|
||||
result =
|
||||
"Plaintext credentials " + this.getName() + " have cleartext value " + this.getValue() +
|
||||
" in properties file"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A dataflow configuration tracking flow of a method that loads a credentials property.
|
||||
*/
|
||||
class LoadCredentialsConfiguration extends DataFlow::Configuration {
|
||||
LoadCredentialsConfiguration() { this = "LoadCredentialsConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(CredentialsConfig cc |
|
||||
source.asExpr().(CompileTimeConstantExpr).getStringValue() = cc.getName()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
sink.asExpr() =
|
||||
any(MethodAccess ma |
|
||||
ma.getMethod()
|
||||
.getDeclaringType()
|
||||
.getASupertype*()
|
||||
.hasQualifiedName("java.util", "Properties") and
|
||||
ma.getMethod().getName() = "getProperty"
|
||||
).getArgument(0)
|
||||
}
|
||||
}
|
||||
import experimental.semmle.code.java.frameworks.CredentialsInPropertiesFile
|
||||
|
||||
from CredentialsConfig cc
|
||||
select cc, cc.getConfigDesc()
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class MailConfig {
|
||||
@Value("${mail.password}")
|
||||
private String mailPassword;
|
||||
|
||||
@Value("${mail.username}")
|
||||
private String mailUserName;
|
||||
}
|
||||
@@ -35,16 +35,6 @@ public class PropertiesUtils {
|
||||
return properties.getProperty("datasource1.password");
|
||||
}
|
||||
|
||||
/** Returns the mail account property value. */
|
||||
public static String getMailUserName() {
|
||||
return properties.getProperty("mail.username");
|
||||
}
|
||||
|
||||
/** Returns the mail password property value. */
|
||||
public static String getMailPassword() {
|
||||
return properties.getProperty("mail.password");
|
||||
}
|
||||
|
||||
/** Returns the AWS Access Key property value. */
|
||||
public static String getAWSAccessKey() {
|
||||
return properties.getProperty("com.example.aws.s3.access_key");
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.2.3
|
||||
Reference in New Issue
Block a user