bridgecrewio / checkov

Prevent cloud misconfigurations and find vulnerabilities during build-time in infrastructure as code, container images and open source packages with Checkov by Bridgecrew.
https://www.checkov.io/
Apache License 2.0
7.1k stars 1.12k forks source link

Bicep framework scan fails for some files #6682

Open romanrabodzei opened 2 months ago

romanrabodzei commented 2 months ago

Hi all,

I'm testing Azure Bicep with Checkov, and the Bicep framework does not work correctly for some files.

Files I use for scan: storageaccount.bicep

/*
.Synopsis
    Bicep template for Storage Account. Template https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/storageAccounts?tabs=bicep#template-format

.NOTES
    Author     : CoE Azure
    Version    : 1.0.240805
*/

/// deployment scope
targetScope = 'resourceGroup'

/// parameters
param location string
param subscription string

param storageAccountName string
param storageAccountKind string = 'StorageV2'
param storageAccountType string = 'Standard_LRS'
param storageAccountAccessTier string = 'Hot'
param storageAccountHnsEnabled bool = false

@description('Network access from outside for the storage account.')
@allowed([
  'Allow'
  'Deny'
])
param networkAccess_default string = 'Allow'
@description(' The resource ID for isolated access to storage account.')
param networkAccess_resource array = []

var resourceAccessRules = [
  for (id, item) in networkAccess_resource: {
    tenantId: az.subscription().tenantId
    resourceId: networkAccess_resource[item]
  }
]

param networkingResourceGroupName string = ''
param virtualNetworkName string = ''
param virtualNetworkSubnetName string = ''

var restorePolicy = {
  enabled: true
  days: 13
}

var changeFeed = {
  enabled: true
}

/// monitoring
param logAnalyticsWorkspaceName string = ''
param logAnalyticsWorkspaceResourceGroupName string = ''

/// tags
param tags object = {}

/// resources
resource virtualNetwork_resource 'Microsoft.Network/virtualNetworks@2021-05-01' existing = if (!empty(networkingResourceGroupName) && !empty(virtualNetworkName) && !empty(virtualNetworkSubnetName)) {
  scope: resourceGroup(networkingResourceGroupName)
  name: virtualNetworkName
  resource subnet 'subnets' existing = {
    name: virtualNetworkSubnetName
  }
}

resource storageAccount_resource 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  name: storageAccountName
  location: location
  tags: tags
  sku: {
    name: storageAccountType
  }
  kind: storageAccountKind
  properties: {
    accessTier: storageAccountAccessTier
    minimumTlsVersion: 'TLS1_2'
    supportsHttpsTrafficOnly: true
    allowBlobPublicAccess: false
    allowCrossTenantReplication: true
    encryption: {
      keySource: 'Microsoft.Storage'
      requireInfrastructureEncryption: false
      services: {
        blob: {
          enabled: true
          keyType: 'Account'
        }
        file: {
          enabled: true
          keyType: 'Account'
        }
        queue: {
          enabled: true
          keyType: 'Account'
        }
        table: {
          enabled: true
          keyType: 'Account'
        }
      }
    }
    isHnsEnabled: storageAccountHnsEnabled
    isLocalUserEnabled: false
    isNfsV3Enabled: false
    isSftpEnabled: false
    keyPolicy: {
      keyExpirationPeriodInDays: 90
    }
    largeFileSharesState: 'Disabled'
    publicNetworkAccess: 'Enabled'
    networkAcls: {
      resourceAccessRules: networkAccess_resource == [''] || networkAccess_resource == [] ? [] : resourceAccessRules
      bypass: 'AzureServices'
      defaultAction: networkAccess_default
      virtualNetworkRules: empty(networkingResourceGroupName) && empty(virtualNetworkName) && empty(virtualNetworkSubnetName)
        ? []
        : [
            {
              id: virtualNetwork_resource::subnet.id
              action: 'Allow'
            }
          ]
    }
  }
}

resource storageAccountBlobService_resource 'Microsoft.Storage/storageAccounts/blobServices@2023-01-01' = {
  name: toLower('${storageAccountName}/default')
  properties: {
    containerDeleteRetentionPolicy: {
      enabled: true
      days: toLower(subscription) == 'prod' ? 90 : 30
    }
    deleteRetentionPolicy: {
      allowPermanentDelete: false
      enabled: true
      days: toLower(subscription) == 'prod' ? 90 : 30
    }
    restorePolicy: storageAccountHnsEnabled == false ? restorePolicy : null
    isVersioningEnabled: storageAccountHnsEnabled == false ? true : null
    changeFeed: storageAccountHnsEnabled == false ? changeFeed : null
  }
  dependsOn: [
    storageAccount_resource
  ]
}

resource storageAccountFileService_resource 'Microsoft.Storage/storageAccounts/fileServices@2023-01-01' = {
  name: toLower('${storageAccountName}/default')
  properties: {
    shareDeleteRetentionPolicy: {
      enabled: true
      days: toLower(subscription) == 'prod' ? 90 : 30
    }
  }
  dependsOn: [
    storageAccount_resource
  ]
}

resource logAnalytics_resource 'Microsoft.OperationalInsights/workspaces@2022-10-01' existing = if (!empty(logAnalyticsWorkspaceName) && !empty(logAnalyticsWorkspaceResourceGroupName)) {
  scope: resourceGroup(logAnalyticsWorkspaceResourceGroupName)
  name: logAnalyticsWorkspaceName
}

resource send_data_to_logAnalyticsWorkspace 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (!empty(logAnalyticsWorkspaceName) && !empty(logAnalyticsWorkspaceName)) {
  scope: storageAccount_resource
  name: toLower('send-data-to-${logAnalyticsWorkspaceName}')
  properties: {
    workspaceId: logAnalytics_resource.id
    metrics: [
      {
        category: 'Transaction'
        enabled: true
      }
    ]
  }
}

var storageAccountPrimaryKey = storageAccount_resource.listKeys().keys[0].value
output storageAccountPrimaryKey string = storageAccountPrimaryKey
output storageAccountConnectionString string = 'DefaultEndpointsProtocol=https;AccountName=${storageAccount_resource.name};AccountKey=${storageAccountPrimaryKey};EndpointSuffix=${environment().suffixes.storage}'
output storageAccountId string = storageAccount_resource.id

servicebus.bicep

/*
.Synopsis
    Bicep template for Service Bus. Template https://docs.microsoft.com/en-us/azure/templates/Microsoft.ServiceBus/namespaces?tabs=bicep#template-format

.NOTES
    Author     : CoE Azure
    Version    : 1.0.231205
*/

/// deployment scope
targetScope = 'resourceGroup'

/// parameters
param location string = ''

param serviceBusName string = ''
param serviceBusSkuName string = 'Standard'
param serviceBusSkuTier string = 'Standard'

@allowed([
  'fs'
  'cs'
  'be'
])
param application string

/// monitoring
param logAnalyticsWorkspaceName string = ''
param logAnalyticsWorkspaceResourceGroupName string = ''

/// tags
param tags object = {}

/// resources
resource serviceBus 'Microsoft.ServiceBus/namespaces@2022-10-01-preview' = {
  name: toLower(serviceBusName)
  location: location
  tags: tags
  sku: {
    name: serviceBusSkuName
    tier: serviceBusSkuTier
  }
  properties: {
    disableLocalAuth: false
  }
}

resource serviceBusAuthorizationRules 'Microsoft.ServiceBus/namespaces/AuthorizationRules@2022-10-01-preview' existing = {
  parent: serviceBus
  name: 'RootManageSharedAccessKey'
}

var serviceBusQueues = {
  fs: [
    'sl_error_internal'
    'sl_event_internal'
    'sl_inbound'
    'sl_inbound_internal'
    'sl_outbound'
    'sl_reply_internal'
  ]
  cs: [
    'na-acs-sb-qu'
  ]
  be: [
    'customerservice-queue'
  ]
}

resource serviceBusQueue 'Microsoft.ServiceBus/namespaces/queues@2022-01-01-preview' = [for item in serviceBusQueues[application]: {
  parent: serviceBus
  name: item
  properties: {
    lockDuration: 'PT5M'
    maxSizeInMegabytes: 5120
    requiresDuplicateDetection: false
    requiresSession: false
    defaultMessageTimeToLive: 'P10675199DT2H48M5.4775807S'
    deadLetteringOnMessageExpiration: false
    duplicateDetectionHistoryTimeWindow: 'PT10M'
    maxDeliveryCount: 10
    autoDeleteOnIdle: 'P10675199DT2H48M5.4775807S'
    enablePartitioning: false
    enableExpress: false
  }
}]

resource logAnalytics_resource 'Microsoft.OperationalInsights/workspaces@2021-06-01' existing = if (!empty(logAnalyticsWorkspaceName) && !empty(logAnalyticsWorkspaceResourceGroupName)) {
  scope: resourceGroup(logAnalyticsWorkspaceResourceGroupName)
  name: logAnalyticsWorkspaceName
}

resource send_data_to_logAnalyticsWorkspace 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (!empty(logAnalyticsWorkspaceName) && !empty(logAnalyticsWorkspaceResourceGroupName)) {
  scope: serviceBus
  name: toLower('send-data-to-${logAnalyticsWorkspaceName}')
  properties: {
    workspaceId: logAnalytics_resource.id
    logs: [
      {
        category: 'OperationalLogs'
        enabled: true
      }
      {
        category: 'VNetAndIPFilteringLogs'
        enabled: true
      }
    ]
    metrics: [
      {
        category: 'AllMetrics'
        enabled: true
      }
    ]
  }
}

var serviceBusPrimaryConnectionString = serviceBusAuthorizationRules.listKeys().primaryConnectionString

output serviceBusId string = serviceBus.id
output serviceBusPrimaryConnectionString string = serviceBusPrimaryConnectionString

Version I use

The output

checkov -f ./servicebus.bicep
[ secrets framework ]: 100%|████████████████████|[1/1], Current File Scanned=./servicebus.bicep
[ bicep framework ]: 100%|████████████████████|[1/1], Current File Scanned=servicebus.bicep
checkov -f ./storageaccount.bicep
[ secrets framework ]: 100%|████████████████████|[1/1], Current File Scanned=./storageaccount.bicep

bicep scan results:
Passed checks: 0, Failed checks: 0, Skipped checks: 0, Parsing errors: 1
Error parsing file storageaccount.bicepֿ

I would be grateful for the help!

lirshindalman commented 5 days ago

@romanrabodzei Hi, thank you for reaching out, can you please elaborate on the checks you expected to get in this example?

romanrabodzei commented 5 days ago

@lirshindalman hi. I'd like to get the full scan for the storage account template as for service bus. It does scan for secrets, but fails with bicep framework. I added the scan results in the message above and templates to reproduce.