bicep
bicep copied to clipboard
Linter warns about hardcoded URLs within Azure Firewall Rules
Bicep version Bicep CLI version 0.4.63 (7ebed03284) Extension v0.4.63
Describe the bug The Linter warns me not to use hardcoded URLs, but environment variables (https://aka.ms/bicep/linter/no-hardcoded-env-urls). However, these URLs are part of Azure Firewall rules and should not be covered by the Linter at all I think.
From my point of view, the resource type Microsoft.Network/firewallPolicies/ruleCollectionGroups is affected.
For NetworkRules, the following parameter should be ignored by the Linter:
- destinationFqdns
For ApplicationRules the following parameters:
- targetFqdns
- targetUrls
To Reproduce Steps to reproduce the behavior:
Use this template in a fresh Bicep file, it shows all the warnings:
param location string = resourceGroup().location
param dnsServers array
resource FirewallPolicy 'Microsoft.Network/firewallPolicies@2020-11-01' = {
name: 'fw-prod-hub-${location}-firewallpolicy'
location: location
properties: {
sku: {
tier: 'Standard'
}
threatIntelMode: 'Alert'
dnsSettings: {
enableProxy: true
servers: dnsServers
}
snat: {
privateRanges: [
'IANAPrivateRanges'
'4.3.2.1/24'
]
}
}
}
resource NetworkRules 'Microsoft.Network/firewallPolicies/ruleCollectionGroups@2020-08-01' = {
parent: FirewallPolicy
name: 'NetworkRules'
dependsOn: [
FirewallPolicy
]
properties: {
priority: 200
ruleCollections: [
{
ruleCollectionType: 'FirewallPolicyFilterRuleCollection'
action: {
type: 'Allow'
}
name: 'bar'
priority: 200
rules: [
{
ruleType: 'NetworkRule'
name: 'foo'
ipProtocols: [
'TCP'
]
sourceAddresses: [
'1.2.3.4'
]
destinationFqdns: [
'kms.core.windows.net'
'somevault.vault.azure.net'
]
destinationPorts: [
'1688'
'443'
]
}
]
}
]
}
}
resource ApplicationRules 'Microsoft.Network/firewallPolicies/ruleCollectionGroups@2020-08-01' = {
parent: FirewallPolicy
name: 'ApplicationRules'
dependsOn: [
FirewallPolicy
NetworkRules
]
properties: {
priority: 300
ruleCollections: [
{
ruleCollectionType: 'FirewallPolicyFilterRuleCollection'
action: {
type: 'Allow'
}
name: 'bar'
priority: 100
rules: [
{
ruleType: 'ApplicationRule'
name: 'foo'
protocols: [
{
protocolType: 'Https'
port: 443
}
]
targetFqdns: [
'prod.msocdn.com'
'management.azure.com'
'device.login.microsoftonline.com'
'login.microsoftonline.com'
'graph.windows.net'
]
destinationAddresses: [
'1.2.3.4/24'
]
}
]
}
]
}
}
@cloudchristoph - have you tried using variables and the environment() function for these values?
e.g.
var kms = 'kms.${environment().suffixes.storage}'
var keyVault = 'somevault.${environment().suffixes.keyvaultDns}'
var resourceManager = environment().resourceManager
var graphAudience = environment().graphAudience
I can do that, of course.
However, this does not meet the goal for a Firewall Rule Set (at least not for my customers, unfortunately). There are exactly defined URLs approved for whitelisting.
I really think that the Linter should ignore these parameters (targetFqdns, destinationFqdns, targetUrls) regarding the "hardcoded URLs" rule.
Don't you think @MarcusFelling?
@cloudchristoph - Does using bicepconfig.json meet your needs? You can modify the list of URL's by specifying disallowedhosts.
I agree with @cloudchristoph here, we need a way to exclude firewall policies from the linter. Adding all targetFqdns, destinationFqdns, targetUrls from all firewall rules will be a real pain. It would be nice if we could ignore specific resource types like Microsoft.Network/firewallPolicies/ruleCollectionGroups in bicepconfig.json.
@bmoore-msft - curious to get your take on this one. I believe this is a TTK rule as well, so wondering how we handle it there.
I think the rule is correct, those are cloud specific URIs and would not work in other clouds (which is one purpose for the rule). @MarcusFelling has the correct solution. If the Cx never needs to be concerned about the rule (will never use another cloud) just disable the rule.
According to the documentation on the environment() function, it returns the URI with https:// prepended to the value. Is that not the case? That would not work in the Firewall Rules since there are separate properties for the targetFQDN, protocolType and port number. https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-deployment?tabs=json#example-1
I think you can still concat/replace as needed...
By the way, for anyone wondering about the data returned by the environment() function - a quick way to test this is to deploy the following Bicep file:
output env object = environment()
You can use the following script to execute it and dump the result:
az deployment group create -g <your_resource_group> --template-file main.bicep --query properties.outputs.env.value
or if you're really lazy:
https://management.azure.com/metadata/endpoints?api-version=2019-05-01
@cloudchristoph would adding the ability to override linter rules in-line help with your scenario? https://github.com/Azure/bicep/issues/3354
It could, I guess. Actually, I don't want to override these rules in principle. They make sense in most places. It is just problematic when they are applied to such parameters. But I think we'll be fine for now if we use the option to disable the rule.
This is indeed quite clumsy but you can achieve this by replacing the https:// and trailing / by doing the following.
name: 'microsoft-authentication'
ruleType: 'ApplicationRule'
targetFqdns: [
'${replace(replace(environment().authentication.loginEndpoint, 'https://', ''), '/', '')}'
]