github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/internal/adapters/terraform/azure/database/adapt.go (about)

     1  package database
     2  
     3  import (
     4  	"github.com/khulnasoft-lab/defsec/pkg/providers/azure/database"
     5  	"github.com/khulnasoft-lab/defsec/pkg/terraform"
     6  	defsecTypes "github.com/khulnasoft-lab/defsec/pkg/types"
     7  )
     8  
     9  func Adapt(modules terraform.Modules) database.Database {
    10  
    11  	mssqlAdapter := mssqlAdapter{
    12  		alertPolicyIDs:    modules.GetChildResourceIDMapByType("azurerm_mssql_server_security_alert_policy"),
    13  		auditingPolicyIDs: modules.GetChildResourceIDMapByType("azurerm_mssql_server_extended_auditing_policy", "azurerm_mssql_database_extended_auditing_policy"),
    14  		firewallIDs:       modules.GetChildResourceIDMapByType("azurerm_sql_firewall_rule", "azurerm_mssql_firewall_rule"),
    15  	}
    16  
    17  	mysqlAdapter := mysqlAdapter{
    18  		firewallIDs: modules.GetChildResourceIDMapByType("azurerm_mysql_firewall_rule"),
    19  	}
    20  
    21  	mariaDBAdapter := mariaDBAdapter{
    22  		firewallIDs: modules.GetChildResourceIDMapByType("azurerm_mariadb_firewall_rule"),
    23  	}
    24  
    25  	postgresqlAdapter := postgresqlAdapter{
    26  		firewallIDs: modules.GetChildResourceIDMapByType("azurerm_postgresql_firewall_rule"),
    27  	}
    28  
    29  	return database.Database{
    30  		MSSQLServers:      mssqlAdapter.adaptMSSQLServers(modules),
    31  		MariaDBServers:    mariaDBAdapter.adaptMariaDBServers(modules),
    32  		MySQLServers:      mysqlAdapter.adaptMySQLServers(modules),
    33  		PostgreSQLServers: postgresqlAdapter.adaptPostgreSQLServers(modules),
    34  	}
    35  }
    36  
    37  type mssqlAdapter struct {
    38  	alertPolicyIDs    terraform.ResourceIDResolutions
    39  	auditingPolicyIDs terraform.ResourceIDResolutions
    40  	firewallIDs       terraform.ResourceIDResolutions
    41  }
    42  
    43  type mysqlAdapter struct {
    44  	firewallIDs terraform.ResourceIDResolutions
    45  }
    46  
    47  type mariaDBAdapter struct {
    48  	firewallIDs terraform.ResourceIDResolutions
    49  }
    50  
    51  type postgresqlAdapter struct {
    52  	firewallIDs terraform.ResourceIDResolutions
    53  }
    54  
    55  func (a *mssqlAdapter) adaptMSSQLServers(modules terraform.Modules) []database.MSSQLServer {
    56  	var mssqlServers []database.MSSQLServer
    57  	for _, module := range modules {
    58  		for _, resource := range module.GetResourcesByType("azurerm_sql_server") {
    59  			mssqlServers = append(mssqlServers, a.adaptMSSQLServer(resource, module))
    60  		}
    61  		for _, resource := range module.GetResourcesByType("azurerm_mssql_server") {
    62  			mssqlServers = append(mssqlServers, a.adaptMSSQLServer(resource, module))
    63  		}
    64  	}
    65  
    66  	orphanResources := modules.GetResourceByIDs(a.alertPolicyIDs.Orphans()...)
    67  
    68  	if len(orphanResources) > 0 {
    69  		orphanage := database.MSSQLServer{
    70  			Metadata: defsecTypes.NewUnmanagedMetadata(),
    71  			Server: database.Server{
    72  				Metadata:                  defsecTypes.NewUnmanagedMetadata(),
    73  				EnableSSLEnforcement:      defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
    74  				MinimumTLSVersion:         defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()),
    75  				EnablePublicNetworkAccess: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
    76  				FirewallRules:             nil,
    77  			},
    78  			ExtendedAuditingPolicies: nil,
    79  			SecurityAlertPolicies:    nil,
    80  		}
    81  		for _, policy := range orphanResources {
    82  			orphanage.SecurityAlertPolicies = append(orphanage.SecurityAlertPolicies, adaptMSSQLSecurityAlertPolicy(policy))
    83  		}
    84  		mssqlServers = append(mssqlServers, orphanage)
    85  
    86  	}
    87  
    88  	orphanResources = modules.GetResourceByIDs(a.auditingPolicyIDs.Orphans()...)
    89  
    90  	if len(orphanResources) > 0 {
    91  		orphanage := database.MSSQLServer{
    92  			Metadata: defsecTypes.NewUnmanagedMetadata(),
    93  			Server: database.Server{
    94  				Metadata:                  defsecTypes.NewUnmanagedMetadata(),
    95  				EnableSSLEnforcement:      defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
    96  				MinimumTLSVersion:         defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()),
    97  				EnablePublicNetworkAccess: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
    98  				FirewallRules:             nil,
    99  			},
   100  		}
   101  		for _, policy := range orphanResources {
   102  			orphanage.ExtendedAuditingPolicies = append(orphanage.ExtendedAuditingPolicies, adaptMSSQLExtendedAuditingPolicy(policy))
   103  		}
   104  		mssqlServers = append(mssqlServers, orphanage)
   105  
   106  	}
   107  
   108  	orphanResources = modules.GetResourceByIDs(a.firewallIDs.Orphans()...)
   109  
   110  	if len(orphanResources) > 0 {
   111  		orphanage := database.MSSQLServer{
   112  			Metadata: defsecTypes.NewUnmanagedMetadata(),
   113  		}
   114  		for _, policy := range orphanResources {
   115  			orphanage.FirewallRules = append(orphanage.FirewallRules, adaptFirewallRule(policy))
   116  		}
   117  		mssqlServers = append(mssqlServers, orphanage)
   118  
   119  	}
   120  
   121  	return mssqlServers
   122  }
   123  func (a *mysqlAdapter) adaptMySQLServers(modules terraform.Modules) []database.MySQLServer {
   124  	var mySQLServers []database.MySQLServer
   125  	for _, module := range modules {
   126  		for _, resource := range module.GetResourcesByType("azurerm_mysql_server") {
   127  			mySQLServers = append(mySQLServers, a.adaptMySQLServer(resource, module))
   128  		}
   129  	}
   130  
   131  	orphanResources := modules.GetResourceByIDs(a.firewallIDs.Orphans()...)
   132  
   133  	if len(orphanResources) > 0 {
   134  		orphanage := database.MySQLServer{
   135  			Metadata: defsecTypes.NewUnmanagedMetadata(),
   136  			Server: database.Server{
   137  				Metadata:                  defsecTypes.NewUnmanagedMetadata(),
   138  				EnableSSLEnforcement:      defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
   139  				MinimumTLSVersion:         defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()),
   140  				EnablePublicNetworkAccess: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
   141  				FirewallRules:             nil,
   142  			},
   143  		}
   144  		for _, policy := range orphanResources {
   145  			orphanage.FirewallRules = append(orphanage.FirewallRules, adaptFirewallRule(policy))
   146  		}
   147  		mySQLServers = append(mySQLServers, orphanage)
   148  
   149  	}
   150  
   151  	return mySQLServers
   152  }
   153  
   154  func (a *mariaDBAdapter) adaptMariaDBServers(modules terraform.Modules) []database.MariaDBServer {
   155  	var mariaDBServers []database.MariaDBServer
   156  	for _, module := range modules {
   157  		for _, resource := range module.GetResourcesByType("azurerm_mariadb_server") {
   158  			mariaDBServers = append(mariaDBServers, a.adaptMariaDBServer(resource, module))
   159  		}
   160  	}
   161  
   162  	orphanResources := modules.GetResourceByIDs(a.firewallIDs.Orphans()...)
   163  
   164  	if len(orphanResources) > 0 {
   165  		orphanage := database.MariaDBServer{
   166  			Metadata: defsecTypes.NewUnmanagedMetadata(),
   167  			Server: database.Server{
   168  				Metadata:                  defsecTypes.NewUnmanagedMetadata(),
   169  				EnableSSLEnforcement:      defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
   170  				MinimumTLSVersion:         defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()),
   171  				EnablePublicNetworkAccess: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
   172  				FirewallRules:             nil,
   173  			},
   174  		}
   175  		for _, policy := range orphanResources {
   176  			orphanage.FirewallRules = append(orphanage.FirewallRules, adaptFirewallRule(policy))
   177  		}
   178  		mariaDBServers = append(mariaDBServers, orphanage)
   179  
   180  	}
   181  
   182  	return mariaDBServers
   183  }
   184  
   185  func (a *postgresqlAdapter) adaptPostgreSQLServers(modules terraform.Modules) []database.PostgreSQLServer {
   186  	var postgreSQLServers []database.PostgreSQLServer
   187  	for _, module := range modules {
   188  		for _, resource := range module.GetResourcesByType("azurerm_postgresql_server") {
   189  			postgreSQLServers = append(postgreSQLServers, a.adaptPostgreSQLServer(resource, module))
   190  		}
   191  	}
   192  
   193  	orphanResources := modules.GetResourceByIDs(a.firewallIDs.Orphans()...)
   194  
   195  	if len(orphanResources) > 0 {
   196  		orphanage := database.PostgreSQLServer{
   197  			Metadata: defsecTypes.NewUnmanagedMetadata(),
   198  			Server: database.Server{
   199  				Metadata:                  defsecTypes.NewUnmanagedMetadata(),
   200  				EnableSSLEnforcement:      defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
   201  				MinimumTLSVersion:         defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()),
   202  				EnablePublicNetworkAccess: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
   203  				FirewallRules:             nil,
   204  			},
   205  			Config: database.PostgresSQLConfig{
   206  				Metadata:             defsecTypes.NewUnmanagedMetadata(),
   207  				LogCheckpoints:       defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
   208  				ConnectionThrottling: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
   209  				LogConnections:       defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
   210  			},
   211  		}
   212  		for _, policy := range orphanResources {
   213  			orphanage.FirewallRules = append(orphanage.FirewallRules, adaptFirewallRule(policy))
   214  		}
   215  		postgreSQLServers = append(postgreSQLServers, orphanage)
   216  
   217  	}
   218  
   219  	return postgreSQLServers
   220  }
   221  
   222  func (a *mssqlAdapter) adaptMSSQLServer(resource *terraform.Block, module *terraform.Module) database.MSSQLServer {
   223  	minTLSVersionVal := defsecTypes.StringDefault("", resource.GetMetadata())
   224  	publicAccessVal := defsecTypes.BoolDefault(true, resource.GetMetadata())
   225  	enableSSLEnforcementVal := defsecTypes.BoolDefault(false, resource.GetMetadata())
   226  
   227  	var auditingPolicies []database.ExtendedAuditingPolicy
   228  	var alertPolicies []database.SecurityAlertPolicy
   229  	var firewallRules []database.FirewallRule
   230  
   231  	if resource.TypeLabel() == "azurerm_mssql_server" {
   232  		minTLSVersionAttr := resource.GetAttribute("minimum_tls_version")
   233  		minTLSVersionVal = minTLSVersionAttr.AsStringValueOrDefault("", resource)
   234  
   235  		publicAccessAttr := resource.GetAttribute("public_network_access_enabled")
   236  		publicAccessVal = publicAccessAttr.AsBoolValueOrDefault(true, resource)
   237  
   238  	}
   239  
   240  	alertPolicyBlocks := module.GetReferencingResources(resource, "azurerm_mssql_server_security_alert_policy", "server_name")
   241  	for _, alertBlock := range alertPolicyBlocks {
   242  		a.alertPolicyIDs.Resolve(alertBlock.ID())
   243  		alertPolicies = append(alertPolicies, adaptMSSQLSecurityAlertPolicy(alertBlock))
   244  	}
   245  
   246  	auditingPoliciesBlocks := module.GetReferencingResources(resource, "azurerm_mssql_server_extended_auditing_policy", "server_id")
   247  	if resource.HasChild("extended_auditing_policy") {
   248  		auditingPoliciesBlocks = append(auditingPoliciesBlocks, resource.GetBlocks("extended_auditing_policy")...)
   249  	}
   250  
   251  	databasesRes := module.GetReferencingResources(resource, "azurerm_mssql_database", "server_id")
   252  	for _, databaseRes := range databasesRes {
   253  		dbAuditingBlocks := module.GetReferencingResources(databaseRes, "azurerm_mssql_database_extended_auditing_policy", "database_id")
   254  		auditingPoliciesBlocks = append(auditingPoliciesBlocks, dbAuditingBlocks...)
   255  	}
   256  
   257  	for _, auditBlock := range auditingPoliciesBlocks {
   258  		a.auditingPolicyIDs.Resolve(auditBlock.ID())
   259  		auditingPolicies = append(auditingPolicies, adaptMSSQLExtendedAuditingPolicy(auditBlock))
   260  	}
   261  
   262  	firewallRuleBlocks := module.GetReferencingResources(resource, "azurerm_sql_firewall_rule", "server_name")
   263  	firewallRuleBlocks = append(firewallRuleBlocks, module.GetReferencingResources(resource, "azurerm_mssql_firewall_rule", "server_id")...)
   264  	for _, firewallBlock := range firewallRuleBlocks {
   265  		a.firewallIDs.Resolve(firewallBlock.ID())
   266  		firewallRules = append(firewallRules, adaptFirewallRule(firewallBlock))
   267  	}
   268  
   269  	return database.MSSQLServer{
   270  		Metadata: resource.GetMetadata(),
   271  		Server: database.Server{
   272  			Metadata:                  resource.GetMetadata(),
   273  			EnableSSLEnforcement:      enableSSLEnforcementVal,
   274  			MinimumTLSVersion:         minTLSVersionVal,
   275  			EnablePublicNetworkAccess: publicAccessVal,
   276  			FirewallRules:             firewallRules,
   277  		},
   278  		ExtendedAuditingPolicies: auditingPolicies,
   279  		SecurityAlertPolicies:    alertPolicies,
   280  	}
   281  }
   282  
   283  func (a *mysqlAdapter) adaptMySQLServer(resource *terraform.Block, module *terraform.Module) database.MySQLServer {
   284  	var firewallRules []database.FirewallRule
   285  
   286  	enableSSLEnforcementAttr := resource.GetAttribute("ssl_enforcement_enabled")
   287  	enableSSLEnforcementVal := enableSSLEnforcementAttr.AsBoolValueOrDefault(false, resource)
   288  
   289  	minTLSVersionAttr := resource.GetAttribute("ssl_minimal_tls_version_enforced")
   290  	minTLSVersionVal := minTLSVersionAttr.AsStringValueOrDefault("TLSEnforcementDisabled", resource)
   291  
   292  	publicAccessAttr := resource.GetAttribute("public_network_access_enabled")
   293  	publicAccessVal := publicAccessAttr.AsBoolValueOrDefault(true, resource)
   294  
   295  	firewallRuleBlocks := module.GetReferencingResources(resource, "azurerm_mysql_firewall_rule", "server_name")
   296  	for _, firewallBlock := range firewallRuleBlocks {
   297  		a.firewallIDs.Resolve(firewallBlock.ID())
   298  		firewallRules = append(firewallRules, adaptFirewallRule(firewallBlock))
   299  	}
   300  
   301  	return database.MySQLServer{
   302  		Metadata: resource.GetMetadata(),
   303  		Server: database.Server{
   304  			Metadata:                  resource.GetMetadata(),
   305  			EnableSSLEnforcement:      enableSSLEnforcementVal,
   306  			MinimumTLSVersion:         minTLSVersionVal,
   307  			EnablePublicNetworkAccess: publicAccessVal,
   308  			FirewallRules:             firewallRules,
   309  		},
   310  	}
   311  }
   312  
   313  func (a *mariaDBAdapter) adaptMariaDBServer(resource *terraform.Block, module *terraform.Module) database.MariaDBServer {
   314  	var firewallRules []database.FirewallRule
   315  
   316  	enableSSLEnforcementAttr := resource.GetAttribute("ssl_enforcement_enabled")
   317  	enableSSLEnforcementVal := enableSSLEnforcementAttr.AsBoolValueOrDefault(false, resource)
   318  
   319  	publicAccessAttr := resource.GetAttribute("public_network_access_enabled")
   320  	publicAccessVal := publicAccessAttr.AsBoolValueOrDefault(true, resource)
   321  
   322  	firewallRuleBlocks := module.GetReferencingResources(resource, "azurerm_mariadb_firewall_rule", "server_name")
   323  	for _, firewallBlock := range firewallRuleBlocks {
   324  		a.firewallIDs.Resolve(firewallBlock.ID())
   325  		firewallRules = append(firewallRules, adaptFirewallRule(firewallBlock))
   326  	}
   327  
   328  	return database.MariaDBServer{
   329  		Metadata: resource.GetMetadata(),
   330  		Server: database.Server{
   331  			Metadata:                  resource.GetMetadata(),
   332  			EnableSSLEnforcement:      enableSSLEnforcementVal,
   333  			MinimumTLSVersion:         defsecTypes.StringDefault("", resource.GetMetadata()),
   334  			EnablePublicNetworkAccess: publicAccessVal,
   335  			FirewallRules:             firewallRules,
   336  		},
   337  	}
   338  }
   339  
   340  func (a *postgresqlAdapter) adaptPostgreSQLServer(resource *terraform.Block, module *terraform.Module) database.PostgreSQLServer {
   341  	var firewallRules []database.FirewallRule
   342  
   343  	enableSSLEnforcementAttr := resource.GetAttribute("ssl_enforcement_enabled")
   344  	enableSSLEnforcementVal := enableSSLEnforcementAttr.AsBoolValueOrDefault(false, resource)
   345  
   346  	minTLSVersionAttr := resource.GetAttribute("ssl_minimal_tls_version_enforced")
   347  	minTLSVersionVal := minTLSVersionAttr.AsStringValueOrDefault("TLSEnforcementDisabled", resource)
   348  
   349  	publicAccessAttr := resource.GetAttribute("public_network_access_enabled")
   350  	publicAccessVal := publicAccessAttr.AsBoolValueOrDefault(true, resource)
   351  
   352  	firewallRuleBlocks := module.GetReferencingResources(resource, "azurerm_postgresql_firewall_rule", "server_name")
   353  	for _, firewallBlock := range firewallRuleBlocks {
   354  		a.firewallIDs.Resolve(firewallBlock.ID())
   355  		firewallRules = append(firewallRules, adaptFirewallRule(firewallBlock))
   356  	}
   357  
   358  	configBlocks := module.GetReferencingResources(resource, "azurerm_postgresql_configuration", "server_name")
   359  	config := adaptPostgreSQLConfig(resource, configBlocks)
   360  
   361  	return database.PostgreSQLServer{
   362  		Metadata: resource.GetMetadata(),
   363  		Server: database.Server{
   364  			Metadata:                  resource.GetMetadata(),
   365  			EnableSSLEnforcement:      enableSSLEnforcementVal,
   366  			MinimumTLSVersion:         minTLSVersionVal,
   367  			EnablePublicNetworkAccess: publicAccessVal,
   368  			FirewallRules:             firewallRules,
   369  		},
   370  		Config: config,
   371  	}
   372  }
   373  
   374  func adaptPostgreSQLConfig(resource *terraform.Block, configBlocks []*terraform.Block) database.PostgresSQLConfig {
   375  	config := database.PostgresSQLConfig{
   376  		Metadata:             resource.GetMetadata(),
   377  		LogCheckpoints:       defsecTypes.BoolDefault(false, resource.GetMetadata()),
   378  		ConnectionThrottling: defsecTypes.BoolDefault(false, resource.GetMetadata()),
   379  		LogConnections:       defsecTypes.BoolDefault(false, resource.GetMetadata()),
   380  	}
   381  
   382  	for _, configBlock := range configBlocks {
   383  
   384  		nameAttr := configBlock.GetAttribute("name")
   385  		valAttr := configBlock.GetAttribute("value")
   386  
   387  		if nameAttr.Equals("log_checkpoints") {
   388  			config.LogCheckpoints = defsecTypes.Bool(valAttr.Equals("on"), valAttr.GetMetadata())
   389  		}
   390  		if nameAttr.Equals("connection_throttling") {
   391  			config.ConnectionThrottling = defsecTypes.Bool(valAttr.Equals("on"), valAttr.GetMetadata())
   392  		}
   393  		if nameAttr.Equals("log_connections") {
   394  			config.LogConnections = defsecTypes.Bool(valAttr.Equals("on"), valAttr.GetMetadata())
   395  		}
   396  	}
   397  
   398  	return config
   399  }
   400  
   401  func adaptMSSQLSecurityAlertPolicy(resource *terraform.Block) database.SecurityAlertPolicy {
   402  
   403  	emailAddressesAttr := resource.GetAttribute("email_addresses")
   404  	disabledAlertsAttr := resource.GetAttribute("disabled_alerts")
   405  
   406  	emailAccountAdminsAttr := resource.GetAttribute("email_account_admins")
   407  	emailAccountAdminsVal := emailAccountAdminsAttr.AsBoolValueOrDefault(false, resource)
   408  
   409  	return database.SecurityAlertPolicy{
   410  		Metadata:           resource.GetMetadata(),
   411  		EmailAddresses:     emailAddressesAttr.AsStringValues(),
   412  		DisabledAlerts:     disabledAlertsAttr.AsStringValues(),
   413  		EmailAccountAdmins: emailAccountAdminsVal,
   414  	}
   415  }
   416  
   417  func adaptFirewallRule(resource *terraform.Block) database.FirewallRule {
   418  	startIPAttr := resource.GetAttribute("start_ip_address")
   419  	startIPVal := startIPAttr.AsStringValueOrDefault("", resource)
   420  
   421  	endIPAttr := resource.GetAttribute("end_ip_address")
   422  	endIPVal := endIPAttr.AsStringValueOrDefault("", resource)
   423  
   424  	return database.FirewallRule{
   425  		Metadata: resource.GetMetadata(),
   426  		StartIP:  startIPVal,
   427  		EndIP:    endIPVal,
   428  	}
   429  }
   430  
   431  func adaptMSSQLExtendedAuditingPolicy(resource *terraform.Block) database.ExtendedAuditingPolicy {
   432  	retentionInDaysAttr := resource.GetAttribute("retention_in_days")
   433  	retentionInDaysVal := retentionInDaysAttr.AsIntValueOrDefault(0, resource)
   434  
   435  	return database.ExtendedAuditingPolicy{
   436  		Metadata:        resource.GetMetadata(),
   437  		RetentionInDays: retentionInDaysVal,
   438  	}
   439  }