Skip to content

Commit 17febe1

Browse files
authored
Merge pull request #4709 from StackStorm/issue/disallowDecryptKVForValuesMarkedSecret
Disallow decrypt_kv jinja filter for fields marked as secret for pack config
2 parents b785e35 + abdf613 commit 17febe1

File tree

11 files changed

+120
-1
lines changed

11 files changed

+120
-1
lines changed

CHANGELOG.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Changed
99

1010
* Allow the orquesta st2kv function to return default for nonexistent key. (improvement) #4678
1111
* Update requests library to latest version (2.22.0) in requirements. (improvement) #4680
12+
* Disallow "decrypt_kv" filter to be specified in the config for values that are marked as
13+
"secret: True" in the schema. (improvement) #4709
1214

1315
Fixed
1416
~~~~~

st2api/st2api/controllers/v1/pack_configs.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ def put(self, pack_config_content, pack_ref, requester_user, show_secrets=False)
107107
config_api.validate(validate_against_schema=True)
108108
except jsonschema.ValidationError as e:
109109
raise ValueValidationException(six.text_type(e))
110+
except ValueValidationException as e:
111+
raise ValueValidationException(six.text_type(e))
110112

111113
self._dump_config_to_disk(config_api)
112114

st2api/tests/unit/controllers/v1/test_pack_configs.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
from st2tests.api import FunctionalTest
2020
from st2api.controllers.v1.pack_configs import PackConfigsController
21-
2221
from st2tests.fixturesloader import get_fixtures_packs_base_path
2322

2423
__all__ = [
@@ -79,3 +78,16 @@ def test_put_pack_config(self):
7978
get_resp.json['values'], expect_errors=True)
8079
self.assertEqual(put_resp.status_int, 200)
8180
self.assertEqual(get_resp.json, put_resp_undo.json)
81+
82+
@mock.patch.object(PackConfigsController, '_dump_config_to_disk', mock.MagicMock())
83+
def test_put_invalid_pack_config(self):
84+
get_resp = self.app.get('/v1/configs/dummy_pack_11', params={'show_secrets': True},
85+
expect_errors=True)
86+
config = copy.copy(get_resp.json['values'])
87+
put_resp = self.app.put_json('/v1/configs/dummy_pack_11', config, expect_errors=True)
88+
self.assertEqual(put_resp.status_int, 400)
89+
expected_msg = ('Values specified as "secret: True" in config schema are automatically '
90+
'decrypted by default. Use of "decrypt_kv" jinja filter is not allowed '
91+
'for such values. Please check the specified values in the config or '
92+
'the default values in the schema.')
93+
self.assertTrue(expected_msg in put_resp.json['faultstring'])

st2common/st2common/util/pack.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
from st2common.constants.pack import PACK_REF_WHITELIST_REGEX
2626
from st2common.content.loader import MetaLoader
2727
from st2common.persistence.pack import Pack
28+
from st2common.exceptions.apivalidation import ValueValidationException
29+
from st2common.util import jinja as jinja_utils
2830

2931
__all__ = [
3032
'get_pack_ref_from_metadata',
@@ -110,6 +112,14 @@ def validate_config_against_schema(config_schema, config_object, config_path,
110112
cleaned = util_schema.validate(instance=instance, schema=schema,
111113
cls=util_schema.CustomValidator, use_default=True,
112114
allow_default_none=True)
115+
for key in cleaned:
116+
if (jinja_utils.is_jinja_expression(value=cleaned.get(key)) and
117+
"decrypt_kv" in cleaned.get(key) and config_schema.get(key).get('secret')):
118+
raise ValueValidationException('Values specified as "secret: True" in config '
119+
'schema are automatically decrypted by default. Use '
120+
'of "decrypt_kv" jinja filter is not allowed for '
121+
'such values. Please check the specified values in '
122+
'the config or the default values in the schema.')
113123
except jsonschema.ValidationError as e:
114124
attribute = getattr(e, 'path', [])
115125

st2common/tests/unit/test_configs_registrar.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
PACK_1_PATH = os.path.join(fixturesloader.get_fixtures_packs_base_path(), 'dummy_pack_1')
3737
PACK_6_PATH = os.path.join(fixturesloader.get_fixtures_packs_base_path(), 'dummy_pack_6')
3838
PACK_19_PATH = os.path.join(fixturesloader.get_fixtures_packs_base_path(), 'dummy_pack_19')
39+
PACK_11_PATH = os.path.join(fixturesloader.get_fixtures_packs_base_path(), 'dummy_pack_11')
40+
PACK_22_PATH = os.path.join(fixturesloader.get_fixtures_packs_base_path(), 'dummy_pack_22')
3941

4042

4143
class ConfigsRegistrarTestCase(CleanDbTestCase):
@@ -148,3 +150,63 @@ def test_register_all_configs_with_config_schema_validation_validation_failure_2
148150
self.assertRaisesRegexp(ValueError, expected_msg,
149151
registrar.register_from_packs,
150152
base_dirs=packs_base_paths)
153+
154+
def test_register_all_configs_with_config_schema_validation_validation_failure_3(self):
155+
# This test checks for values containing "decrypt_kv" jinja filter in the config
156+
# object where keys have "secret: True" set in the schema.
157+
158+
# Verify DB is empty
159+
pack_dbs = Pack.get_all()
160+
config_dbs = Config.get_all()
161+
162+
self.assertEqual(len(pack_dbs), 0)
163+
self.assertEqual(len(config_dbs), 0)
164+
165+
registrar = ConfigsRegistrar(use_pack_cache=False, fail_on_failure=True,
166+
validate_configs=True)
167+
registrar._pack_loader.get_packs = mock.Mock()
168+
registrar._pack_loader.get_packs.return_value = {'dummy_pack_11': PACK_11_PATH}
169+
170+
# Register ConfigSchema for pack
171+
registrar._register_pack_db = mock.Mock()
172+
registrar._register_pack(pack_name='dummy_pack_11', pack_dir=PACK_11_PATH)
173+
packs_base_paths = content_utils.get_packs_base_paths()
174+
175+
expected_msg = ('Values specified as "secret: True" in config schema are automatically '
176+
'decrypted by default. Use of "decrypt_kv" jinja filter is not allowed '
177+
'for such values. Please check the specified values in the config or '
178+
'the default values in the schema.')
179+
180+
self.assertRaisesRegexp(ValueError, expected_msg,
181+
registrar.register_from_packs,
182+
base_dirs=packs_base_paths)
183+
184+
def test_register_all_configs_with_config_schema_validation_validation_failure_4(self):
185+
# This test checks for default values containing "decrypt_kv" jinja filter for
186+
# keys which have "secret: True" set.
187+
188+
# Verify DB is empty
189+
pack_dbs = Pack.get_all()
190+
config_dbs = Config.get_all()
191+
192+
self.assertEqual(len(pack_dbs), 0)
193+
self.assertEqual(len(config_dbs), 0)
194+
195+
registrar = ConfigsRegistrar(use_pack_cache=False, fail_on_failure=True,
196+
validate_configs=True)
197+
registrar._pack_loader.get_packs = mock.Mock()
198+
registrar._pack_loader.get_packs.return_value = {'dummy_pack_22': PACK_22_PATH}
199+
200+
# Register ConfigSchema for pack
201+
registrar._register_pack_db = mock.Mock()
202+
registrar._register_pack(pack_name='dummy_pack_22', pack_dir=PACK_22_PATH)
203+
packs_base_paths = content_utils.get_packs_base_paths()
204+
205+
expected_msg = ('Values specified as "secret: True" in config schema are automatically '
206+
'decrypted by default. Use of "decrypt_kv" jinja filter is not allowed '
207+
'for such values. Please check the specified values in the config or '
208+
'the default values in the schema.')
209+
210+
self.assertRaisesRegexp(ValueError, expected_msg,
211+
registrar.register_from_packs,
212+
base_dirs=packs_base_paths)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
api_key: "{{st2kv.user.api_key | decrypt_kv}}"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
---
2+
key_with_no_secret_and_no_default: "Any Value"
3+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
api_key:
3+
type: "string"
4+
secret: true
5+
required: true
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
name : dummy_pack_11
3+
description : dummy pack
4+
version : 0.1.0
5+
author : st2-dev
6+
email : info@stackstorm.com
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
wrong_key_with_invalid_default_value:
3+
type: "string"
4+
secret: true
5+
required: true
6+
default: "{{st2kv.user.api_key | decrypt_kv}}"
7+
key_with_no_secret_and_no_default:
8+
type: "string"
9+

0 commit comments

Comments
 (0)