Skip to content

Commit f00852b

Browse files
committed
Added flags to disable env and file ops #2515
1 parent c716d15 commit f00852b

File tree

10 files changed

+222
-0
lines changed

10 files changed

+222
-0
lines changed

cmd/root.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ yq -P -oy sample.json
218218
panic(err)
219219
}
220220

221+
rootCmd.PersistentFlags().BoolVarP(&yqlib.ConfiguredSecurityPreferences.DisableEnvOps, "security-disable-env-ops", "", false, "Disable env related operations.")
222+
rootCmd.PersistentFlags().BoolVarP(&yqlib.ConfiguredSecurityPreferences.DisableFileOps, "security-disable-file-ops", "", false, "Disable file related operations (e.g. load)")
223+
221224
rootCmd.AddCommand(
222225
createEvaluateSequenceCommand(),
223226
createEvaluateAllCommand(),

pkg/yqlib/doc/operators/env-variable-operators.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ as follows:
2929
yq '(.. | select(tag == "!!str")) |= envsubst' file.yaml
3030
```
3131

32+
## Disabling env operators
33+
If required, you can use the `--security-disable-env-ops` to disable env operations.
34+
3235

3336
## Read string environment variable
3437
Running
@@ -254,3 +257,39 @@ will output
254257
Error: variable ${notThere} not set
255258
```
256259

260+
## env() operation fails when security is enabled
261+
Use `--security-disable-env-ops` to disable env operations for security.
262+
263+
Running
264+
```bash
265+
yq --null-input 'env("MYENV")'
266+
```
267+
will output
268+
```bash
269+
Error: env operations have been disabled
270+
```
271+
272+
## strenv() operation fails when security is enabled
273+
Use `--security-disable-env-ops` to disable env operations for security.
274+
275+
Running
276+
```bash
277+
yq --null-input 'strenv("MYENV")'
278+
```
279+
will output
280+
```bash
281+
Error: env operations have been disabled
282+
```
283+
284+
## envsubst() operation fails when security is enabled
285+
Use `--security-disable-env-ops` to disable env operations for security.
286+
287+
Running
288+
```bash
289+
yq --null-input '"value: ${MYENV}" | envsubst'
290+
```
291+
will output
292+
```bash
293+
Error: env operations have been disabled
294+
```
295+

pkg/yqlib/doc/operators/headers/env-variable-operators.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,6 @@ as follows:
2929
yq '(.. | select(tag == "!!str")) |= envsubst' file.yaml
3030
```
3131

32+
## Disabling env operators
33+
If required, you can use the `--security-disable-env-ops` to disable env operations.
34+

pkg/yqlib/doc/operators/headers/load.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,7 @@ this.is = a properties file
4646
```
4747
bXkgc2VjcmV0IGNoaWxsaSByZWNpcGUgaXMuLi4u
4848
```
49+
50+
## Disabling file operators
51+
If required, you can use the `--security-disable-file-ops` to disable file operations.
52+

pkg/yqlib/doc/operators/load.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ this.is = a properties file
4747
bXkgc2VjcmV0IGNoaWxsaSByZWNpcGUgaXMuLi4u
4848
```
4949

50+
## Disabling file operators
51+
If required, you can use the `--security-disable-file-ops` to disable file operations.
52+
53+
5054
## Simple example
5155
Given a sample.yml file of:
5256
```yaml
@@ -194,3 +198,63 @@ cool: things
194198
more_stuff: my secret chilli recipe is....
195199
```
196200

201+
## load() operation fails when security is enabled
202+
Use `--security-disable-file-ops` to disable file operations for security.
203+
204+
Running
205+
```bash
206+
yq --null-input 'load("../../examples/thing.yml")'
207+
```
208+
will output
209+
```bash
210+
Error: file operations have been disabled
211+
```
212+
213+
## load_str() operation fails when security is enabled
214+
Use `--security-disable-file-ops` to disable file operations for security.
215+
216+
Running
217+
```bash
218+
yq --null-input 'load_str("../../examples/thing.yml")'
219+
```
220+
will output
221+
```bash
222+
Error: file operations have been disabled
223+
```
224+
225+
## load_xml() operation fails when security is enabled
226+
Use `--security-disable-file-ops` to disable file operations for security.
227+
228+
Running
229+
```bash
230+
yq --null-input 'load_xml("../../examples/small.xml")'
231+
```
232+
will output
233+
```bash
234+
Error: file operations have been disabled
235+
```
236+
237+
## load_props() operation fails when security is enabled
238+
Use `--security-disable-file-ops` to disable file operations for security.
239+
240+
Running
241+
```bash
242+
yq --null-input 'load_props("../../examples/small.properties")'
243+
```
244+
will output
245+
```bash
246+
Error: file operations have been disabled
247+
```
248+
249+
## load_base64() operation fails when security is enabled
250+
Use `--security-disable-file-ops` to disable file operations for security.
251+
252+
Running
253+
```bash
254+
yq --null-input 'load_base64("../../examples/base64.txt")'
255+
```
256+
will output
257+
```bash
258+
Error: file operations have been disabled
259+
```
260+

pkg/yqlib/operator_env.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ type envOpPreferences struct {
1717
}
1818

1919
func envOperator(_ *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
20+
if ConfiguredSecurityPreferences.DisableEnvOps {
21+
return Context{}, fmt.Errorf("env operations have been disabled")
22+
}
2023
envName := expressionNode.Operation.CandidateNode.Value
2124
log.Debug("EnvOperator, env name:", envName)
2225

@@ -54,6 +57,9 @@ func envOperator(_ *dataTreeNavigator, context Context, expressionNode *Expressi
5457
}
5558

5659
func envsubstOperator(_ *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
60+
if ConfiguredSecurityPreferences.DisableEnvOps {
61+
return Context{}, fmt.Errorf("env operations have been disabled")
62+
}
5763
var results = list.New()
5864
preferences := envOpPreferences{}
5965
if expressionNode.Operation.Preferences != nil {

pkg/yqlib/operator_env_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,40 @@ func TestEnvOperatorScenarios(t *testing.T) {
250250
}
251251
documentOperatorScenarios(t, "env-variable-operators", envOperatorScenarios)
252252
}
253+
254+
var envOperatorSecurityDisabledScenarios = []expressionScenario{
255+
{
256+
description: "env() operation fails when security is enabled",
257+
subdescription: "Use `--security-disable-env-ops` to disable env operations for security.",
258+
expression: `env("MYENV")`,
259+
expectedError: "env operations have been disabled",
260+
},
261+
{
262+
description: "strenv() operation fails when security is enabled",
263+
subdescription: "Use `--security-disable-env-ops` to disable env operations for security.",
264+
expression: `strenv("MYENV")`,
265+
expectedError: "env operations have been disabled",
266+
},
267+
{
268+
description: "envsubst() operation fails when security is enabled",
269+
subdescription: "Use `--security-disable-env-ops` to disable env operations for security.",
270+
expression: `"value: ${MYENV}" | envsubst`,
271+
expectedError: "env operations have been disabled",
272+
},
273+
}
274+
275+
func TestEnvOperatorSecurityDisabledScenarios(t *testing.T) {
276+
// Save original security preferences
277+
originalDisableEnvOps := ConfiguredSecurityPreferences.DisableEnvOps
278+
defer func() {
279+
ConfiguredSecurityPreferences.DisableEnvOps = originalDisableEnvOps
280+
}()
281+
282+
// Test that env() fails when DisableEnvOps is true
283+
ConfiguredSecurityPreferences.DisableEnvOps = true
284+
285+
for _, tt := range envOperatorSecurityDisabledScenarios {
286+
testScenario(t, &tt)
287+
}
288+
appendOperatorDocumentScenario(t, "env-variable-operators", envOperatorSecurityDisabledScenarios)
289+
}

pkg/yqlib/operator_load.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ func loadWithDecoder(filename string, decoder Decoder) (*CandidateNode, error) {
6363

6464
func loadStringOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
6565
log.Debugf("loadString")
66+
if ConfiguredSecurityPreferences.DisableFileOps {
67+
return Context{}, fmt.Errorf("file operations have been disabled")
68+
}
6669

6770
var results = list.New()
6871

@@ -94,6 +97,9 @@ func loadStringOperator(d *dataTreeNavigator, context Context, expressionNode *E
9497

9598
func loadOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
9699
log.Debugf("loadOperator")
100+
if ConfiguredSecurityPreferences.DisableFileOps {
101+
return Context{}, fmt.Errorf("file operations have been disabled")
102+
}
97103

98104
loadPrefs := expressionNode.Operation.Preferences.(loadPrefs)
99105

pkg/yqlib/operator_load_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,52 @@ func TestLoadScenarios(t *testing.T) {
131131
}
132132
documentOperatorScenarios(t, "load", loadScenarios)
133133
}
134+
135+
var loadOperatorSecurityDisabledScenarios = []expressionScenario{
136+
{
137+
description: "load() operation fails when security is enabled",
138+
subdescription: "Use `--security-disable-file-ops` to disable file operations for security.",
139+
expression: `load("../../examples/thing.yml")`,
140+
expectedError: "file operations have been disabled",
141+
},
142+
{
143+
description: "load_str() operation fails when security is enabled",
144+
subdescription: "Use `--security-disable-file-ops` to disable file operations for security.",
145+
expression: `load_str("../../examples/thing.yml")`,
146+
expectedError: "file operations have been disabled",
147+
},
148+
{
149+
description: "load_xml() operation fails when security is enabled",
150+
subdescription: "Use `--security-disable-file-ops` to disable file operations for security.",
151+
expression: `load_xml("../../examples/small.xml")`,
152+
expectedError: "file operations have been disabled",
153+
},
154+
{
155+
description: "load_props() operation fails when security is enabled",
156+
subdescription: "Use `--security-disable-file-ops` to disable file operations for security.",
157+
expression: `load_props("../../examples/small.properties")`,
158+
expectedError: "file operations have been disabled",
159+
},
160+
{
161+
description: "load_base64() operation fails when security is enabled",
162+
subdescription: "Use `--security-disable-file-ops` to disable file operations for security.",
163+
expression: `load_base64("../../examples/base64.txt")`,
164+
expectedError: "file operations have been disabled",
165+
},
166+
}
167+
168+
func TestLoadOperatorSecurityDisabledScenarios(t *testing.T) {
169+
// Save original security preferences
170+
originalDisableFileOps := ConfiguredSecurityPreferences.DisableFileOps
171+
defer func() {
172+
ConfiguredSecurityPreferences.DisableFileOps = originalDisableFileOps
173+
}()
174+
175+
// Test that load operations fail when DisableFileOps is true
176+
ConfiguredSecurityPreferences.DisableFileOps = true
177+
178+
for _, tt := range loadOperatorSecurityDisabledScenarios {
179+
testScenario(t, &tt)
180+
}
181+
appendOperatorDocumentScenario(t, "load", loadOperatorSecurityDisabledScenarios)
182+
}

pkg/yqlib/security_prefs.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package yqlib
2+
3+
type SecurityPreferences struct {
4+
DisableEnvOps bool
5+
DisableFileOps bool
6+
}
7+
8+
var ConfiguredSecurityPreferences = SecurityPreferences{
9+
DisableEnvOps: false,
10+
DisableFileOps: false,
11+
}

0 commit comments

Comments
 (0)