From 1de5375962306b1ce04c553eb38ad5237839959f Mon Sep 17 00:00:00 2001 From: kansi Date: Tue, 31 Oct 2017 15:16:59 +0530 Subject: [PATCH] Validate asset data keys --- bigchaindb/common/utils.py | 19 ++++++++++++++++++- bigchaindb/models.py | 4 +++- tests/web/test_transactions.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/bigchaindb/common/utils.py b/bigchaindb/common/utils.py index f6f671db..fd9386e1 100644 --- a/bigchaindb/common/utils.py +++ b/bigchaindb/common/utils.py @@ -1,7 +1,10 @@ import time - +import re import rapidjson +import bigchaindb +from bigchaindb.common.exceptions import ValidationError + def gen_timestamp(): """The Unix time, rounded to the nearest second. @@ -46,3 +49,17 @@ def deserialize(data): string. """ return rapidjson.loads(data) + + +def validate_asset_data_keys(tx_body): + backend = bigchaindb.config['database']['backend'] + + if backend == 'mongodb': + data = tx_body['asset'].get('data', {}) + keys = data.keys() if data else [] + for key in keys: + if re.search(r'^[$]|\.', key): + error_str = ('Invalid key name "{}" in asset object. The ' + 'key name cannot contain characters ' + '"." and "$"').format(key) + raise ValidationError(error_str) from ValueError() diff --git a/bigchaindb/models.py b/bigchaindb/models.py index c8ad9dd3..9704372d 100644 --- a/bigchaindb/models.py +++ b/bigchaindb/models.py @@ -8,7 +8,8 @@ from bigchaindb.common.exceptions import (InvalidHash, InvalidSignature, SybilError, DuplicateTransaction) from bigchaindb.common.transaction import Transaction -from bigchaindb.common.utils import gen_timestamp, serialize +from bigchaindb.common.utils import (gen_timestamp, serialize, + validate_asset_data_keys) from bigchaindb.common.schema import validate_transaction_schema @@ -84,6 +85,7 @@ class Transaction(Transaction): @classmethod def from_dict(cls, tx_body): validate_transaction_schema(tx_body) + validate_asset_data_keys(tx_body) return super().from_dict(tx_body) @classmethod diff --git a/tests/web/test_transactions.py b/tests/web/test_transactions.py index acea8c2c..4c2a6ed9 100644 --- a/tests/web/test_transactions.py +++ b/tests/web/test_transactions.py @@ -47,6 +47,34 @@ def test_post_create_transaction_endpoint(b, client): assert res.json['outputs'][0]['public_keys'][0] == user_pub +@pytest.mark.parametrize("key,expected_status_code", [ + ('bad.key', 400), + ('$bad.key', 400), + ('$badkey', 400), + ('good_key', 202) +]) +@pytest.mark.assetkey +@pytest.mark.bdb +def test_post_create_transaction_with_invalid_asset_key(b, client, key, expected_status_code): + from bigchaindb.models import Transaction + from bigchaindb.backend.mongodb.connection import MongoDBConnection + user_priv, user_pub = crypto.generate_key_pair() + + if isinstance(b.connection, MongoDBConnection): + tx = Transaction.create([user_pub], [([user_pub], 1)], + asset={key: 'random_value'}) + tx = tx.sign([user_priv]) + res = client.post(TX_ENDPOINT, data=json.dumps(tx.to_dict())) + + assert res.status_code == expected_status_code + if res.status_code == 400: + expected_error_message = ( + 'Invalid transaction (ValidationError): Invalid key name "{}" ' + 'in asset object. The key name cannot contain characters ' + '"." and "$"').format(key) + assert res.json['message'] == expected_error_message + + @patch('bigchaindb.web.views.base.logger') def test_post_create_transaction_with_invalid_id(mock_logger, b, client): from bigchaindb.common.exceptions import InvalidHash