diff --git a/.coverage.json b/.coverage.json index 7e84ec4..e3627e8 100644 --- a/.coverage.json +++ b/.coverage.json @@ -1,8 +1,23 @@ { "queries": [ + { + "path": "ql/src/security/CWE-404/DatabaseNoGeoRedundantBackup.ql", + "name": "DatabaseNoGeoRedundantBackup", + "category": "security", + "cwe": "CWE-404", + "covered": false, + "test_files": [] + }, + { + "path": "ql/src/security/CWE-404/CosmosDBNoBackupPolicy.ql", + "name": "CosmosDBNoBackupPolicy", + "category": "security", + "cwe": "CWE-404", + "covered": false, + "test_files": [] + }, { "path": "ql/src/security/CWE-200/PublicResource.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-200/PublicResource.ql", "name": "PublicResource", "category": "security", "cwe": "CWE-200", @@ -11,7 +26,6 @@ }, { "path": "ql/src/security/CWE-200/GrafanaExternalSnapshotsEnabled.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-200/GrafanaExternalSnapshotsEnabled.ql", "name": "GrafanaExternalSnapshotsEnabled", "category": "security", "cwe": "CWE-200", @@ -19,161 +33,143 @@ "test_files": [] }, { - "path": "ql/src/security/CWE-284/DatabasePublicNetworkAccess.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-284/DatabasePublicNetworkAccess.ql", - "name": "DatabasePublicNetworkAccess", + "path": "ql/src/security/CWE-319/DatabaseSslNotEnforced.ql", + "name": "DatabaseSslNotEnforced", "category": "security", - "cwe": "CWE-284", + "cwe": "CWE-319", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-284/RedisCachePublicNetwork.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-284/RedisCachePublicNetwork.ql", - "name": "RedisCachePublicNetwork", + "path": "ql/src/security/CWE-319/GrafanaInsecureStartTLSPolicy.ql", + "name": "GrafanaInsecureStartTLSPolicy", "category": "security", - "cwe": "CWE-284", + "cwe": "CWE-319", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-306/RedisCacheNoAuth.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-306/RedisCacheNoAuth.ql", - "name": "RedisCacheNoAuth", + "path": "ql/src/security/CWE-319/RedisCacheNonSslPort.ql", + "name": "RedisCacheNonSslPort", "category": "security", - "cwe": "CWE-306", + "cwe": "CWE-319", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-306/GrafanaApiKeyEnabled.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-306/GrafanaApiKeyEnabled.ql", - "name": "GrafanaApiKeyEnabled", + "path": "ql/src/security/CWE-319/SslEnforement.ql", + "name": "SslEnforement", "category": "security", - "cwe": "CWE-306", + "cwe": "CWE-319", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-319/GrafanaInsecureStartTLSPolicy.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-319/GrafanaInsecureStartTLSPolicy.ql", - "name": "GrafanaInsecureStartTLSPolicy", + "path": "ql/src/security/CWE-327/TlsDisabled.ql", + "name": "TlsDisabled", "category": "security", - "cwe": "CWE-319", + "cwe": "CWE-327", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-319/DatabaseSslNotEnforced.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-319/DatabaseSslNotEnforced.ql", - "name": "DatabaseSslNotEnforced", + "path": "ql/src/security/CWE-327/WeakTlsVersion.ql", + "name": "WeakTlsVersion", "category": "security", - "cwe": "CWE-319", + "cwe": "CWE-327", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-319/SslEnforement.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-319/SslEnforement.ql", - "name": "SslEnforement", + "path": "ql/src/security/CWE-327/DatabaseWeakTlsVersion.ql", + "name": "DatabaseWeakTlsVersion", "category": "security", - "cwe": "CWE-319", + "cwe": "CWE-327", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-319/RedisCacheNonSslPort.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-319/RedisCacheNonSslPort.ql", - "name": "RedisCacheNonSslPort", + "path": "ql/src/security/CWE-311/AKSWithoutDiskEncryption.ql", + "name": "AKSWithoutDiskEncryption", "category": "security", - "cwe": "CWE-319", + "cwe": "CWE-311", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-352/GrafanaCsrfDisabled.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-352/GrafanaCsrfDisabled.ql", - "name": "GrafanaCsrfDisabled", + "path": "ql/src/security/CWE-311/DatabaseNoInfrastructureEncryption.ql", + "name": "DatabaseNoInfrastructureEncryption", "category": "security", - "cwe": "CWE-352", + "cwe": "CWE-311", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-327/DatabaseWeakTlsVersion.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-327/DatabaseWeakTlsVersion.ql", - "name": "DatabaseWeakTlsVersion", + "path": "ql/src/security/CWE-942/InsecureCorsAllMethods.ql", + "name": "InsecureCorsAllMethods", "category": "security", - "cwe": "CWE-327", + "cwe": "CWE-942", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-327/WeakTlsVersion.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-327/WeakTlsVersion.ql", - "name": "WeakTlsVersion", + "path": "ql/src/security/CWE-942/InsecureCorsWildcardOrigin.ql", + "name": "InsecureCorsWildcardOrigin", "category": "security", - "cwe": "CWE-327", + "cwe": "CWE-942", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-327/TlsDisabled.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-327/TlsDisabled.ql", - "name": "TlsDisabled", + "path": "ql/src/security/CWE-942/InsecureCorsAllowCredentialsWildcard.ql", + "name": "InsecureCorsAllowCredentialsWildcard", "category": "security", - "cwe": "CWE-327", + "cwe": "CWE-942", "covered": false, "test_files": [] }, { - "path": "ql/src/security/AKS/AKSPublicApi.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/AKS/AKSPublicApi.ql", - "name": "AKSPublicApi", + "path": "ql/src/security/CWE-942/InsecureCorsAllHeaders.ql", + "name": "InsecureCorsAllHeaders", "category": "security", - "cwe": "", + "cwe": "CWE-942", "covered": false, "test_files": [] }, { - "path": "ql/src/security/AKS/AKSKubeDashboardEnabled.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/AKS/AKSKubeDashboardEnabled.ql", - "name": "AKSKubeDashboardEnabled", + "path": "ql/src/security/CWE-284/AKSPublicNetworkAccess.ql", + "name": "AKSPublicNetworkAccess", "category": "security", - "cwe": "", + "cwe": "CWE-284", "covered": false, "test_files": [] }, { - "path": "ql/src/security/AKS/AKSPrivateApiEnabled.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/AKS/AKSPrivateApiEnabled.ql", - "name": "AKSPrivateApiEnabled", + "path": "ql/src/security/CWE-284/AKSRbacDisabled.ql", + "name": "AKSRbacDisabled", "category": "security", - "cwe": "", + "cwe": "CWE-284", "covered": false, "test_files": [] }, { - "path": "ql/src/security/Dashboards/GrafanaMissingZoneRedundancy.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/Dashboards/GrafanaMissingZoneRedundancy.ql", - "name": "GrafanaMissingZoneRedundancy", + "path": "ql/src/security/CWE-284/DatabasePublicNetworkAccess.ql", + "name": "DatabasePublicNetworkAccess", "category": "security", - "cwe": "", + "cwe": "CWE-284", "covered": false, "test_files": [] }, { - "path": "ql/src/security/Storage/SupportHttpTraffic.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/Storage/SupportHttpTraffic.ql", - "name": "SupportHttpTraffic", + "path": "ql/src/security/CWE-284/RedisCachePublicNetwork.ql", + "name": "RedisCachePublicNetwork", "category": "security", - "cwe": "", + "cwe": "CWE-284", "covered": false, "test_files": [] }, { - "path": "ql/src/security/Storage/PublicAccess.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/Storage/PublicAccess.ql", + "path": "ql/src/security/storage/PublicAccess.ql", "name": "PublicAccess", "category": "security", "cwe": "", @@ -181,80 +177,71 @@ "test_files": [] }, { - "path": "ql/src/security/CWE-272/GrafanaExcessiveEditorPermissions.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-272/GrafanaExcessiveEditorPermissions.ql", - "name": "GrafanaExcessiveEditorPermissions", + "path": "ql/src/security/storage/SupportHttpTraffic.ql", + "name": "SupportHttpTraffic", "category": "security", - "cwe": "CWE-272", + "cwe": "", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-272/GrafanaExcessiveViewerPermissions.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-272/GrafanaExcessiveViewerPermissions.ql", - "name": "GrafanaExcessiveViewerPermissions", + "path": "ql/src/security/AKS/AKSPrivateApiEnabled.ql", + "name": "AKSPrivateApiEnabled", "category": "security", - "cwe": "CWE-272", + "cwe": "", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-311/DatabaseNoInfrastructureEncryption.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-311/DatabaseNoInfrastructureEncryption.ql", - "name": "DatabaseNoInfrastructureEncryption", + "path": "ql/src/security/AKS/AKSKubeDashboardEnabled.ql", + "name": "AKSKubeDashboardEnabled", "category": "security", - "cwe": "CWE-311", + "cwe": "", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-400/RedisCacheUnsafeMemoryPolicy.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-400/RedisCacheUnsafeMemoryPolicy.ql", - "name": "RedisCacheUnsafeMemoryPolicy", + "path": "ql/src/security/AKS/AKSPublicApi.ql", + "name": "AKSPublicApi", "category": "security", - "cwe": "CWE-400", + "cwe": "", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-942/InsecureCorsAllHeaders.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-942/InsecureCorsAllHeaders.ql", - "name": "InsecureCorsAllHeaders", + "path": "ql/src/security/CWE-400/RedisCacheUnsafeMemoryPolicy.ql", + "name": "RedisCacheUnsafeMemoryPolicy", "category": "security", - "cwe": "CWE-942", + "cwe": "CWE-400", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-942/InsecureCorsAllowCredentialsWildcard.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-942/InsecureCorsAllowCredentialsWildcard.ql", - "name": "InsecureCorsAllowCredentialsWildcard", + "path": "ql/src/security/CWE-400/AKSNodeAutoScalingDisabled.ql", + "name": "AKSNodeAutoScalingDisabled", "category": "security", - "cwe": "CWE-942", + "cwe": "CWE-400", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-942/InsecureCorsWildcardOrigin.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-942/InsecureCorsWildcardOrigin.ql", - "name": "InsecureCorsWildcardOrigin", + "path": "ql/src/security/CWE-668/AKSInsecureNetworkPolicy.ql", + "name": "AKSInsecureNetworkPolicy", "category": "security", - "cwe": "CWE-942", + "cwe": "CWE-668", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-942/InsecureCorsAllMethods.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-942/InsecureCorsAllMethods.ql", - "name": "InsecureCorsAllMethods", + "path": "ql/src/security/CWE-295/GrafanaSmtpSslVerificationDisabled.ql", + "name": "GrafanaSmtpSslVerificationDisabled", "category": "security", - "cwe": "CWE-942", + "cwe": "CWE-295", "covered": false, "test_files": [] }, { "path": "ql/src/security/CWE-693/RedisCacheNoBackup.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-693/RedisCacheNoBackup.ql", "name": "RedisCacheNoBackup", "category": "security", "cwe": "CWE-693", @@ -262,17 +249,23 @@ "test_files": [] }, { - "path": "ql/src/security/CWE-295/GrafanaSmtpSslVerificationDisabled.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-295/GrafanaSmtpSslVerificationDisabled.ql", - "name": "GrafanaSmtpSslVerificationDisabled", + "path": "ql/src/security/Dashboards/GrafanaMissingZoneRedundancy.ql", + "name": "GrafanaMissingZoneRedundancy", "category": "security", - "cwe": "CWE-295", + "cwe": "", + "covered": false, + "test_files": [] + }, + { + "path": "ql/src/security/CWE-798/HardcodedSmtpCredentials.ql", + "name": "HardcodedSmtpCredentials", + "category": "security", + "cwe": "CWE-798", "covered": false, "test_files": [] }, { "path": "ql/src/security/CWE-798/RedisCacheNoAAD.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-798/RedisCacheNoAAD.ql", "name": "RedisCacheNoAAD", "category": "security", "cwe": "CWE-798", @@ -280,35 +273,63 @@ "test_files": [] }, { - "path": "ql/src/security/CWE-798/HardcodedSmtpCredentials.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-798/HardcodedSmtpCredentials.ql", - "name": "HardcodedSmtpCredentials", + "path": "ql/src/security/CWE-306/RedisCacheNoAuth.ql", + "name": "RedisCacheNoAuth", "category": "security", - "cwe": "CWE-798", + "cwe": "CWE-306", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-404/CosmosDBNoBackupPolicy.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-404/CosmosDBNoBackupPolicy.ql", - "name": "CosmosDBNoBackupPolicy", + "path": "ql/src/security/CWE-306/AKSLocalAccountsEnabled.ql", + "name": "AKSLocalAccountsEnabled", "category": "security", - "cwe": "CWE-404", + "cwe": "CWE-306", "covered": false, "test_files": [] }, { - "path": "ql/src/security/CWE-404/DatabaseNoGeoRedundantBackup.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/security/CWE-404/DatabaseNoGeoRedundantBackup.ql", - "name": "DatabaseNoGeoRedundantBackup", + "path": "ql/src/security/CWE-306/GrafanaApiKeyEnabled.ql", + "name": "GrafanaApiKeyEnabled", "category": "security", - "cwe": "CWE-404", + "cwe": "CWE-306", + "covered": false, + "test_files": [] + }, + { + "path": "ql/src/security/CWE-352/GrafanaCsrfDisabled.ql", + "name": "GrafanaCsrfDisabled", + "category": "security", + "cwe": "CWE-352", + "covered": false, + "test_files": [] + }, + { + "path": "ql/src/security/CWE-272/GrafanaExcessiveViewerPermissions.ql", + "name": "GrafanaExcessiveViewerPermissions", + "category": "security", + "cwe": "CWE-272", + "covered": false, + "test_files": [] + }, + { + "path": "ql/src/security/CWE-272/GrafanaExcessiveEditorPermissions.ql", + "name": "GrafanaExcessiveEditorPermissions", + "category": "security", + "cwe": "CWE-272", + "covered": false, + "test_files": [] + }, + { + "path": "ql/src/testing/test.ql", + "name": "test", + "category": "testing", + "cwe": "", "covered": false, "test_files": [] }, { "path": "ql/src/diagnostics/ExtractionErrors.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/diagnostics/ExtractionErrors.ql", "name": "ExtractionErrors", "category": "diagnostics", "cwe": "", @@ -317,7 +338,6 @@ }, { "path": "ql/src/diagnostics/SuccessfullyExtractedFiles.ql", - "absolute_path": "/home/geekmasher/development/github/codeql-extractor-bicep/ql/src/diagnostics/SuccessfullyExtractedFiles.ql", "name": "SuccessfullyExtractedFiles", "category": "diagnostics", "cwe": "", @@ -326,27 +346,29 @@ } ], "metadata": { - "total_queries": 36, + "total_queries": 43, "covered_queries": 0, "categories": [ + "testing", "diagnostics", "security" ], "cwes": [ - "CWE-200", - "CWE-306", + "CWE-668", "CWE-311", - "CWE-942", "CWE-400", + "CWE-306", + "CWE-352", "CWE-319", - "CWE-693", - "CWE-327", + "CWE-942", + "CWE-272", "CWE-284", "CWE-295", - "CWE-404", - "CWE-352", + "CWE-200", + "CWE-327", "CWE-798", - "CWE-272" + "CWE-693", + "CWE-404" ], "coverage_percentage": 0.0 } diff --git a/README.md b/README.md index e3f1a6c..0f9f61f 100644 --- a/README.md +++ b/README.md @@ -31,18 +31,19 @@ | Metric | Value | |--------|-------| -| Total Queries | 36 | +| Total Queries | 43 | | Covered Queries | 0 | | Coverage Percentage | 0.0% | -| Categories | 2 | -| CWE Categories | 14 | +| Categories | 3 | +| CWE Categories | 15 | ### Coverage by Category | Category | Covered | Total | Percentage | |----------|---------|-------|------------| | Diagnostics | 0 | 2 | 0.0% | -| Security | 0 | 34 | 0.0% | +| Security | 0 | 40 | 0.0% | +| Testing | 0 | 1 | 0.0% | ### Coverage by CWE @@ -50,20 +51,21 @@ |-----|-------------|---------|-------|------------| | CWE-200 | Information Exposure | 0 | 2 | 0.0% | | CWE-272 | Least Privilege Violation | 0 | 2 | 0.0% | -| CWE-284 | Improper Access Control | 0 | 2 | 0.0% | +| CWE-284 | Improper Access Control | 0 | 4 | 0.0% | | CWE-295 | Improper Certificate Validation | 0 | 1 | 0.0% | -| CWE-306 | Missing Authentication | 0 | 2 | 0.0% | -| CWE-311 | Missing Encryption | 0 | 1 | 0.0% | +| CWE-306 | Missing Authentication | 0 | 3 | 0.0% | +| CWE-311 | Missing Encryption | 0 | 2 | 0.0% | | CWE-319 | Cleartext Transmission | 0 | 4 | 0.0% | | CWE-327 | Broken/Risky Crypto Algorithm | 0 | 3 | 0.0% | | CWE-352 | Cross-Site Request Forgery | 0 | 1 | 0.0% | -| CWE-400 | Resource Exhaustion | 0 | 1 | 0.0% | +| CWE-400 | Resource Exhaustion | 0 | 2 | 0.0% | | CWE-404 | Improper Resource Shutdown | 0 | 2 | 0.0% | +| CWE-668 | Security Vulnerability | 0 | 1 | 0.0% | | CWE-693 | Protection Mechanism Failure | 0 | 1 | 0.0% | | CWE-798 | Hard-coded Credentials | 0 | 2 | 0.0% | | CWE-942 | Overly Permissive CORS | 0 | 4 | 0.0% | -*Last updated: 2025-06-17 15:45:17 UTC* +*Last updated: 2025-06-25 14:04:04 UTC* diff --git a/ql/src/security/CWE-284/AKSPublicNetworkAccess.md b/ql/src/security/CWE-284/AKSPublicNetworkAccess.md new file mode 100644 index 0000000..44bac35 --- /dev/null +++ b/ql/src/security/CWE-284/AKSPublicNetworkAccess.md @@ -0,0 +1,67 @@ +# AKS cluster with public network access enabled + +Azure Kubernetes Service (AKS) clusters with public network access enabled can be accessed from any public IP address, which may expose the cluster to potential attackers on the internet. + +## Problem statement + +When public network access is enabled on an AKS cluster (which is the default setting), the Kubernetes API server is accessible from the internet. This increases the attack surface of the cluster and makes it vulnerable to various attacks including brute force attempts, exploitation of known vulnerabilities, and unauthorized access attempts. + +## Recommendation + +Disable public network access by setting the `publicNetworkAccess` property to `'Disabled'` and enable private cluster access using `apiServerAccessProfile.enablePrivateCluster` set to `true`. This ensures that the Kubernetes API server is only accessible from within your virtual network. + +```bicep +resource aksCluster 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'secureAksCluster' + location: location + properties: { + // Other properties... + publicNetworkAccess: 'Disabled' + apiServerAccessProfile: { + enablePrivateCluster: true + } + // Other properties... + } +} +``` + +## Example + +### Insecure configuration (Public network access enabled) + +```bicep +resource aksClusterInsecure 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterInsecure' + location: location + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdns' + publicNetworkAccess: 'Enabled' // Insecure: Public network access is enabled + // Default with no apiServerAccessProfile is also insecure + // Other properties... + } +} +``` + +### Secure configuration (Public network access disabled) + +```bicep +resource aksClusterSecure 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterSecure' + location: location + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdns' + publicNetworkAccess: 'Disabled' // Secure: Public network access is disabled + apiServerAccessProfile: { + enablePrivateCluster: true // Secure: Private cluster is enabled + } + // Other properties... + } +} +``` + +## References + +* [Azure Kubernetes Service (AKS) network concepts](https://learn.microsoft.com/en-us/azure/aks/concepts-network) +* [Create a private AKS cluster](https://learn.microsoft.com/en-us/azure/aks/private-clusters) diff --git a/ql/src/security/CWE-284/AKSPublicNetworkAccess.ql b/ql/src/security/CWE-284/AKSPublicNetworkAccess.ql new file mode 100644 index 0000000..3ca10ab --- /dev/null +++ b/ql/src/security/CWE-284/AKSPublicNetworkAccess.ql @@ -0,0 +1,33 @@ +/** + * @name AKS cluster with public network access enabled + * @description Detects Azure Kubernetes Service (AKS) clusters with public network access enabled, which can expose the cluster to potential unauthorized access. + * @kind problem + * @problem.severity warning + * @security-severity 6.5 + * @precision high + * @id bicep/aks-public-network-access + * @tags security + * bicep + * azure + * CWE-284 + */ + +import codeql.bicep.frameworks.Microsoft.AKS + +from AKS::ManagedContainerResource resource, AKS::ManagedContainerProperties::Properties properties +where + properties = resource.getProperties() and + ( + ( + exists(properties.getPublicNetworkAccess()) and + properties.getPublicNetworkAccess().getValue().toLowerCase() = "enabled" + ) or + not exists(properties.getPublicNetworkAccess()) // Default is "enabled" if not specified + ) and + // Exclude clusters that have private API server enabled + ( + not exists(properties.getApiServerAccessProfile()) or + not exists(properties.getApiServerAccessProfile().getEnablePrivateCluster()) or + properties.getApiServerAccessProfile().enablePrivateCluster() = false + ) +select resource, "AKS cluster has public network access enabled, which can expose the cluster to unauthorized access." diff --git a/ql/src/security/CWE-284/AKSRbacDisabled.md b/ql/src/security/CWE-284/AKSRbacDisabled.md new file mode 100644 index 0000000..b85713e --- /dev/null +++ b/ql/src/security/CWE-284/AKSRbacDisabled.md @@ -0,0 +1,60 @@ +# AKS cluster with RBAC disabled + +Azure Kubernetes Service (AKS) clusters should have Role-Based Access Control (RBAC) enabled to properly restrict access to cluster resources based on user roles and permissions. + +## Problem statement + +When RBAC is disabled in AKS, anyone with access to the cluster can potentially perform any action on any resource within the cluster. This creates a significant security vulnerability as there's no fine-grained access control to protect sensitive operations. + +## Recommendation + +Always enable RBAC for AKS clusters by setting `enableRBAC` to `true` in your Bicep template: + +```bicep +resource aksCluster 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'secureAksCluster' + location: location + properties: { + // Other properties... + enableRBAC: true + // Other properties... + } +} +``` + +## Example + +### Insecure configuration (RBAC disabled) + +```bicep +resource aksClusterInsecure 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterInsecure' + location: location + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdns' + enableRBAC: false // Insecure: RBAC is disabled + // Other properties... + } +} +``` + +### Secure configuration (RBAC enabled) + +```bicep +resource aksClusterSecure 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterSecure' + location: location + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdns' + enableRBAC: true // Secure: RBAC is enabled + // Other properties... + } +} +``` + +## References + +* [Azure Kubernetes Service RBAC](https://learn.microsoft.com/en-us/azure/aks/concepts-identity#kubernetes-rbac) +* [Security best practices for AKS](https://learn.microsoft.com/en-us/azure/aks/security-best-practices) diff --git a/ql/src/security/CWE-284/AKSRbacDisabled.ql b/ql/src/security/CWE-284/AKSRbacDisabled.ql new file mode 100644 index 0000000..2d3d31a --- /dev/null +++ b/ql/src/security/CWE-284/AKSRbacDisabled.ql @@ -0,0 +1,25 @@ +/** + * @name AKS cluster with RBAC disabled + * @description Detects Azure Kubernetes Service (AKS) clusters where RBAC is disabled, which can lead to unauthorized access to the cluster. + * @kind problem + * @problem.severity warning + * @security-severity 7.5 + * @precision high + * @id bicep/aks-rbac-disabled + * @tags security + * bicep + * azure + * CWE-284 + */ + +import codeql.bicep.frameworks.Microsoft.AKS + +from AKS::ManagedContainerResource resource, AKS::ManagedContainerProperties::Properties properties +where + properties = resource.getProperties() and + ( + // RBAC is explicitly disabled + exists(properties.getEnableRBAC()) and + properties.getEnableRBAC().getBool() = false + ) +select resource, "AKS cluster has RBAC disabled, which can lead to unauthorized access to the cluster." diff --git a/ql/src/security/CWE-306/AKSLocalAccountsEnabled.md b/ql/src/security/CWE-306/AKSLocalAccountsEnabled.md new file mode 100644 index 0000000..ceee5f6 --- /dev/null +++ b/ql/src/security/CWE-306/AKSLocalAccountsEnabled.md @@ -0,0 +1,74 @@ +# AKS cluster with local accounts enabled + +Azure Kubernetes Service (AKS) clusters should have local Kubernetes accounts disabled in favor of Azure Active Directory (Azure AD) integration for stronger authentication controls. + +## Problem statement + +When local accounts are enabled in AKS clusters: + +1. Authentication relies on locally stored credentials rather than centralized Azure AD identities +2. User access management is more manual and error-prone +3. Central audit and monitoring of access is more difficult +4. Advanced security features like Conditional Access policies cannot be applied + +## Recommendation + +Disable local accounts in AKS clusters by setting `disableLocalAccounts` to `true` and configure Azure AD integration: + +```bicep +resource aksCluster 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'secureAksCluster' + location: location + properties: { + // Other properties... + disableLocalAccounts: true + aadProfile: { + managed: true + enableAzureRBAC: true + } + // Other properties... + } +} +``` + +## Example + +### Insecure configuration (Local accounts enabled) + +```bicep +resource aksClusterInsecure 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterInsecure' + location: location + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdns' + disableLocalAccounts: false // Insecure: Local accounts are explicitly enabled + // Or omitting disableLocalAccounts entirely (defaults to false) + // Other properties... + } +} +``` + +### Secure configuration (Local accounts disabled) + +```bicep +resource aksClusterSecure 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterSecure' + location: location + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdns' + disableLocalAccounts: true // Secure: Local accounts are disabled + aadProfile: { + managed: true + enableAzureRBAC: true + } + // Other properties... + } +} +``` + +## References + +* [Use Azure AD with AKS](https://learn.microsoft.com/en-us/azure/aks/managed-aad) +* [AKS best practices for authentication and authorization](https://learn.microsoft.com/en-us/azure/aks/operator-best-practices-identity) diff --git a/ql/src/security/CWE-306/AKSLocalAccountsEnabled.ql b/ql/src/security/CWE-306/AKSLocalAccountsEnabled.ql new file mode 100644 index 0000000..b5fab01 --- /dev/null +++ b/ql/src/security/CWE-306/AKSLocalAccountsEnabled.ql @@ -0,0 +1,24 @@ +/** + * @name AKS cluster with local accounts enabled + * @description Detects Azure Kubernetes Service (AKS) clusters with local accounts enabled, which can lead to weaker authentication controls. + * @kind problem + * @problem.severity warning + * @security-severity 5.0 + * @precision high + * @id bicep/aks-local-accounts-enabled + * @tags security + * bicep + * azure + * CWE-306 + */ + +import codeql.bicep.frameworks.Microsoft.AKS + +from AKS::ManagedContainerResource resource, AKS::ManagedContainerProperties::Properties properties +where + properties = resource.getProperties() and + ( + not exists(properties.getDisableLocalAccounts()) or + properties.getDisableLocalAccounts().getBool() = false + ) +select resource, "AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication." diff --git a/ql/src/security/CWE-311/AKSWithoutDiskEncryption.md b/ql/src/security/CWE-311/AKSWithoutDiskEncryption.md new file mode 100644 index 0000000..96a22a0 --- /dev/null +++ b/ql/src/security/CWE-311/AKSWithoutDiskEncryption.md @@ -0,0 +1,78 @@ +# AKS cluster without disk encryption + +Azure Kubernetes Service (AKS) clusters should utilize disk encryption to protect sensitive data at rest. Without disk encryption, data stored on node disks could be vulnerable to unauthorized access if the storage is compromised. + +## Problem statement + +When an AKS cluster is configured without disk encryption: + +1. Node VM disks including OS disks and data disks could store data in an unencrypted format +2. In case of physical theft, hardware decommissioning, or improper disk handling, sensitive data might be exposed +3. Security and compliance requirements (like HIPAA, PCI DSS, or GDPR) may be violated +4. If a node is compromised, an attacker may be able to access data directly from the disk + +## Recommendation + +Configure disk encryption for your AKS cluster by setting a disk encryption set ID: + +```bicep +resource diskEncryptionSet 'Microsoft.Compute/diskEncryptionSets@2022-07-02' = { + name: 'myDiskEncryptionSet' + location: location + identity: { + type: 'SystemAssigned' + } + properties: { + activeKey: { + keyUrl: keyVault.getSecret('encryptionKey').id + } + } +} + +resource aksCluster 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'secureAksCluster' + location: location + properties: { + // Other properties... + diskEncryptionSetID: diskEncryptionSet.id + // Other properties... + } +} +``` + +## Example + +### Insecure configuration (No disk encryption) + +```bicep +resource aksClusterInsecure 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterInsecure' + location: location + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdns' + // Missing diskEncryptionSetID + // Other properties... + } +} +``` + +### Secure configuration (With disk encryption) + +```bicep +resource aksClusterSecure 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterSecure' + location: location + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdns' + diskEncryptionSetID: diskEncryptionSet.id // Secure: Using disk encryption + // Other properties... + } +} +``` + +## References + +* [Azure Disk Encryption for AKS clusters](https://learn.microsoft.com/en-us/azure/aks/azure-disk-customer-managed-keys) +* [Data encryption in AKS](https://learn.microsoft.com/en-us/azure/aks/concepts-data-encryption) diff --git a/ql/src/security/CWE-311/AKSWithoutDiskEncryption.ql b/ql/src/security/CWE-311/AKSWithoutDiskEncryption.ql new file mode 100644 index 0000000..14f57ce --- /dev/null +++ b/ql/src/security/CWE-311/AKSWithoutDiskEncryption.ql @@ -0,0 +1,22 @@ +/** + * @name AKS cluster without disk encryption + * @description Detects Azure Kubernetes Service (AKS) clusters without disk encryption, which can expose sensitive data. + * @kind problem + * @problem.severity warning + * @security-severity 6.0 + * @precision high + * @id bicep/aks-without-disk-encryption + * @tags security + * bicep + * azure + * CWE-311 + */ + +import codeql.bicep.frameworks.Microsoft.AKS +import bicep + +from AKS::ManagedContainerResource resource, AKS::ManagedContainerProperties::Properties properties +where + properties = resource.getProperties() and + not exists(properties.getDiskEncryptionSetID()) +select resource, "AKS cluster is configured without disk encryption, which can expose sensitive data at rest." diff --git a/ql/src/security/CWE-400/AKSNodeAutoScalingDisabled.md b/ql/src/security/CWE-400/AKSNodeAutoScalingDisabled.md new file mode 100644 index 0000000..42b18b8 --- /dev/null +++ b/ql/src/security/CWE-400/AKSNodeAutoScalingDisabled.md @@ -0,0 +1,92 @@ +# AKS cluster with node auto-scaling disabled + +Azure Kubernetes Service (AKS) clusters should have node auto-scaling enabled to efficiently handle varying workloads and prevent resource constraints during high load periods. + +## Problem statement + +When node auto-scaling is disabled in AKS agent pools, the cluster cannot automatically adjust the number of nodes based on resource demands. This can lead to: + +1. Resource constraints during high traffic periods, potentially causing service disruptions +2. Inefficient resource utilization during low traffic periods, resulting in unnecessary costs +3. Manual intervention required to scale the cluster, which may lead to delayed responses to changing workloads + +## Recommendation + +Enable auto-scaling for AKS agent pools by setting `enableAutoScaling` to `true` and configuring appropriate minimum and maximum node counts: + +```bicep +resource aksCluster 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'efficientAksCluster' + location: location + properties: { + // Other properties... + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + enableAutoScaling: true + minCount: 1 + maxCount: 5 + } + ] + // Other properties... + } +} +``` + +## Example + +### Inefficient configuration (Auto-scaling disabled) + +```bicep +resource aksClusterInefficient 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterInefficient' + location: location + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdns' + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + enableAutoScaling: false // Inefficient: Auto-scaling is disabled + } + ] + // Other properties... + } +} +``` + +### Efficient configuration (Auto-scaling enabled) + +```bicep +resource aksClusterEfficient 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterEfficient' + location: location + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdns' + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + enableAutoScaling: true // Efficient: Auto-scaling is enabled + minCount: 1 + maxCount: 5 + } + ] + // Other properties... + } +} +``` + +## References + +* [Cluster autoscaler in AKS](https://learn.microsoft.com/en-us/azure/aks/concepts-scale#cluster-autoscaler) +* [Best practices for cluster autoscaler in AKS](https://learn.microsoft.com/en-us/azure/aks/cluster-autoscaler#best-practices-for-the-cluster-autoscaler) diff --git a/ql/src/security/CWE-400/AKSNodeAutoScalingDisabled.ql b/ql/src/security/CWE-400/AKSNodeAutoScalingDisabled.ql new file mode 100644 index 0000000..1ea360c --- /dev/null +++ b/ql/src/security/CWE-400/AKSNodeAutoScalingDisabled.ql @@ -0,0 +1,26 @@ +/** + * @name AKS cluster with node auto-scaling disabled + * @description Detects Azure Kubernetes Service (AKS) clusters with node auto-scaling disabled, which may lead to resource constraints during high load. + * @kind problem + * @problem.severity warning + * @security-severity 4.0 + * @precision high + * @id bicep/aks-node-auto-scaling-disabled + * @tags security + * bicep + * azure + * CWE-400 + */ + +import codeql.bicep.frameworks.Microsoft.AKS + +from AKS::ManagedContainerResource resource, AKS::ManagedContainerProperties::Properties properties, + AKS::ManagedContainerProperties::AgentPoolProfile agentPool +where + properties = resource.getProperties() and + agentPool = properties.getAgentPoolProfiles() and + ( + not exists(agentPool.getEnableAutoScaling()) or + agentPool.getEnableAutoScaling().getBool() = false + ) +select agentPool, "AKS agent pool '" + agentPool.name() + "' has auto-scaling disabled, which may lead to resource constraints during high load." diff --git a/ql/src/security/CWE-668/AKSInsecureNetworkPolicy.md b/ql/src/security/CWE-668/AKSInsecureNetworkPolicy.md new file mode 100644 index 0000000..e03a08e --- /dev/null +++ b/ql/src/security/CWE-668/AKSInsecureNetworkPolicy.md @@ -0,0 +1,104 @@ +# AKS cluster with insecure network policy + +Azure Kubernetes Service (AKS) clusters should be configured with a secure network policy to limit pod-to-pod communication and reduce the attack surface within the cluster. + +## Problem statement + +When an AKS cluster is configured without a network policy or with the policy set to `'none'`, pods can communicate with each other without restrictions, which: + +1. Violates the principle of least privilege +2. Increases the risk of lateral movement in case of a breach +3. Makes it difficult to enforce network segmentation within the cluster +4. Allows potential attackers to move freely within the network once they gain access to a pod + +## Recommendation + +Configure your AKS cluster with a secure network policy such as `'azure'` (Azure Network Policy) or `'calico'` (Calico Network Policy): + +```bicep +resource aksCluster 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'secureAksCluster' + location: location + properties: { + // Other properties... + networkProfile: { + networkPlugin: 'azure' + networkPolicy: 'azure' // Or 'calico' + // Other network settings... + } + // Other properties... + } +} +``` + +## Example + +### Insecure configuration (Missing or none network policy) + +```bicep +resource aksClusterInsecure1 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterInsecure1' + location: location + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdns' + networkProfile: { + networkPlugin: 'azure' + // Missing networkPolicy (defaults to none) + } + // Other properties... + } +} + +resource aksClusterInsecure2 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterInsecure2' + location: location + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdns' + networkProfile: { + networkPlugin: 'azure' + networkPolicy: 'none' // Explicitly set to none (insecure) + } + // Other properties... + } +} +``` + +### Secure configuration (Azure or Calico network policy) + +```bicep +resource aksClusterSecure1 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterSecure1' + location: location + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdns' + networkProfile: { + networkPlugin: 'azure' + networkPolicy: 'azure' // Secure: Azure Network Policy + } + // Other properties... + } +} + +resource aksClusterSecure2 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterSecure2' + location: location + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdns' + networkProfile: { + networkPlugin: 'azure' + networkPolicy: 'calico' // Secure: Calico Network Policy + } + // Other properties... + } +} +``` + +## References + +* [Network policies for AKS](https://learn.microsoft.com/en-us/azure/aks/use-network-policies) +* [Azure Network Policy vs Calico Network Policy](https://learn.microsoft.com/en-us/azure/aks/concepts-network#azure-network-policy-vs-calico-network-policy) +* [Secure pod traffic with network policies in AKS](https://learn.microsoft.com/en-us/azure/aks/use-network-policies) diff --git a/ql/src/security/CWE-668/AKSInsecureNetworkPolicy.ql b/ql/src/security/CWE-668/AKSInsecureNetworkPolicy.ql new file mode 100644 index 0000000..773fbf1 --- /dev/null +++ b/ql/src/security/CWE-668/AKSInsecureNetworkPolicy.ql @@ -0,0 +1,27 @@ +/** + * @name AKS cluster with insecure network policy + * @description Detects Azure Kubernetes Service (AKS) clusters configured with an insecure or missing network policy, which may allow unwanted pod-to-pod communication. + * @kind problem + * @problem.severity warning + * @security-severity 5.5 + * @precision high + * @id bicep/aks-insecure-network-policy + * @tags security + * bicep + * azure + * CWE-668 + */ + +import codeql.bicep.frameworks.Microsoft.AKS +import bicep + +from AKS::ManagedContainerResource resource, AKS::ManagedContainerProperties::Properties properties, + Object networkProfile +where + properties = resource.getProperties() and + networkProfile = properties.getNetworkProfile() and + ( + not exists(networkProfile.getProperty("networkPolicy")) or + networkProfile.getProperty("networkPolicy").(StringLiteral).getValue() = "none" + ) +select resource, "AKS cluster is configured with an insecure or missing network policy, which may allow unwanted pod-to-pod communication." diff --git a/ql/test/queries-tests/security/AKS/AKSInsecureNetworkPolicy.expected b/ql/test/queries-tests/security/AKS/AKSInsecureNetworkPolicy.expected new file mode 100644 index 0000000..f7c9aa1 --- /dev/null +++ b/ql/test/queries-tests/security/AKS/AKSInsecureNetworkPolicy.expected @@ -0,0 +1,4 @@ +| aks-security-examples.bicep:2:1:30:1 | ManagedContainerResource | AKS cluster is configured with an insecure or missing network policy, which may allow unwanted pod-to-pod communication. | +| aks-security-examples.bicep:32:1:62:1 | ManagedContainerResource | AKS cluster is configured with an insecure or missing network policy, which may allow unwanted pod-to-pod communication. | +| app.bicep:287:1:307:1 | ManagedContainerResource | AKS cluster is configured with an insecure or missing network policy, which may allow unwanted pod-to-pod communication. | +| app.bicep:310:1:330:1 | ManagedContainerResource | AKS cluster is configured with an insecure or missing network policy, which may allow unwanted pod-to-pod communication. | diff --git a/ql/test/queries-tests/security/AKS/AKSInsecureNetworkPolicy.qlref b/ql/test/queries-tests/security/AKS/AKSInsecureNetworkPolicy.qlref new file mode 100644 index 0000000..9add631 --- /dev/null +++ b/ql/test/queries-tests/security/AKS/AKSInsecureNetworkPolicy.qlref @@ -0,0 +1 @@ +security/CWE-668/AKSInsecureNetworkPolicy.ql diff --git a/ql/test/queries-tests/security/AKS/AKSLocalAccountsEnabled.expected b/ql/test/queries-tests/security/AKS/AKSLocalAccountsEnabled.expected new file mode 100644 index 0000000..73a4459 --- /dev/null +++ b/ql/test/queries-tests/security/AKS/AKSLocalAccountsEnabled.expected @@ -0,0 +1,18 @@ +| aks-security-examples.bicep:2:1:30:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| aks-security-examples.bicep:32:1:62:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:6:1:22:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:25:1:41:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:46:1:66:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:69:1:86:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:89:1:106:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:111:1:130:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:133:1:150:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:153:1:170:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:199:1:216:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:219:1:236:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:241:1:261:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:264:1:284:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:287:1:307:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:310:1:330:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:349:1:366:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | +| app.bicep:369:1:386:1 | ManagedContainerResource | AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. | diff --git a/ql/test/queries-tests/security/AKS/AKSLocalAccountsEnabled.qlref b/ql/test/queries-tests/security/AKS/AKSLocalAccountsEnabled.qlref new file mode 100644 index 0000000..eaeb4e8 --- /dev/null +++ b/ql/test/queries-tests/security/AKS/AKSLocalAccountsEnabled.qlref @@ -0,0 +1 @@ +security/CWE-306/AKSLocalAccountsEnabled.ql diff --git a/ql/test/queries-tests/security/AKS/AKSNodeAutoScalingDisabled.expected b/ql/test/queries-tests/security/AKS/AKSNodeAutoScalingDisabled.expected new file mode 100644 index 0000000..1beb482 --- /dev/null +++ b/ql/test/queries-tests/security/AKS/AKSNodeAutoScalingDisabled.expected @@ -0,0 +1,17 @@ +| aks-security-examples.bicep:9:7:16:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:14:7:19:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:33:7:38:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:58:7:63:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:78:7:83:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:98:7:103:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:141:7:147:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:161:7:167:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:188:7:193:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:208:7:213:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:228:7:233:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:253:7:258:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:276:7:281:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:299:7:304:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:322:7:327:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:358:7:363:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | +| app.bicep:378:7:383:7 | AgentPoolProfile | AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. | diff --git a/ql/test/queries-tests/security/AKS/AKSNodeAutoScalingDisabled.qlref b/ql/test/queries-tests/security/AKS/AKSNodeAutoScalingDisabled.qlref new file mode 100644 index 0000000..aba8f39 --- /dev/null +++ b/ql/test/queries-tests/security/AKS/AKSNodeAutoScalingDisabled.qlref @@ -0,0 +1 @@ +security/CWE-400/AKSNodeAutoScalingDisabled.ql diff --git a/ql/test/queries-tests/security/AKS/AKSPrivateApiEnabled.expected b/ql/test/queries-tests/security/AKS/AKSPrivateApiEnabled.expected index f55efbb..c631454 100644 --- a/ql/test/queries-tests/security/AKS/AKSPrivateApiEnabled.expected +++ b/ql/test/queries-tests/security/AKS/AKSPrivateApiEnabled.expected @@ -1 +1,2 @@ | aks-security-examples.bicep:32:1:62:1 | ManagedContainerResource | AKS cluster API server is private (private cluster enabled). | +| app.bicep:46:1:66:1 | ManagedContainerResource | AKS cluster API server is private (private cluster enabled). | diff --git a/ql/test/queries-tests/security/AKS/AKSPublicNetworkAccess.expected b/ql/test/queries-tests/security/AKS/AKSPublicNetworkAccess.expected new file mode 100644 index 0000000..0333052 --- /dev/null +++ b/ql/test/queries-tests/security/AKS/AKSPublicNetworkAccess.expected @@ -0,0 +1,17 @@ +| aks-security-examples.bicep:2:1:30:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:6:1:22:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:25:1:41:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:69:1:86:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:89:1:106:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:111:1:130:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:133:1:150:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:153:1:170:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:175:1:196:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:199:1:216:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:219:1:236:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:241:1:261:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:264:1:284:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:287:1:307:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:310:1:330:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:349:1:366:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | +| app.bicep:369:1:386:1 | ManagedContainerResource | AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. | diff --git a/ql/test/queries-tests/security/AKS/AKSPublicNetworkAccess.qlref b/ql/test/queries-tests/security/AKS/AKSPublicNetworkAccess.qlref new file mode 100644 index 0000000..0ff7b01 --- /dev/null +++ b/ql/test/queries-tests/security/AKS/AKSPublicNetworkAccess.qlref @@ -0,0 +1 @@ +security/CWE-284/AKSPublicNetworkAccess.ql diff --git a/ql/test/queries-tests/security/AKS/AKSRbacDisabled.expected b/ql/test/queries-tests/security/AKS/AKSRbacDisabled.expected new file mode 100644 index 0000000..38a36f8 --- /dev/null +++ b/ql/test/queries-tests/security/AKS/AKSRbacDisabled.expected @@ -0,0 +1 @@ +| app.bicep:25:1:41:1 | ManagedContainerResource | AKS cluster has RBAC disabled, which can lead to unauthorized access to the cluster. | diff --git a/ql/test/queries-tests/security/AKS/AKSRbacDisabled.qlref b/ql/test/queries-tests/security/AKS/AKSRbacDisabled.qlref new file mode 100644 index 0000000..fc90ed9 --- /dev/null +++ b/ql/test/queries-tests/security/AKS/AKSRbacDisabled.qlref @@ -0,0 +1 @@ +security/CWE-284/AKSRbacDisabled.ql diff --git a/ql/test/queries-tests/security/AKS/AKSWithoutDiskEncryption.expected b/ql/test/queries-tests/security/AKS/AKSWithoutDiskEncryption.expected new file mode 100644 index 0000000..3edb81f --- /dev/null +++ b/ql/test/queries-tests/security/AKS/AKSWithoutDiskEncryption.expected @@ -0,0 +1,19 @@ +| aks-security-examples.bicep:2:1:30:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| aks-security-examples.bicep:32:1:62:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:6:1:22:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:25:1:41:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:46:1:66:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:69:1:86:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:89:1:106:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:111:1:130:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:133:1:150:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:153:1:170:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:175:1:196:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:199:1:216:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:219:1:236:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:241:1:261:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:264:1:284:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:287:1:307:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:310:1:330:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:349:1:366:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | +| app.bicep:369:1:386:1 | ManagedContainerResource | AKS cluster is configured without disk encryption, which can expose sensitive data at rest. | diff --git a/ql/test/queries-tests/security/AKS/AKSWithoutDiskEncryption.qlref b/ql/test/queries-tests/security/AKS/AKSWithoutDiskEncryption.qlref new file mode 100644 index 0000000..ce40c22 --- /dev/null +++ b/ql/test/queries-tests/security/AKS/AKSWithoutDiskEncryption.qlref @@ -0,0 +1 @@ +security/CWE-311/AKSWithoutDiskEncryption.ql diff --git a/ql/test/queries-tests/security/AKS/app.bicep b/ql/test/queries-tests/security/AKS/app.bicep new file mode 100644 index 0000000..491d3e0 --- /dev/null +++ b/ql/test/queries-tests/security/AKS/app.bicep @@ -0,0 +1,386 @@ +// Test file for AKS security queries + +// ==== AKS RBAC Tests ==== + +// GOOD: AKS cluster with RBAC enabled +resource aksClusterRbacGood 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterRbacGood' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnsgood' + enableRBAC: true // Secure configuration with RBAC enabled + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + } + ] + } +} + +// BAD: AKS cluster with RBAC disabled +resource aksClusterRbacBad 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { // $ExpectedResult=AKS cluster has RBAC disabled, which can lead to unauthorized access to the cluster. + name: 'aksClusterRbacBad' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnsbad' + enableRBAC: false // Insecure configuration with RBAC disabled + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + } + ] + } +} + +// ==== AKS Public Network Access Tests ==== + +// GOOD: AKS cluster with public network access disabled and private cluster enabled +resource aksClusterNetworkGood 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterNetworkGood' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnsnetgood' + enableRBAC: true + publicNetworkAccess: 'Disabled' // Secure: Public network access is disabled + apiServerAccessProfile: { + enablePrivateCluster: true // Secure: Private cluster is enabled + } + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + } + ] + } +} + +// BAD: AKS cluster with public network access explicitly enabled +resource aksClusterNetworkBad1 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { // $ExpectedResult=AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. + name: 'aksClusterNetworkBad1' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnsnetbad1' + enableRBAC: true + publicNetworkAccess: 'Enabled' // Insecure: Public network access is explicitly enabled + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + } + ] + } +} + +// BAD: AKS cluster with default public network access (not specified) +resource aksClusterNetworkBad2 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { // $ExpectedResult=AKS cluster has public network access enabled, which can expose the cluster to unauthorized access. + name: 'aksClusterNetworkBad2' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnsnetbad2' + enableRBAC: true + // publicNetworkAccess defaults to 'Enabled' when not specified + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + } + ] + } +} + +// ==== AKS Node Auto-Scaling Tests ==== + +// GOOD: AKS cluster with node auto-scaling enabled +resource aksClusterAutoScalingGood 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterAutoScalingGood' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnsasgood' + enableRBAC: true + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + enableAutoScaling: true // Efficient: Auto-scaling is enabled + minCount: 1 + maxCount: 5 + } + ] + } +} + +// BAD: AKS cluster with node auto-scaling explicitly disabled +resource aksClusterAutoScalingBad1 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterAutoScalingBad1' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnsasbad1' + enableRBAC: true + agentPoolProfiles: [ + { // $ExpectedResult=AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + enableAutoScaling: false // Inefficient: Auto-scaling is explicitly disabled + } + ] + } +} + +// BAD: AKS cluster with node auto-scaling not specified (defaults to disabled) +resource aksClusterAutoScalingBad2 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterAutoScalingBad2' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnsasbad2' + enableRBAC: true + agentPoolProfiles: [ + { // $ExpectedResult=AKS agent pool 'agentpool' has auto-scaling disabled, which may lead to resource constraints during high load. + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + // enableAutoScaling defaults to false when not specified + } + ] + } +} + +// ==== AKS Local Accounts Tests ==== + +// GOOD: AKS cluster with local accounts disabled and AAD integration +resource aksClusterLocalAccountsGood 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterLocalAccountsGood' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnslagood' + enableRBAC: true + disableLocalAccounts: true // Secure: Local accounts are disabled + aadProfile: { + managed: true + enableAzureRBAC: true + } + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + } + ] + } +} + +// BAD: AKS cluster with local accounts explicitly enabled +resource aksClusterLocalAccountsBad1 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { // $ExpectedResult=AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. + name: 'aksClusterLocalAccountsBad1' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnslabad1' + enableRBAC: true + disableLocalAccounts: false // Insecure: Local accounts are explicitly enabled + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + } + ] + } +} + +// BAD: AKS cluster with local accounts not specified (defaults to enabled) +resource aksClusterLocalAccountsBad2 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { // $ExpectedResult=AKS cluster has local accounts enabled, which can lead to weaker authentication controls compared to Azure AD-backed authentication. + name: 'aksClusterLocalAccountsBad2' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnslabad2' + enableRBAC: true + // disableLocalAccounts defaults to false when not specified + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + } + ] + } +} + +// ==== AKS Network Policy Tests ==== + +// GOOD: AKS cluster with Azure network policy +resource aksClusterNetworkPolicyGood1 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterNetworkPolicyGood1' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnsnpgood1' + enableRBAC: true + networkProfile: { + networkPlugin: 'azure' + networkPolicy: 'azure' // Secure: Azure Network Policy + } + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + } + ] + } +} + +// GOOD: AKS cluster with Calico network policy +resource aksClusterNetworkPolicyGood2 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterNetworkPolicyGood2' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnsnpgood2' + enableRBAC: true + networkProfile: { + networkPlugin: 'azure' + networkPolicy: 'calico' // Secure: Calico Network Policy + } + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + } + ] + } +} + +// BAD: AKS cluster with network policy explicitly set to none +resource aksClusterNetworkPolicyBad1 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { // $ExpectedResult=AKS cluster is configured with an insecure or missing network policy, which may allow unwanted pod-to-pod communication. + name: 'aksClusterNetworkPolicyBad1' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnsnpbad1' + enableRBAC: true + networkProfile: { + networkPlugin: 'azure' + networkPolicy: 'none' // Insecure: Network policy explicitly set to none + } + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + } + ] + } +} + +// BAD: AKS cluster with missing network policy +resource aksClusterNetworkPolicyBad2 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { // $ExpectedResult=AKS cluster is configured with an insecure or missing network policy, which may allow unwanted pod-to-pod communication. + name: 'aksClusterNetworkPolicyBad2' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnsnpbad2' + enableRBAC: true + networkProfile: { + networkPlugin: 'azure' + // Missing networkPolicy (defaults to none) + } + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + } + ] + } +} + +// ==== AKS Disk Encryption Tests ==== + +// First, create a disk encryption set resource +resource diskEncryptionSet 'Microsoft.Compute/diskEncryptionSets@2022-07-02' = { + name: 'myDiskEncryptionSet' + location: 'eastus' + identity: { + type: 'SystemAssigned' + } + properties: { + activeKey: { + keyUrl: 'https://mykeyvault.vault.azure.net/keys/mykey/1234567890abcdef1234567890abcdef' + } + } +} + +// GOOD: AKS cluster with disk encryption +resource aksClusterDiskEncryptionGood 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { + name: 'aksClusterDiskEncryptionGood' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnsdegood' + enableRBAC: true + diskEncryptionSetID: diskEncryptionSet.id // Secure: Using disk encryption + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + } + ] + } +} + +// BAD: AKS cluster without disk encryption +resource aksClusterDiskEncryptionBad 'Microsoft.ContainerService/managedClusters@2023-02-02-preview' = { // $ExpectedResult=AKS cluster is configured without disk encryption, which can expose sensitive data at rest. + name: 'aksClusterDiskEncryptionBad' + location: 'eastus' + properties: { + kubernetesVersion: '1.24.9' + dnsPrefix: 'aksdnsdebad' + enableRBAC: true + // Missing diskEncryptionSetID + agentPoolProfiles: [ + { + name: 'agentpool' + count: 3 + vmSize: 'Standard_DS2_v2' + osType: 'Linux' + } + ] + } +} diff --git a/scripts/coverage.py b/scripts/coverage.py old mode 100644 new mode 100755 index e5ce7eb..0c27bd1 --- a/scripts/coverage.py +++ b/scripts/coverage.py @@ -93,7 +93,6 @@ def process_query_paths(queries: List[str], project_root: Path) -> List[Dict[str # Extract query metadata query_info = { "path": str(relative_path), - "absolute_path": query_path, "name": Path(query_path).stem, "category": extract_category_from_path(relative_path), "cwe": extract_cwe_from_path(relative_path),