Ejemplo n.º 1
0
def test_encrypt_stores_encrypted_secret(uuid_env_var, patch_get_store_path):
    enc = Encryption({'name': 'secret_thing', 'user': '******'})
    enc_string = enc.encrypt('testing123')
    assert enc_string != 'testing123'
    with open(QUSER_DB_STORE) as db_file:
        store_json = json.load(db_file)
    assert store_json['secret_thing']['secret'] == enc_string
Ejemplo n.º 2
0
def test_init_strips_leading_and_trailing_whitespace(uuid_env_var,
                                                     patch_get_store_path):
    enc = Encryption({'name': '  secret_thing  ', 'user': '******'})
    enc_string = enc.encrypt('testing123')
    with open(QUSER_DB_STORE) as db_file:
        store_json = json.load(db_file)
    assert store_json['secret_thing']['secret'] == enc_string
Ejemplo n.º 3
0
def test_encryption_stores_encrypted_secret_in_config(
        set_unset_qradar_app_uuid_env_var, patch_get_store_path):
    enc = Encryption({"name": "test_name", "user": "******"})
    enc_string = enc.encrypt('testing123')
    assert enc_string != 'testing123'

    with open(DB_STORE) as db_file:
        file_json = json.load(db_file)
        assert file_json.get('test_name').get('secret') == enc_string
Ejemplo n.º 4
0
def encrypt(key):
    # Get '?val=' query param
    value = request.args.get('val')
    # Encrypt the value with the key provided
    enc = Encryption({'name': key, 'user': '******'})
    encrypted = enc.encrypt(value)
    return render_template('encrypt.html',
                           key=key,
                           value=value,
                           encrypted=encrypted)
Ejemplo n.º 5
0
def test_decrypt_raises_error_when_secret_not_in_config_db(
        uuid_env_var, tmpdir):
    db_store = 'missing_secret_e.db'
    db_store_path = os.path.join(tmpdir.strpath, db_store)
    with open(db_store_path, 'w') as db_file:
        db_file.write('{"secret_thing": {"version": 3}}')
    with patch('qpylib.qpylib.get_store_path') as mock_get_store_path:
        mock_get_store_path.return_value = db_store_path
        enc = Encryption({'name': 'secret_thing', 'user': '******'})
        with pytest.raises(EncryptionError,
                           match='No secret found for name secret_thing'):
            enc.decrypt()
Ejemplo n.º 6
0
def test_encryption_raises_value_error_on_missing_name_and_user_fields():
    with pytest.raises(ValueError) as ex:
        Encryption({})
    assert str(ex.value) == "Encryption : name and user are mandatory fields!"

    with pytest.raises(ValueError) as ex:
        Encryption({"name": "test_name"})
    assert str(ex.value) == "Encryption : name and user are mandatory fields!"

    with pytest.raises(ValueError) as ex:
        Encryption({"user": "******"})
    assert str(ex.value) == "Encryption : name and user are mandatory fields!"
Ejemplo n.º 7
0
def test_decrypt_raises_error_on_decryption_failure(uuid_env_var, tmpdir):
    db_store = 'badsecret_e.db'
    copy_dbstore(db_store, tmpdir.strpath)
    with patch('qpylib.qpylib.get_store_path') as mock_get_store_path:
        mock_get_store_path.return_value = os.path.join(
            tmpdir.strpath, db_store)
        enc = Encryption({'name': 'secret_thing', 'user': '******'})
        with pytest.raises(
                EncryptionError,
                match=
                'Failed to decrypt secret for name secret_thing: InvalidToken'
        ):
            enc.decrypt()
Ejemplo n.º 8
0
def decrypt(key):
    # Set up encdec encryption
    enc = Encryption({'name': key, 'user': '******'})
    try:
        # Attempt to decrypt the value
        decrypted = enc.decrypt()
        return render_template('decrypt.html',
                               key=key,
                               decrypted=decrypted,
                               key_found=True)
    except EncryptionError:
        # EncryptionError raised, handle the error with a template describing
        # that the decryption failed (for example if the key doesn't exist)
        return render_template('decrypt.html', key=key, key_found=False)
Ejemplo n.º 9
0
 def save(self):
     """ Save to the secure storage
     """
     try:
         from qpylib.encdec import Encryption
         Encryption({'name': self.name, 'user': self.simpleHash(self.user)}).encrypt(self.pswd)
     except Exception as ex:
         pass
Ejemplo n.º 10
0
 def load(self):
     """ Load from the secure storage
     """
     try:
         from qpylib.encdec import Encryption
         self.pswd = Encryption({'name': self.name, 'user': self.simpleHash(self.user)}).decrypt()
     except Exception as ex:
         pass
Ejemplo n.º 11
0
def test_init_raises_error_on_invalid_config_file_json(uuid_env_var, tmpdir):
    db_store = 'bad_content_e.db'
    db_store_path = os.path.join(tmpdir.strpath, db_store)
    with open(db_store_path, 'w') as db_file:
        db_file.write('{invalid json}')
    with patch('qpylib.qpylib.get_store_path') as mock_get_store_path:
        mock_get_store_path.return_value = db_store_path
        with pytest.raises(EncryptionError,
                           match='Unable to load config store'):
            Encryption({'name': 'secret_thing', 'user': '******'})
Ejemplo n.º 12
0
def test_decrypt_raises_error_on_invalid_config_engine_version(
        uuid_env_var, tmpdir):
    db_store = 'bad_engine_version_e.db'
    db_store_path = os.path.join(tmpdir.strpath, db_store)
    with open(db_store_path, 'w') as db_file:
        db_file.write(
            '{"secret_thing": {"version": 1, "secret": "522ae11b6b2b88cb1bb16adea76f7b96"}}'
        )
    with patch('qpylib.qpylib.get_store_path') as mock_get_store_path:
        mock_get_store_path.return_value = db_store_path
        enc = Encryption({
            'name': 'secret_thing',
            'user': '******'
        })
        with pytest.raises(EncryptionError) as ex:
            enc.decrypt()
        assert str(
            ex.value
        ) == 'Config for name secret_thing contains invalid engine version 1'
Ejemplo n.º 13
0
def test_decrypt_raises_error_when_config_missing(
        set_unset_qradar_app_uuid_env_var, patch_get_store_path):
    enc = Encryption({"name": "test_name", "user": "******"})
    enc_string = enc.encrypt('testing123')
    assert enc_string != 'testing123'
    os.remove(DB_STORE)
    enc = Encryption({"name": "test_name", "user": "******"})
    with pytest.raises(ValueError) as ex:
        enc.decrypt()
    assert str(ex.value) == "Encryption : no secret to decrypt"
Ejemplo n.º 14
0
def repeatable_encrypt():
    e = Encryption({"name": "test_name", "user": "******"})
    e.config["test_name"]['salt'] = 'Lk&RBjmg,22Xcs`!'
    e.config["test_name"]['UUID'] = '6599ba78-4896-11e8-842f-0ed5f89f718b'
    e.config["test_name"]['ivz'] = 'AXN(=,ix7=s,e}g\\'
    e.config["test_name"]['iterations'] = 100000
    return e
Ejemplo n.º 15
0
def create_app():
    # Create a Flask instance.
    qflask = Flask(__name__)

    csrf = CSRFProtect()
    csrf.init_app(qflask)

    # Retrieve QRadar app id.
    qradar_app_id = qpylib.get_app_id()

    # Create unique session cookie name for this app.
    qflask.config['SESSION_COOKIE_NAME'] = 'session_{0}'.format(qradar_app_id)

    secret_key = ""
    try:
        # Read in secret key
        secret_key_store = Encryption({'name': 'secret_key', 'user': '******'})
        secret_key = secret_key_store.decrypt()
    except EncryptionError:
        # If secret key file doesn't exist/fail to decrypt it,
        # generate a new random password for it and encrypt it
        secret_key = secrets.token_urlsafe(64)
        secret_key_store = Encryption({'name': 'secret_key', 'user': '******'})
        secret_key_store.encrypt(secret_key)

    qflask.config["SECRET_KEY"] = secret_key

    # Hide server details in endpoint responses.
    # pylint: disable=unused-variable
    @qflask.after_request
    def obscure_server_header(resp):
        resp.headers['Server'] = 'QRadar App {0}'.format(qradar_app_id)
        return resp

    # Register q_url_for function for use with Jinja2 templates.
    qflask.add_template_global(qpylib.q_url_for, 'q_url_for')

    # Initialize logging.
    qpylib.create_log()

    # To enable app health checking, the QRadar App Framework
    # requires every Flask app to define a /debug endpoint.
    # The endpoint function should contain a trivial implementation
    # that returns a simple confirmation response message.
    @qflask.route('/debug')
    def debug():
        return 'Pong!'

    # Import additional endpoints.
    # For more information see:
    #   https://flask.palletsprojects.com/en/1.1.x/tutorial/views
    from . import views
    qflask.register_blueprint(views.viewsbp)

    return qflask
Ejemplo n.º 16
0
def test_decrypt_handles_enginev3_secrets(v3_uuid_env_var, tmpdir):
    db_store = 'v3user_e.db'
    copy_dbstore(db_store, tmpdir.strpath)
    with patch('qpylib.qpylib.get_store_path') as mock_get_store_path:
        mock_get_store_path.return_value = os.path.join(
            tmpdir.strpath, db_store)
        mykey = Encryption({'name': 'mykey', 'user': '******'})
        assert mykey.decrypt() == '12345678'
        mytoken = Encryption({'name': 'mytoken', 'user': '******'})
        assert mytoken.decrypt() == 'abcdefghij'
Ejemplo n.º 17
0
def test_encrypt_raises_error_when_config_db_not_writable(
        uuid_env_var, tmpdir):
    db_store = QUSER_DB_STORE
    db_store_path = os.path.join(tmpdir.strpath, db_store)
    with patch('qpylib.qpylib.get_store_path') as mock_get_store_path:
        mock_get_store_path.return_value = db_store_path
        enc = Encryption({'name': 'secret_thing', 'user': '******'})
        enc.encrypt('xyz')
        os.chmod(db_store_path, 0o400)
        with pytest.raises(EncryptionError, match='Unable to save config'):
            enc.encrypt('xyz')
Ejemplo n.º 18
0
def test_decrypt_raise_value_error_on_engine_version_mismatch(
        set_unset_qradar_app_uuid_env_var, patch_get_store_path):
    enc = Encryption({"name": "test_name", "user": "******"})
    enc_string = enc.encrypt('testing123')
    assert enc_string != 'testing123'

    with open(DB_STORE) as db_file:
        file_json = json.load(db_file)
    file_json['test_name']['version'] = -1
    with open(DB_STORE, 'w') as db_file:
        json.dump(file_json, db_file)
    enc = Encryption({"name": "test_name", "user": "******"})
    with pytest.raises(ValueError) as ex:
        enc.decrypt()
    assert "Encryption : secret engine mismatch." in str(ex.value)
Ejemplo n.º 19
0
def test_encrypt_raises_error_on_encryption_failure(uuid_env_var,
                                                    patch_get_store_path):
    enc = Encryption({'name': 'secret_thing', 'user': '******'})
    enc.encrypt('mypassword')
    with patch('qpylib.encdec.Encryption.latest_engine_class'
               ) as mock_latest_engine:
        mock_latest_engine.return_value = DummyEngine
        with pytest.raises(
                EncryptionError,
                match=
                'Failed to encrypt secret for name secret_thing: ValueError'):
            enc.encrypt('mypassword')
Ejemplo n.º 20
0
def test_decrypt_returns_incorrect_plaintext_with_altered_salt(
        set_unset_qradar_app_uuid_env_var, patch_get_store_path):
    enc = Encryption({"name": "test_name", "user": "******"})
    enc_string = enc.encrypt('testing123')
    assert enc_string != 'testing123'

    with open(DB_STORE) as db_file:
        file_json = json.load(db_file)
    file_json['test_name']['salt'] = 'incorrect'
    with open(DB_STORE, 'w') as db_file:
        json.dump(file_json, db_file)
    enc = Encryption({"name": "test_name", "user": "******"})
    assert enc.decrypt() != 'testing123'
Ejemplo n.º 21
0
def test_decrypt_v3_secret_reencrypts_with_latest_engine(
        v3_uuid_env_var, tmpdir):
    db_store = 'v3user_e.db'
    copy_dbstore(db_store, tmpdir.strpath)
    with patch('qpylib.qpylib.get_store_path') as mock_get_store_path:
        db_store_path = os.path.join(tmpdir.strpath, db_store)
        mock_get_store_path.return_value = db_store_path
        mytoken = Encryption({'name': 'mytoken', 'user': '******'})
        assert mytoken.config['mytoken']['version'] == 3
        assert mytoken.decrypt() == 'abcdefghij'
        # DB config for 'mytoken' has now been updated with latest engine version details.
        mytoken2 = Encryption({'name': 'mytoken', 'user': '******'})
        assert mytoken2.config['mytoken'][
            'version'] == Encryption.latest_engine_version
        assert mytoken2.decrypt() == 'abcdefghij'
        with open(db_store_path) as db_file:
            store_json = json.load(db_file)
        assert store_json['mytoken'][
            'version'] == Encryption.latest_engine_version
Ejemplo n.º 22
0
def test_init_raises_error_on_missing_uuid_env_var():
    with pytest.raises(
            EncryptionError,
            match='Environment variable QRADAR_APP_UUID is missing'):
        Encryption({'name': 'secret_thing', 'user': '******'})
Ejemplo n.º 23
0
def test_init_raises_error_on_whitespace_user_field():
    with pytest.raises(EncryptionError,
                       match='Supplied name and user cannot be empty'):
        Encryption({'name': 'secret_thing', 'user': '******'})
Ejemplo n.º 24
0
def test_init_raises_error_on_empty_name_field():
    with pytest.raises(EncryptionError,
                       match='Supplied name and user cannot be empty'):
        Encryption({'name': '', 'user': '******'})
Ejemplo n.º 25
0
def test_init_raises_error_on_missing_user_field():
    with pytest.raises(EncryptionError,
                       match='You must supply name and user strings'):
        Encryption({'name': 'secret_thing'})
Ejemplo n.º 26
0
def test_init_raises_error_on_missing_name_field():
    with pytest.raises(EncryptionError,
                       match='You must supply name and user strings'):
        Encryption({'user': '******'})
Ejemplo n.º 27
0
def test_init_raises_error_on_missing_data_fields():
    with pytest.raises(EncryptionError,
                       match='You must supply name and user strings'):
        Encryption({})
Ejemplo n.º 28
0
def test_encrypt_decrypt_whitespace(uuid_env_var, patch_get_store_path):
    enc = Encryption({'name': 'secret_thing', 'user': '******'})
    assert enc.encrypt('  \n \t ')
    assert enc.decrypt() == '  \n \t '
Ejemplo n.º 29
0
def test_encrypt_decrypt_empty_string(uuid_env_var, patch_get_store_path):
    enc = Encryption({'name': 'secret_thing', 'user': '******'})
    enc.encrypt('')
    assert enc.decrypt() == ''
Ejemplo n.º 30
0
def test_encrypt_decrypt_null_char(uuid_env_var, patch_get_store_path):
    enc = Encryption({'name': 'secret_thing', 'user': '******'})
    enc.encrypt('\x00')
    assert enc.decrypt() == '\x00'