Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AC_AZURE_0285 policy does not work with inline rules #1453

Open
jakub-i opened this issue Nov 15, 2022 · 1 comment
Open

AC_AZURE_0285 policy does not work with inline rules #1453

jakub-i opened this issue Nov 15, 2022 · 1 comment

Comments

@jakub-i
Copy link

jakub-i commented Nov 15, 2022

  • terrascan version: 1.16.0
  • Operating System: Windows 11

Description

Azure Policiy AC_AZURE_0285 for Network security rule allowing communication to Tcp port 22 is not caught by terrascan if the network rule is defined inline as security_rule property of the azurerm_network_security_group

I have not checked any other similar policies, but I imagine this issue is also relevant for those.

I see this as a bug, but it may also be a missing policy for azurerm_network_security_group resource, but the end result is that using inline rules circumvents the AC_AZURE_0285 policy. Meaning that the deployed resource will be the same disregarding if the rules are defined inline or as independent azurerm resource.

Either a policy should work disregarding which way a resource is configured, or several separate policies should exist covering the same issue. One cannot know or expect that developers are following one or the other way of configuring a resource.

What I Did

Following terraform code with inline rule:

resource "azurerm_virtual_network" "vnet" {
  name                = "vnet-network"
  address_space       = ["10.0.0.0/16"]
  location            = data.azurerm_resource_group.rg.location
  resource_group_name = data.azurerm_resource_group.rg.name
}

resource "azurerm_subnet" "subnet" {
  name                 = "subnet1"
  resource_group_name  = data.azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.0.2.0/24"]
}

resource "azurerm_network_security_group" "allow_ssh" {
  name = "allow_ssh"
  location = data.azurerm_resource_group.rg.location
  resource_group_name = data.azurerm_resource_group.rg.name

  security_rule {
    name = "allow_ssh"
    priority = 100
    direction = "Inbound"
    access = "Allow"
    protocol = "TCP"
    source_port_range = "*"
    source_address_prefix = "*"
    destination_port_range = "22"
    destination_address_prefix = "*"
  }
}

resource "azurerm_subnet_network_security_group_association" "subnet1_nsg" {
  network_security_group_id = azurerm_network_security_group.allow_ssh.id
  subnet_id = azurerm_subnet.subnet.id
}

Produced following terrascan output:

>terrascan scan -i terraform -t azure



Scan Summary -

        File/Folder         :   ~\workspace\StaticCodeAnalysis\tf\subnet-without-module-inline-rules
        IaC Type            :   terraform
        Scanned At          :   2022-11-15 10:22:51.8402614 +0000 UTC
        Policies Validated  :   1
        Violated Policies   :   0
        Low                 :   0
        Medium              :   0
        High                :   0

Using an azurerm resource for network rule with following code:

resource "azurerm_virtual_network" "vnet" {
  name                = "vnet-network"
  address_space       = ["10.0.0.0/16"]
  location            = data.azurerm_resource_group.rg.location
  resource_group_name = data.azurerm_resource_group.rg.name
}

resource "azurerm_subnet" "subnet" {
  name                 = "subnet1"
  resource_group_name  = data.azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.0.2.0/24"]
}

resource "azurerm_network_security_group" "allow_ssh" {
  name = "allow_ssh"
  location = data.azurerm_resource_group.rg.location
  resource_group_name = data.azurerm_resource_group.rg.name
}

resource "azurerm_network_security_rule" "ssh_allow" {
  network_security_group_name = azurerm_network_security_group.allow_ssh.name
  name = "allow_ssh"
  priority = 100
  direction = "Inbound"
  access = "Allow"
  protocol = "Tcp"
  source_port_range = "*"
  source_address_prefix = "*"
  destination_port_range = "22"
  destination_address_prefix = "*"
}

resource "azurerm_subnet_network_security_group_association" "subnet1_nsg" {
  network_security_group_id = azurerm_network_security_group.allow_ssh.id
  subnet_id = azurerm_subnet.subnet.id
}

Produces following expected output:

>terrascan scan -i terraform -t azure



Violation Details -

        Description    :        Ensure SSH (Tcp:22) is not exposed to entire internet for Azure Network Security Rule
        File           :        main.tf
        Module Name    :        root
        Plan Root      :        .\
        Line           :        29
        Severity       :        HIGH
        -----------------------------------------------------------------------


Scan Summary -

        File/Folder         : ~\workspace\StaticCodeAnalysis\tf\subnet-without-module
        IaC Type            :   terraform
        Scanned At          :   2022-11-15 10:25:31.1276851 +0000 UTC
        Policies Validated  :   46
        Violated Policies   :   1
        Low                 :   0
        Medium              :   0
        High                :   1
@jakub-i
Copy link
Author

jakub-i commented Nov 16, 2022

Did some more detective work, and tested following terraform snippet:

resource "azurerm_virtual_network" "vnet" {
  name                = "vnet-network"
  address_space       = ["10.0.0.0/16"]
  location            = data.azurerm_resource_group.rg.location
  resource_group_name = data.azurerm_resource_group.rg.name
}

resource "azurerm_subnet" "subnet" {
  name                 = "subnet1"
  resource_group_name  = data.azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.0.2.0/24"]
}

resource "azurerm_network_security_group" "nsg" {
  name = "ngs1"
  location = data.azurerm_resource_group.rg.location
  resource_group_name = data.azurerm_resource_group.rg.name

  security_rule {
    name = "allow_ssh"
    priority = 100
    direction = "Inbound"
    access = "Allow"
    protocol = "TCP"
    source_port_range = "*"
    source_address_prefix = "*"
    destination_port_range = "22"
    destination_address_prefix = "*"
  }
}

resource "azurerm_network_security_rule" "rule1" {
  network_security_group_name = azurerm_network_security_group.nsg.name
  name = "rule1"
  priority = 101
  direction = "Inbound"
  access = "Deny"
  protocol = "Tcp"
  source_port_range = "*"
  source_address_prefix = "*"
  destination_port_range = "443"
  destination_address_prefix = "*"
}

resource "azurerm_subnet_network_security_group_association" "subnet1_nsg" {
  network_security_group_id = azurerm_network_security_group.nsg.id
  subnet_id = azurerm_subnet.subnet.id
}

Which returned following output:

> terrascan scan -i terraform -t azure



Violation Details -

        Description    :        Ensure SSH (Tcp:22) is not exposed to entire internet for Azure Network Security Rule
        File           :        main.tf
        Module Name    :        root
        Plan Root      :        .\
        Line           :        23
        Severity       :        HIGH
        -----------------------------------------------------------------------


Scan Summary -

        File/Folder         :   ~\workspace\Zure.IaC.StaticCodeAnalysis\tf\subnet-without-module-inline-rules
        IaC Type            :   terraform
        Scanned At          :   2022-11-16 12:12:21.9045731 +0000 UTC
        Policies Validated  :   46
        Violated Policies   :   1
        Low                 :   0
        Medium              :   0
        High                :   1

So the .rego implementation works, but the policy is only asserted for in-line and out-line network security rules if there is a azurerm_network_security_rule resource defined. Terraform provider documentation for azurerm_network_security_group and for azurerm_network_security_rule states that only in-line or out-line approach should be used and not both.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant