diff --git a/rules/002_domain_model/002_0009_no_default_value.rego b/rules/002_domain_model/002_0009_no_default_value.rego new file mode 100644 index 0000000..ea79a29 --- /dev/null +++ b/rules/002_domain_model/002_0009_no_default_value.rego @@ -0,0 +1,48 @@ +# METADATA +# scope: package +# title: Do not use default values on attributes +# description: Avoid default values because it introduces hidden logic that is hard to detect via "find changes". +# authors: +# - Rick Schreuder +# custom: +# category: Maintainability +# rulename: NoDefaultValue +# severity: LOW +# rulenumber: 002_0009 +# remediation: Remove the attribute default value and set it explicitly in logic where needed. +# input: .*DomainModels\$DomainModel\.yaml + +package app.mendix.domain_model.no_default_value + +import rego.v1 + +# Load custom rule annotations (severity, category, rule number). +annotation := rego.metadata.chain()[1].annotations + +# The file is valid only if no rule violations are found. +default allow := false +allow if count(errors) == 0 + +# A default value is considered "set" if it exists AND it is not the empty string. +has_default_value(default_value) if { + default_value != null + default_value != "" +} + +# Emit an error for each attribute that defines a DefaultValue. +errors contains error_message if { + + some entity in input.Entities + some attribute in entity.Attributes + has_default_value(attribute.Value.DefaultValue) + + error_message := sprintf("[%v, %v, %v] %v.%v has a default value set", + [ + annotation.custom.severity, + annotation.custom.category, + annotation.custom.rulenumber, + entity.Name, + attribute.Name + ] + ) +} \ No newline at end of file diff --git a/rules/002_domain_model/002_0009_no_default_value_test.yaml b/rules/002_domain_model/002_0009_no_default_value_test.yaml new file mode 100644 index 0000000..148e366 --- /dev/null +++ b/rules/002_domain_model/002_0009_no_default_value_test.yaml @@ -0,0 +1,23 @@ +TestCases: +- name: allow attributes with no default value or empty/null default value + allow: true + input: + Entities: + - Name: Entity1 + Attributes: + - Name: Attr1 + - Name: Attr2 + Value: + DefaultValue: null + - Name: Attr3 + Value: + DefaultValue: "" +- name: deny attribute with a default value set + allow: false + input: + Entities: + - Name: Entity1 + Attributes: + - Name: Attr1 + Value: + DefaultValue: "0" \ No newline at end of file diff --git a/rules/006_security/006_0001_exposed_constants.rego b/rules/006_security/006_0001_exposed_constants.rego new file mode 100644 index 0000000..f5f8ae8 --- /dev/null +++ b/rules/006_security/006_0001_exposed_constants.rego @@ -0,0 +1,69 @@ +# METADATA +# scope: package +# title: Exposed constants with sensitive data +# description: Constants with potentially sensitive data should not be exposed to the client. +# authors: +# - Bart Zantingh +# custom: +# category: Security +# rulename: ExposedConstants +# severity: HIGH +# rulenumber: "006_0001" +# remediation: Set constant's 'Exposed to client' setting to false. +# input: "**/*$Constant.yaml" +package app.mendix.constants.exposed_constants + +import rego.v1 + +annotation := rego.metadata.chain()[1].annotations + +default allow := false + +allow if count(errors) == 0 + +exposed := input.ExposedToClient + +errors contains error if { + exposed + + name := input.Name + + error := sprintf( + "[%v, %v, %v] Constant %v is exposed to the client", + [ + "MEDIUM", + annotation.custom.category, + annotation.custom.rulenumber, + name, + ], + ) +} + +errors contains error if { + contains_sensitive_data + exposed + + name := input.Name + + error := sprintf( + "[%v, %v, %v] Constant %v is exposed to the client, and seems to contain sensitive data", + [ + annotation.custom.severity, + annotation.custom.category, + annotation.custom.rulenumber, + name, + ], + ) +} + +sensitive_keywords := [ + "id", "ident", + "username", "user_name", "user", "usr", "uname", + "secret", "scrt", + "password", "pwd", "passwrd", +] + +contains_sensitive_data if { + some keyword in sensitive_keywords + contains(lower(input.Name), keyword) +} diff --git a/rules/006_security/006_0001_exposed_constants_test.yaml b/rules/006_security/006_0001_exposed_constants_test.yaml new file mode 100644 index 0000000..598f8cc --- /dev/null +++ b/rules/006_security/006_0001_exposed_constants_test.yaml @@ -0,0 +1,16 @@ +TestCases: +- name: allow not exposed with sensitive name + allow: true + input: + ExposedToClient: false + Name: CST_TestConstant_password +- name: allow not exposed without sensitive name + allow: true + input: + ExposedToClient: false + Name: CST_TestConstant +- name: deny exposed with sensitive name + allow: false + input: + ExposedToClient: true + Name: CST_TestConstant_Id