microsoft / PSRule

Validate infrastructure as code (IaC) and objects using PowerShell rules.
https://microsoft.github.io/PSRule/v2/
MIT License
392 stars 49 forks source link

`Invoke-PSRule -OutputFormat 'Json'` fails if all found rules are in `RULE.EXCLUDE` #1832

Open o-l-a-v opened 4 months ago

o-l-a-v commented 4 months ago

Description of the issue

As mentoined in this issue comment:

If doing Invoke-PSRule -OutputFormat 'Json' where all findings are excluded with -Option @{'RULE.EXCLUDE'=[string[]](<rules>), the command fails with error OperationStopped: Index was outside the bounds of the array.

Seems it happens in the toJson override here:

Setting -OutputFormat 'None' works fine.

To Reproduce

Steps to reproduce the issue:

# Assets
$FilePath = [string] 'some\file\path.bicepparam'

# Get all available rules and find the ones to exclude
$PSRuleRulesAvailable = [array](Get-PSRule -Module 'PSRule.Rules.Azure')
$PSRuleRulesExclude   = [string[]](
    $PSRuleRulesAvailable.Where{
        $_.'Tags'.'Release' -ne 'GA' -or
        $_.'Tags'.'Azure.WAF/pillar' -eq 'Reliability' -or
        $_.'Info'.'Annotations'.'severity' -eq 'Awareness'
    }.'Name' | Sort-Object
)

# Run PSRule
## Fails - RULES.EXCLUDE
[PSCustomObject[]](
    Invoke-PSRule -InputPath $FilePath -Module 'PSRule.Rules.Azure' -Outcome 'Fail','Error' -OutputFormat 'Json' -Option @{
        'AZURE_BICEP_CHECK_TOOL'             = [bool] $true
        'AZURE_BICEP_FILE_EXPANSION'         = [bool] $true
        'AZURE_BICEP_FILE_EXPANSION_TIMEOUT' = [uint16] 30
        'AZURE_BICEP_PARAMS_FILE_EXPANSION'  = [bool] $true
        'RULE.EXCLUDE'                       = [string[]]($PSRuleRulesExclude)
    } | ConvertFrom-Json | Sort-Object -Property 'ruleName'
)

## Succeedes - Where-Object exclusions afterwards
[PSCustomObject[]](
    Invoke-PSRule -InputPath $FilePath -Module 'PSRule.Rules.Azure' -Outcome 'Fail','Error' -OutputFormat 'Json' -Option @{
        'AZURE_BICEP_CHECK_TOOL'             = [bool] $true
        'AZURE_BICEP_FILE_EXPANSION'         = [bool] $true
        'AZURE_BICEP_FILE_EXPANSION_TIMEOUT' = [uint16] 30
        'AZURE_BICEP_PARAMS_FILE_EXPANSION'  = [bool] $true
    } | ConvertFrom-Json | Where-Object -FilterScript {$_.'ruleName' -notin $PSRuleRulesExclude} | Sort-Object -Property 'ruleName'
)

Expected behaviour

ToString should not be called if no findings?

TargetSite     : System.String ToJson(System.Object[], System.Nullable`1[System.Int32])
Message        : Index was outside the bounds of the array.
Data           : {[System.Management.Automation.Interpreter.InterpretedFrameInfo,
                 System.Management.Automation.Interpreter.InterpretedFrameInfo[]]}
InnerException : 
HelpLink       : 
Source         : Microsoft.PSRule.Core
HResult        : -2146233080
StackTrace     :    at PSRule.Pipeline.Output.JsonOutputWriter.ToJson(Object[] o, Nullable`1 jsonIndent) in
                 /_/src/PSRule/Pipeline/Output/JsonOutputWriter.cs:line 25
                    at PSRule.Pipeline.Output.JsonOutputWriter.Serialize(Object[] o) in
                 /_/src/PSRule/Pipeline/Output/JsonOutputWriter.cs:line 20
                    at PSRule.Pipeline.SerializationOutputWriter`1.End() in /_/src/PSRule/Pipeline/PipelineWriter.cs:line 432
                    at PSRule.Pipeline.InvokeRulePipeline.End() in /_/src/PSRule/Pipeline/InvokeRulePipeline.cs:line 98
                    at CallSite.Target(Closure, CallSite, Object)
                    at System.Management.Automation.Interpreter.DynamicInstruction`2.Run(InterpretedFrame frame)
                    at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
...
VERBOSE: [PSRule][R][10][PSRule.Rules.Azure\Azure.WebPubSub.ManagedIdentity] :: 7d331434a7045-Site-Publish-Cred-1
OperationStopped: Index was outside the bounds of the array.
VERBOSE: [Invoke-PSRule] END::
PS >

Module in use and version:

Additional context

BernieWhite commented 4 months ago

Thanks for reporting the issue @o-l-a-v.

Also maybe check out this example for building a baseline dynamically. https://github.com/Azure/PSRule.Rules.Azure/blob/ad6ab981befdc149b22748e5e519552493b401d7/scripts/security-baseline.ps1