Skip to content

Commit

Permalink
Added new test for Azure Function App Authentication Enabled (#1058)
Browse files Browse the repository at this point in the history
  • Loading branch information
brandon-bailey-rc committed Aug 30, 2021
1 parent e13983e commit 9b913f8
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package functionapp

import (
"github.com/aquasecurity/tfsec/internal/app/tfsec/block"
"github.com/aquasecurity/tfsec/internal/app/tfsec/scanner"
"github.com/aquasecurity/tfsec/pkg/provider"
"github.com/aquasecurity/tfsec/pkg/result"
"github.com/aquasecurity/tfsec/pkg/rule"
"github.com/aquasecurity/tfsec/pkg/severity"
)

func init() {
scanner.RegisterCheckRule(rule.Rule{
Provider: provider.AzureProvider,
Service: "functionapp",
ShortCode: "authentication-enabled",
Documentation: rule.RuleDocumentation{
Summary: "Function App authentication is activated",
Explanation: `Enabling authentication ensures that all communications in the application are authenticated. The auth_settings block needs to be filled out with the appropriate auth backend settings`,
Impact: "Anonymous HTTP requests will be accepted",
Resolution: "Enable authentication to prevent anonymous request being accepted",
BadExample: []string{`
resource "azurerm_function_app" "bad_example" {
name = "example-function-app"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
app_service_plan_id = azurerm_function_app_plan.example.id
}
`},
GoodExample: []string{`
resource "azurerm_function_app" "good_example" {
name = "example-function-app"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
app_service_plan_id = azurerm_function_app_plan.example.id
auth_settings {
enabled = true
}
}
`},
Links: []string{
"https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/function_app#enabled",
},
},
RequiredTypes: []string{
"resource",
},
RequiredLabels: []string{
"azurerm_function_app",
},
DefaultSeverity: severity.Low,
CheckFunc: func(set result.Set, resourceBlock block.Block, module block.Module) {
if enabledAttr := resourceBlock.GetBlock("auth_settings").GetAttribute("enabled"); enabledAttr.IsNil() { // alert on use of default value
set.AddResult().
WithDescription("Resource '%s' uses default value for auth_settings.enabled", resourceBlock.FullName())
} else if enabledAttr.IsFalse() {
set.AddResult().
WithDescription("Resource '%s' has attribute auth_settings.enabled that is false", resourceBlock.FullName()).
WithAttribute(enabledAttr)
}
},
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package functionapp

import (
"strings"
"testing"

"github.com/aquasecurity/tfsec/internal/app/tfsec/scanner"
"github.com/aquasecurity/tfsec/internal/app/tfsec/testutil"
)

func Test_AzureAuthenticationEnabled_FailureExamples(t *testing.T) {
expectedCode := "azure-functionapp-authentication-enabled"

rule, err := scanner.GetRuleById(expectedCode)
if err != nil {
t.Fatalf("Rule not found: %s", expectedCode)
}
for i, badExample := range rule.Documentation.BadExample {
t.Logf("Running bad example for '%s' #%d", expectedCode, i+1)
if strings.TrimSpace(badExample) == "" {
t.Fatalf("bad example code not provided for %s", rule.ID())
}
defer func() {
if err := recover(); err != nil {
t.Fatalf("Scan (bad) failed: %s", err)
}
}()
results := testutil.ScanHCL(badExample, t)
testutil.AssertCheckCode(t, rule.ID(), "", results)
}
}

func Test_AzureAuthenticationEnabled_SuccessExamples(t *testing.T) {
expectedCode := "azure-functionapp-authentication-enabled"

rule, err := scanner.GetRuleById(expectedCode)
if err != nil {
t.Fatalf("Rule not found: %s", expectedCode)
}
for i, example := range rule.Documentation.GoodExample {
t.Logf("Running good example for '%s' #%d", expectedCode, i+1)
if strings.TrimSpace(example) == "" {
t.Fatalf("good example code not provided for %s", rule.ID())
}
defer func() {
if err := recover(); err != nil {
t.Fatalf("Scan (good) failed: %s", err)
}
}()
results := testutil.ScanHCL(example, t)
testutil.AssertCheckCode(t, "", rule.ID(), results)
}
}
1 change: 1 addition & 0 deletions internal/app/tfsec/rules/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import (
_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/azure/securitycenter"
_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/azure/storage"
_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/azure/synapse"
_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/azure/functionapp"
_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/cloudstack/compute"
_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/digitalocean/compute"
_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/digitalocean/droplet"
Expand Down
1 change: 1 addition & 0 deletions rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
| azure-keyvault-ensure-key-expiry | azure | keyvault | Ensure that the expiration date is set on all keys |
| azure-synapse-virtual-network-enabled | azure | synapse | Synapse Workspace should have managed virtual network enabled, the default is disabled. |
| azure-appservice-enforce-https | azure | appservice | Ensure the Function App can only be accessed via HTTPS. The default is false. |
| azure-functionapp-authentication-enabled | functionapp | Ensure the Function App has authentication enabled. The default is false. |
| digitalocean-compute-no-public-ingress | digitalocean | compute | The firewall has an inbound rule with open access |
| digitalocean-compute-no-public-egress | digitalocean | compute | The firewall has an outbound rule with open access |
| digitalocean-droplet-use-ssh-keys | digitalocean | droplet | SSH Keys are the preferred way to connect to your droplet, no keys are supplied |
Expand Down

0 comments on commit 9b913f8

Please sign in to comment.