func()

in internal/scanners/asp/rules.go [256:398]


func (a *AppServiceScanner) getFunctionRules() map[string]models.AzqrRecommendation {
	return map[string]models.AzqrRecommendation{
		"func-001": {
			RecommendationID: "func-001",
			ResourceType:     "Microsoft.Web/sites",
			Category:         models.CategoryMonitoringAndAlerting,
			Recommendation:   "Function should have diagnostic settings enabled",
			Impact:           models.ImpactLow,
			Eval: func(target interface{}, scanContext *models.ScanContext) (bool, string) {
				service := target.(*armappservice.Site)
				_, ok := scanContext.DiagnosticsSettings[strings.ToLower(*service.ID)]
				return !ok, ""
			},
			LearnMoreUrl: "https://learn.microsoft.com/en-us/azure/azure-functions/functions-monitor-log-analytics?tabs=csharp",
		},
		"func-004": {
			RecommendationID: "func-004",
			ResourceType:     "Microsoft.Web/sites",
			Category:         models.CategorySecurity,
			Recommendation:   "Function should have private endpoints enabled",
			Impact:           models.ImpactHigh,
			Eval: func(target interface{}, scanContext *models.ScanContext) (bool, string) {
				i := target.(*armappservice.Site)
				_, pe := scanContext.PrivateEndpoints[*i.ID]
				return !pe, ""
			},
			LearnMoreUrl: "https://learn.microsoft.com/en-us/azure/azure-functions/functions-create-vnet",
		},
		"func-006": {
			RecommendationID: "func-006",
			ResourceType:     "Microsoft.Web/sites",
			Category:         models.CategoryGovernance,
			Recommendation:   "Function Name should comply with naming conventions",
			Impact:           models.ImpactLow,
			Eval: func(target interface{}, scanContext *models.ScanContext) (bool, string) {
				c := target.(*armappservice.Site)
				caf := strings.HasPrefix(*c.Name, "func")
				return !caf, ""
			},
			LearnMoreUrl: "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations",
		},
		"func-007": {
			RecommendationID: "func-007",
			ResourceType:     "Microsoft.Web/sites",
			Category:         models.CategorySecurity,
			Recommendation:   "Function should use HTTPS only",
			Impact:           models.ImpactHigh,
			Eval: func(target interface{}, scanContext *models.ScanContext) (bool, string) {
				c := target.(*armappservice.Site)
				h := c.Properties.HTTPSOnly != nil && *c.Properties.HTTPSOnly
				return !h, ""
			},
			LearnMoreUrl: "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-https",
		},
		"func-008": {
			RecommendationID: "func-008",
			ResourceType:     "Microsoft.Web/sites",
			Category:         models.CategoryGovernance,
			Recommendation:   "Function should have tags",
			Impact:           models.ImpactLow,
			Eval: func(target interface{}, scanContext *models.ScanContext) (bool, string) {
				c := target.(*armappservice.Site)
				return len(c.Tags) == 0, ""
			},
			LearnMoreUrl: "https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources?tabs=json",
		},
		"func-009": {
			RecommendationID: "func-009",
			ResourceType:     "Microsoft.Web/sites",
			Category:         models.CategorySecurity,
			Recommendation:   "Function should use VNET integration",
			Impact:           models.ImpactMedium,
			Eval: func(target interface{}, scanContext *models.ScanContext) (bool, string) {
				c := target.(*armappservice.Site)
				return c.Properties.VirtualNetworkSubnetID == nil || len(*c.Properties.VirtualNetworkSubnetID) == 0, ""
			},
			LearnMoreUrl: "https://learn.microsoft.com/en-us/azure/app-service/overview-vnet-integration",
		},
		"func-010": {
			RecommendationID: "func-010",
			ResourceType:     "Microsoft.Web/sites",
			Category:         models.CategorySecurity,
			Recommendation:   "Function should have VNET Route all enabled for VNET integration",
			Impact:           models.ImpactMedium,
			Eval: func(target interface{}, scanContext *models.ScanContext) (bool, string) {
				c := target.(*armappservice.Site)
				return c.Properties.VnetRouteAllEnabled == nil || !*c.Properties.VnetRouteAllEnabled, ""
			},
			LearnMoreUrl: "https://learn.microsoft.com/en-us/azure/app-service/overview-vnet-integration",
		},
		"func-011": {
			RecommendationID: "func-011",
			ResourceType:     "Microsoft.Web/sites",
			Category:         models.CategorySecurity,
			Recommendation:   "Function should use TLS 1.2",
			Impact:           models.ImpactMedium,
			Eval: func(target interface{}, scanContext *models.ScanContext) (bool, string) {
				broken := scanContext.SiteConfig.Properties.MinTLSVersion == nil || *scanContext.SiteConfig.Properties.MinTLSVersion != armappservice.SupportedTLSVersionsOne2
				return broken, ""
			},
			LearnMoreUrl: "https://learn.microsoft.com/en-us/azure/app-service/overview-tls",
		},
		"func-012": {
			RecommendationID: "func-012",
			ResourceType:     "Microsoft.Web/sites",
			Category:         models.CategorySecurity,
			Recommendation:   "Function remote debugging should be disabled",
			Impact:           models.ImpactMedium,
			Eval: func(target interface{}, scanContext *models.ScanContext) (bool, string) {
				broken := scanContext.SiteConfig.Properties.RemoteDebuggingEnabled == nil || *scanContext.SiteConfig.Properties.RemoteDebuggingEnabled
				return broken, ""
			},
			LearnMoreUrl: "https://learn.microsoft.com/en-us/visualstudio/debugger/remote-debugging-azure-app-service?view=vs-2022#enable-remote-debugging",
		},
		"func-013": {
			RecommendationID: "func-013",
			ResourceType:     "Microsoft.Web/sites",
			Category:         models.CategoryHighAvailability,
			Recommendation:   "Function should avoid using Client Affinity",
			Impact:           models.ImpactMedium,
			Eval: func(target interface{}, scanContext *models.ScanContext) (bool, string) {
				c := target.(*armappservice.Site)
				return c.Properties.ClientAffinityEnabled != nil && *c.Properties.ClientAffinityEnabled, ""
			},
			LearnMoreUrl: "https://learn.microsoft.com/en-us/azure/well-architected/service-guides/azure-app-service/reliability#checklist",
		},
		"func-014": {
			RecommendationID: "func-014",
			ResourceType:     "Microsoft.Web/sites",
			Category:         models.CategorySecurity,
			Recommendation:   "Function should use Managed Identities",
			Impact:           models.ImpactMedium,
			Eval: func(target interface{}, scanContext *models.ScanContext) (bool, string) {
				// c := target.(*armappservice.Site)
				// c.Identity == nil || c.Identity.Type == nil || *c.Identity.Type == armappservice.ManagedServiceIdentityTypeNone
				// not working because SDK set's Identity to nil even when configured.
				ok := scanContext.SiteConfig.Properties.ManagedServiceIdentityID != nil || scanContext.SiteConfig.Properties.XManagedServiceIdentityID != nil
				return !ok, ""
			},
			LearnMoreUrl: "https://learn.microsoft.com/en-us/azure/app-service/overview-managed-identity?tabs=portal%2Chttp",
		},
	}
}