Added flags to disable env and file ops #2515

This commit is contained in:
Mike Farah 2025-11-22 09:40:03 +11:00
parent c716d157f2
commit f00852bc6c
10 changed files with 222 additions and 0 deletions

View File

@ -218,6 +218,9 @@ yq -P -oy sample.json
panic(err) panic(err)
} }
rootCmd.PersistentFlags().BoolVarP(&yqlib.ConfiguredSecurityPreferences.DisableEnvOps, "security-disable-env-ops", "", false, "Disable env related operations.")
rootCmd.PersistentFlags().BoolVarP(&yqlib.ConfiguredSecurityPreferences.DisableFileOps, "security-disable-file-ops", "", false, "Disable file related operations (e.g. load)")
rootCmd.AddCommand( rootCmd.AddCommand(
createEvaluateSequenceCommand(), createEvaluateSequenceCommand(),
createEvaluateAllCommand(), createEvaluateAllCommand(),

View File

@ -29,6 +29,9 @@ as follows:
yq '(.. | select(tag == "!!str")) |= envsubst' file.yaml yq '(.. | select(tag == "!!str")) |= envsubst' file.yaml
``` ```
## Disabling env operators
If required, you can use the `--security-disable-env-ops` to disable env operations.
## Read string environment variable ## Read string environment variable
Running Running
@ -254,3 +257,39 @@ will output
Error: variable ${notThere} not set Error: variable ${notThere} not set
``` ```
## env() operation fails when security is enabled
Use `--security-disable-env-ops` to disable env operations for security.
Running
```bash
yq --null-input 'env("MYENV")'
```
will output
```bash
Error: env operations have been disabled
```
## strenv() operation fails when security is enabled
Use `--security-disable-env-ops` to disable env operations for security.
Running
```bash
yq --null-input 'strenv("MYENV")'
```
will output
```bash
Error: env operations have been disabled
```
## envsubst() operation fails when security is enabled
Use `--security-disable-env-ops` to disable env operations for security.
Running
```bash
yq --null-input '"value: ${MYENV}" | envsubst'
```
will output
```bash
Error: env operations have been disabled
```

View File

@ -29,3 +29,6 @@ as follows:
yq '(.. | select(tag == "!!str")) |= envsubst' file.yaml yq '(.. | select(tag == "!!str")) |= envsubst' file.yaml
``` ```
## Disabling env operators
If required, you can use the `--security-disable-env-ops` to disable env operations.

View File

@ -46,3 +46,7 @@ this.is = a properties file
``` ```
bXkgc2VjcmV0IGNoaWxsaSByZWNpcGUgaXMuLi4u bXkgc2VjcmV0IGNoaWxsaSByZWNpcGUgaXMuLi4u
``` ```
## Disabling file operators
If required, you can use the `--security-disable-file-ops` to disable file operations.

View File

@ -47,6 +47,10 @@ this.is = a properties file
bXkgc2VjcmV0IGNoaWxsaSByZWNpcGUgaXMuLi4u bXkgc2VjcmV0IGNoaWxsaSByZWNpcGUgaXMuLi4u
``` ```
## Disabling file operators
If required, you can use the `--security-disable-file-ops` to disable file operations.
## Simple example ## Simple example
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
@ -194,3 +198,63 @@ cool: things
more_stuff: my secret chilli recipe is.... more_stuff: my secret chilli recipe is....
``` ```
## load() operation fails when security is enabled
Use `--security-disable-file-ops` to disable file operations for security.
Running
```bash
yq --null-input 'load("../../examples/thing.yml")'
```
will output
```bash
Error: file operations have been disabled
```
## load_str() operation fails when security is enabled
Use `--security-disable-file-ops` to disable file operations for security.
Running
```bash
yq --null-input 'load_str("../../examples/thing.yml")'
```
will output
```bash
Error: file operations have been disabled
```
## load_xml() operation fails when security is enabled
Use `--security-disable-file-ops` to disable file operations for security.
Running
```bash
yq --null-input 'load_xml("../../examples/small.xml")'
```
will output
```bash
Error: file operations have been disabled
```
## load_props() operation fails when security is enabled
Use `--security-disable-file-ops` to disable file operations for security.
Running
```bash
yq --null-input 'load_props("../../examples/small.properties")'
```
will output
```bash
Error: file operations have been disabled
```
## load_base64() operation fails when security is enabled
Use `--security-disable-file-ops` to disable file operations for security.
Running
```bash
yq --null-input 'load_base64("../../examples/base64.txt")'
```
will output
```bash
Error: file operations have been disabled
```

View File

@ -17,6 +17,9 @@ type envOpPreferences struct {
} }
func envOperator(_ *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) { func envOperator(_ *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
if ConfiguredSecurityPreferences.DisableEnvOps {
return Context{}, fmt.Errorf("env operations have been disabled")
}
envName := expressionNode.Operation.CandidateNode.Value envName := expressionNode.Operation.CandidateNode.Value
log.Debug("EnvOperator, env name:", envName) log.Debug("EnvOperator, env name:", envName)
@ -54,6 +57,9 @@ func envOperator(_ *dataTreeNavigator, context Context, expressionNode *Expressi
} }
func envsubstOperator(_ *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) { func envsubstOperator(_ *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
if ConfiguredSecurityPreferences.DisableEnvOps {
return Context{}, fmt.Errorf("env operations have been disabled")
}
var results = list.New() var results = list.New()
preferences := envOpPreferences{} preferences := envOpPreferences{}
if expressionNode.Operation.Preferences != nil { if expressionNode.Operation.Preferences != nil {

View File

@ -250,3 +250,40 @@ func TestEnvOperatorScenarios(t *testing.T) {
} }
documentOperatorScenarios(t, "env-variable-operators", envOperatorScenarios) documentOperatorScenarios(t, "env-variable-operators", envOperatorScenarios)
} }
var envOperatorSecurityDisabledScenarios = []expressionScenario{
{
description: "env() operation fails when security is enabled",
subdescription: "Use `--security-disable-env-ops` to disable env operations for security.",
expression: `env("MYENV")`,
expectedError: "env operations have been disabled",
},
{
description: "strenv() operation fails when security is enabled",
subdescription: "Use `--security-disable-env-ops` to disable env operations for security.",
expression: `strenv("MYENV")`,
expectedError: "env operations have been disabled",
},
{
description: "envsubst() operation fails when security is enabled",
subdescription: "Use `--security-disable-env-ops` to disable env operations for security.",
expression: `"value: ${MYENV}" | envsubst`,
expectedError: "env operations have been disabled",
},
}
func TestEnvOperatorSecurityDisabledScenarios(t *testing.T) {
// Save original security preferences
originalDisableEnvOps := ConfiguredSecurityPreferences.DisableEnvOps
defer func() {
ConfiguredSecurityPreferences.DisableEnvOps = originalDisableEnvOps
}()
// Test that env() fails when DisableEnvOps is true
ConfiguredSecurityPreferences.DisableEnvOps = true
for _, tt := range envOperatorSecurityDisabledScenarios {
testScenario(t, &tt)
}
appendOperatorDocumentScenario(t, "env-variable-operators", envOperatorSecurityDisabledScenarios)
}

View File

@ -63,6 +63,9 @@ func loadWithDecoder(filename string, decoder Decoder) (*CandidateNode, error) {
func loadStringOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) { func loadStringOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
log.Debugf("loadString") log.Debugf("loadString")
if ConfiguredSecurityPreferences.DisableFileOps {
return Context{}, fmt.Errorf("file operations have been disabled")
}
var results = list.New() var results = list.New()
@ -94,6 +97,9 @@ func loadStringOperator(d *dataTreeNavigator, context Context, expressionNode *E
func loadOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) { func loadOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
log.Debugf("loadOperator") log.Debugf("loadOperator")
if ConfiguredSecurityPreferences.DisableFileOps {
return Context{}, fmt.Errorf("file operations have been disabled")
}
loadPrefs := expressionNode.Operation.Preferences.(loadPrefs) loadPrefs := expressionNode.Operation.Preferences.(loadPrefs)

View File

@ -131,3 +131,52 @@ func TestLoadScenarios(t *testing.T) {
} }
documentOperatorScenarios(t, "load", loadScenarios) documentOperatorScenarios(t, "load", loadScenarios)
} }
var loadOperatorSecurityDisabledScenarios = []expressionScenario{
{
description: "load() operation fails when security is enabled",
subdescription: "Use `--security-disable-file-ops` to disable file operations for security.",
expression: `load("../../examples/thing.yml")`,
expectedError: "file operations have been disabled",
},
{
description: "load_str() operation fails when security is enabled",
subdescription: "Use `--security-disable-file-ops` to disable file operations for security.",
expression: `load_str("../../examples/thing.yml")`,
expectedError: "file operations have been disabled",
},
{
description: "load_xml() operation fails when security is enabled",
subdescription: "Use `--security-disable-file-ops` to disable file operations for security.",
expression: `load_xml("../../examples/small.xml")`,
expectedError: "file operations have been disabled",
},
{
description: "load_props() operation fails when security is enabled",
subdescription: "Use `--security-disable-file-ops` to disable file operations for security.",
expression: `load_props("../../examples/small.properties")`,
expectedError: "file operations have been disabled",
},
{
description: "load_base64() operation fails when security is enabled",
subdescription: "Use `--security-disable-file-ops` to disable file operations for security.",
expression: `load_base64("../../examples/base64.txt")`,
expectedError: "file operations have been disabled",
},
}
func TestLoadOperatorSecurityDisabledScenarios(t *testing.T) {
// Save original security preferences
originalDisableFileOps := ConfiguredSecurityPreferences.DisableFileOps
defer func() {
ConfiguredSecurityPreferences.DisableFileOps = originalDisableFileOps
}()
// Test that load operations fail when DisableFileOps is true
ConfiguredSecurityPreferences.DisableFileOps = true
for _, tt := range loadOperatorSecurityDisabledScenarios {
testScenario(t, &tt)
}
appendOperatorDocumentScenario(t, "load", loadOperatorSecurityDisabledScenarios)
}

View File

@ -0,0 +1,11 @@
package yqlib
type SecurityPreferences struct {
DisableEnvOps bool
DisableFileOps bool
}
var ConfiguredSecurityPreferences = SecurityPreferences{
DisableEnvOps: false,
DisableFileOps: false,
}