Skip to main content

Grundlagen der Azure-Bicep-Sicherheit

Artikel von
Headshot of Mark Johnson

Mark Johnson

feature bicep security

13. Dezember 2022

0 Min. Lesezeit

Dieser Beitrag wurde von Snyk Ambassador Mark Johnson (@tazmainiandevil) verfasst. Erhalten Sie exklusiven Zugang zu Snyk, indem Sie sich als Snyk Ambassador anmelden.

Azure Bicep wird immer beliebter und entwickelt sich rasch zum Nachfolger von Azure Resource Manager (ARM)-Vorlagen. In diesem Beitrag gehe ich auf einige grundlegende Sicherheitsaspekte bei der Verwendung von Bicep ein. Wenn Sie Bicep noch nicht kennen, empfehle ich Ihnen, einen Blick in die Dokumentation zu Microsoft Learn zu werfen, um mehr zu erfahren.

Halten Sie Secrets aus der Versionsverwaltung heraus

Wir alle wissen, dass Secrets nicht in die Versionsverwaltung gehören. Trotzdem können sie leicht versehentlich in Dateien landen – insbesondere, wenn Sie Ihre Bicep-Konfigurationen lokal testen.

So vermeiden Sie, Secrets mitzucommitten:

  • Übergeben Sie Parameter über die Befehlszeile.

  • Verwenden Sie eine JSON-Parameterdatei, die von der Versionsverwaltung ignoriert wird. Fügen Sie die Datei beispielsweise zu Ihrer .gitignore-Datei hinzu, wenn Sie Git verwenden.

Eingaben schützen

Parameter von außen zu übergeben ist das eine. Doch wie stellen Sie sicher, dass Secrets geschützt sind und nicht in Ausgaben erscheinen? Bicep stellt für Parameter vom Typ String und Object den Decorator @secure bereit. Zum Beispiel:

@secure()
param adminPassword string

@secure()
param adminCredentials object

Vorsicht bei Ausgaben

Ausgaben zu Ihren Bicep-Modulen hinzuzufügen, ist sehr nützlich. Dabei gibt es jedoch einiges zu beachten. Wenn Sie eine Ausgabe festlegen, die wie ein Secret aussieht, weist Bicep Sie mit einer Warnung darauf hin, dass Sie möglicherweise Secrets offenlegen. Die folgende Ausgabe für eine Verbindungszeichenfolge zu einem Speicherkonto würde eine solche Warnung auslösen:

output connection string = 'DefaultEndpointsProtocol=https;AccountName=${storageaccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageaccount.id, storageaccount.apiVersion).keys[0].value}'

Wenn der Wert jedoch zunächst einer Variable zugewiesen und erst danach als Ausgabe festgelegt wird, erscheint keine Warnung – das Problem kann dann leicht übersehen werden.

var connectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageaccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageaccount.id, storageaccount.apiVersion).keys[0].value}'

output connection string = connectionString

Sehen wir uns nun an, was passiert, wenn eine Speicherkontoressource mit der folgenden Konfiguration in Azure bereitgestellt wird:

deploy.bicep
param location string = resourceGroup().location
param tags object = {}
param storageName string = 'stsecureteststore'
param sku string = 'Standard_LRS'

module storageModule 'modules/storage.bicep' = {
  name: 'StorageDeploy'
  params: {
    location: location
    storageName: storageName
    tags: tags
    sku: sku
  }
}

modules/storage.bicep

@description('The storage account name')
@minLength(3)
@maxLength(24)
param storageName string
@description('The storage account location')
param location string
@description('The tags for the storage account')
param tags object
@description('The storage account sku') 
@allowed([ 'Standard_LRS', 'Standard_GRS', 'Standard_GZRS', 'Standard_RAGRS', 'Standard_RAGZRS', 'Standard_ZRS', 'Premium_LRS', 'Premium_ZRS' ])
param sku string = 'Standard_LRS'
@description('The access tier for the blob services') 
@allowed([ 'Hot', 'Cool' ]) 
param accessTier string = 'Hot' 
@description('Allow public access to blobs') 
param allowBlobPublicAccess bool = false 

resource storageaccount 'Microsoft.Storage/storageAccounts@2022-05-01' = {
  name: storageName
  location: location
  kind: 'StorageV2'
  tags: tags
  sku: {
    name: sku
  }
  properties: {
    supportsHttpsTrafficOnly: true
    minimumTlsVersion: 'TLS1_2'
    accessTier: accessTier
    allowBlobPublicAccess: allowBlobPublicAccess
  }
}

var connectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageaccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageaccount.id, storageaccount.apiVersion).keys[0].value}'
output connection string = connectionString

Alle in Bicep definierten Ausgaben finden Sie unter Bereitstellungen für die Ressourcengruppe, in der die Ressourcen bereitgestellt wurden:

Azure-Portal: Bereitstellungsseite für die Ressourcengruppe rg-security-example mit den Bereitstellungen StorageDeploy und main mit dem Status „Erfolgreich“

Bei den Ausgaben von StorageDeploy sehen wir, dass die Verbindungszeichenfolge den Kontoschlüssel im Klartext enthält:

Azure-Portal: Seite „StorageDeploy Outputs“ mit der Ausgabe einer Verbindungszeichenfolge für ein Speicherkonto.

Das bedeutet, dass jede Person mit Zugriff auf die Ressourcen im Azure-Portal diese Ausgaben sehen kann. Um eine gute Sicherheitslage zu gewährleisten, sollten Sie in Bicep keine Secrets als Ausgaben zurückgeben.

Hoffentlich unterstützt Bicep künftig den Decorator @secure für Ausgaben, damit Secrets sicher zurückgegeben werden können.

Secrets aus Ressourcen

Wenn es problematisch ist, Secrets aus Bicep zurückzugeben, wie lassen sich Secrets dann von einem Modul an ein anderes übergeben? Eine Möglichkeit besteht darin, mit dem Schlüsselwort existing auf eine vorhandene Ressource zuzugreifen. Zum Beispiel:

param storageName string

resource storageaccount 'Microsoft.Storage/storageAccounts@2022-05-01' existing = {
  name: storageName  
}

var connectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageName};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageaccount.id, storageaccount.apiVersion).keys[0].value}'

Diese Verbindungszeichenfolge kann dann als Eingabe für eine andere Ressource verwendet werden.

Secrets aus Key Vault

Vorhandene Ressourcen abzurufen, ist eine Möglichkeit, an Secrets zu gelangen. Es gibt aber auch Unterstützung dafür, Secrets aus einem Key Vault abzurufen.

Hinweis: Stellen Sie sicher, dass die Key-Vault-Zugriffskonfiguration den Zugriff über „Azure Resource Manager für die Vorlagenbereitstellung“ zulässt.

Ressourcenzugriffseinstellungen mit ausgewählter Azure Resource Manager-Option für die Vorlagenbereitstellung; virtuelle Computer und Datenträgerverschlüsselung sind nicht ausgewählt.

Der Zugriff auf Key Vaults erfolgt wie im vorherigen Abschnitt über das Schlüsselwort existing. Beachten Sie jedoch, dass die Methode getSecret nur verwendet werden kann, wenn Sie einem Modulparameter mit dem Decorator @secure einen Wert zuweisen:

deploy.bicep
param location string = resourceGroup().location
param tags object
param sqlServerName string
param keyVaultName string
param keyVaultResourceGroupName string
param subscriptionId string = subscription().subscriptionId

resource vaultResource 'Microsoft.KeyVault/vaults@2022-07-01' existing = {
  name: keyVaultName 
  scope: resourceGroup(subscriptionId, keyVaultResourceGroupName  )
}

module sqlModule 'modules/sql.bicep' = {
  name: 'SqlDeploy'
  params: {
    location: location
    tags: tags
    sqlServerName: sqlServerName
    administratorLogin: vaultResource.getSecret('sqlUser')
    administratorLoginPassword: vaultResource.getSecret('sqlPassword')
  }  
}

modules/sql.bicep
@description('The resource location')
param location string
@description('The tags for the resources')
param tags object
@description('The name for the SQL Server')
param sqlServerName string
@secure()
@description('The SQL Administrator Login')
param administratorLogin string
@secure()
@description('The SQL Administrator password')
param administratorLoginPassword string

resource sqlServerResource 'Microsoft.Sql/servers@2022-05-01-preview' = {
  name: sqlServerName
  location: location
  tags:tags
  properties: {
    administratorLogin: administratorLogin
    administratorLoginPassword: administratorLoginPassword
  }
}

Bicep auf Sicherheitsprobleme scannen

Das Scannen von Infrastructure as Code (IaC) wird immer beliebter. Es ist erfreulich, dass Sicherheitsprobleme möglichst früh erkannt werden sollen. Snyk bietet eine kostenlose CLI, mit der Sie lokal IaC-Scans durchführen und Ihre Konfigurationen anhand von Sicherheits- und Compliance-Standards prüfen können. Bicep wird zwar nicht direkt unterstützt, aber ARM-Vorlagen, in die Bicep kompiliert wird, lassen sich scannen.

Um Bicep in ARM zu kompilieren, müssen Sie die Bicep-CLI installieren. Für den Einstieg mit der Snyk CLI erstellen Sie ein kostenloses Konto und installieren anschließend die Snyk CLI mit npm. Wenn Node.js lokal installiert ist, können Sie die CLI mit folgendem Befehl installieren:

npm install snyk@latest -g

Nach der Installation und Einrichtung können Sie folgenden Befehl ausführen:

az bicep build -f {file_name}.bicep

Dadurch wird eine JSON-Datei mit demselben Namen wie die Bicep-Datei erstellt. Anschließend können Sie den Snyk-Scan mit folgendem Befehl ausführen:

snyk iac test {file_name}.json

Abschließende Gedanken

Sicherheit müssen wir alle berücksichtigen. Auch wenn sie sich ständig verändert, können wir mit zunehmendem Wissen mehr tun, um unsere Ressourcen zu schützen. Ich hoffe, dieser Beitrag war informativ und hat Ihnen einige Einblicke gegeben, wie Sie Ihre Bicep-Konfigurationen absichern können.

IaC-Sicherheit für Entwickler

Snyk schützt Ihre Infrastructure as Code vom SDLC bis zur Laufzeit in der Cloud mit einer einheitlichen Policy-as-Code-Engine, damit jedes Team sicher entwickeln, bereitstellen und betreiben kann.

Weiterlesen

feature insights context
Blog

Autonome Angriffe sind bereits Realität. Die Verteidigung muss Schritt halten.

Autonome Angreifer verkürzen das Zeitfenster für die Verteidigung. Erfahren Sie, wie kontinuierliches Erkennen, Beheben, Validieren und Verhindern Sicherheitsteams helfen kann, Schritt zu halten.

Blog

Evo ADS Govern Agent Behavior ist allgemein verfügbar: MCP-Nutzung unter Kontrolle bringen

Evo ADS Govern Agent Behavior ist jetzt allgemein verfügbar und startet mit MCP Governance. Entdecken, genehmigen, überwachen, protokollieren und blockieren Sie die MCP-Server-Nutzung in führenden KI-Coding-Agenten.

illustration hero ai
Blog

Was ist Agentic AppSec?

Erfahren Sie, wie Agentic AppSec fundierte, klar begrenzte und unabhängig überprüfte KI-Agenten einsetzt, um den Application-Security-Kreislauf zu steuern.