feat(misconf): add support for ARM resources declared with symbolic names
Description
This PR fixes the issue where Trivy fails to detect security misconfigurations in Azure ARM templates generated from Bicep files that use modules. When Bicep generates ARM templates with modules, the resources property becomes a dictionary instead of an array, which the Azure ARM scanner wasn't handling correctly.
Problem -When building a Bicep file that contains modules with az bicep build -f main.bicep, Trivy does not detect security issues for the generated Azure ARM template when running trivy config .. ---The main difference when using modules is that the resources property becomes a dictionary instead of an array.
Root Cause Analysis -Detection Priority Issue: Both CloudFormation and Azure ARM matchers were detecting the same file, but CloudFormation was taking precedence -Dictionary Resources Not Supported: The Azure ARM parser only handled array-style resources, not dictionary-style resources from Bicep modulesNested Templates Not Processed: The scanner wasn't extracting and processing nested templates inside Microsoft.Resources/deployments resources (Bicep modules) -Azure Value Raw() Method Bug: The Raw() method for complex objects was returning nil instead of the actual data
Solution This PR implements a comprehensive fix with the following changes:
- Fixed Detection Priority (pkg/iac/detection/detect.go) Modified CloudFormation detection logic to exclude files that are already detected as Azure ARM templates Ensures Azure ARM takes precedence over CloudFormation for ARM templates2. Added Dictionary Resource Support (pkg/iac/scanners/azure/arm/parser/template.go) Updated template parsing logic to handle both array and dictionary resource formats Added convertMapToResource function to convert dictionary resources to the expected format Fixed Azure Value Raw() method to properly handle complex objects and arrays
- Implemented Nested Template Extraction (pkg/iac/scanners/azure/arm/parser/parser.go) Added logic to detect Microsoft.Resources/deployments resources (Bicep modules) Extract nested templates from the properties.template field Add nested resources directly to the main deployment's resources list for proper scanning
- Enhanced Testing (pkg/iac/scanners/azure/arm/parser/parser_test.go) Added comprehensive test case for dictionary resources Updated test expectations to account for nested resources Before and After Example
Before Fix:
$ trivy config test_main.json
Report Summary
┌────────┬──────┬───────────────────┐
│ Target │ Type │ Misconfigurations │
├────────┼──────┼───────────────────┤
│ - │ - │ - │
└────────┴──────┴───────────────────┘
After Fix:
$ trivy config test_main.json
Report Summary
┌────────────────┬───────────┬───────────────────┐
│ Target │ Type │ Misconfigurations │
├────────────────┼───────────┼───────────────────┤
│ test_main.json │ azure-arm │ 3 │
└────────────────┴───────────┴───────────────────┘
test_main.json (azure-arm)
Tests: 6 (SUCCESSES: 3, FAILURES: 3)
Failures: 3 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 2)
AVD-AZU-0008 (HIGH): Account does not enforce HTTPS.
AVD-AZU-0011 (CRITICAL): Storage account uses an insecure TLS version.
AVD-AZU-0012 (CRITICAL): Network rules allow access by default.
Related issues
- Close https://github.com/aquasecurity/trivy/issues/9467
Checklist
[x] I've read the guidelines for contributing to this repository. [x] I've followed the conventions in the PR title. [x] I've added tests that prove my fix is effective or that my feature works. [ ] I've updated the documentation with the relevant information (if needed). [ ] I've added usage information (if the PR introduces new options) [x] I've included a "before" and "after" example to the description (if the PR is a user interface change).
This PR ensures that Trivy now correctly detects and scans security issues in Azure ARM templates generated from Bicep files that use modules, resolving the original issue described in #9466.
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
Eshani Parulekar seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
Eshani Parulekar seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.
@simar7 Please review
@simar7 I have signed the CLA agreement but it seems that the bot is unable to recognise it. Also, if I try to open the link once and confirm if I have signed it, checkboxes and interactive ui/ux do not show up. What can I do ?
@nikpivkin once you're back could you take a look?
Fixing the following errors, shall commit the changes asap.
Hi, please check now. I have fixed the test issues.
Hi, any update? @simar7 @nikpivkin
Hi @eshentials !
Thank you for your contribution! I left a few comments.
@simar7 I suggested moving support for the Microsoft.Resources/deployments resource to a separate PR, as it is not related to the resource declaration issue. WDYT?
@simar7 I suggested moving support for the
Microsoft.Resources/deploymentsresource to a separate PR, as it is not related to the resource declaration issue. WDYT?
Yeah makes sense to me.
Hi, revisting the issues mentioned here and committing them.
Please check once now @nikpivkin @simar7
@eshentials What about this? https://github.com/aquasecurity/trivy/pull/9470#discussion_r2348854077
We can create a
Resourcestype with its own unmarshaling method and use it inTemplateand in child resources. This will avoid duplicate logic:type Resources []Resource func (r *Resources) UnmarshalJSONFrom(dec *jsontext.Decoder) error { switch dec.PeekKind() { case '[': var arr []Resource if err := json.UnmarshalDecode(dec, &arr); err != nil { return err } *r = arr case '{': var m map[string]Resource if err := json.UnmarshalDecode(dec, &m); err != nil { return err } res := make([]Resource, 0, len(m)) for k, v := range m { res = append(res, v) } *r = res default: return errors.New("unexpected JSON token for resources") } return nil }
Working on this currently
@nikpivkin check now
This PR is stale because it has been labeled with inactivity.