CVE-2022-4724 (Python, published 2022-12-27T15:15Z)
Description: value: Improper Access Control in GitHub repository ikus060/rdiffweb prior to 2.5.5.
Severity: nan (CVSS v3 base score: 9.8)
Weakness: CWE-284 \u2014 Improper Access Control
The product does not restrict or incorrectly restricts access to a resource from an unauthorized actor.
Repository: https://github.com/ikus060/rdiffweb
Files changed:
README.md
rdiffweb/core/model/__init__.py
rdiffweb/core/model/_sshkey.py
rdiffweb/core/model/_user.py
rdiffweb/core/model/tests/test_user.py
Commit message: Make sure that all ssh keys are unique, regardless of the user


Vulnerable code:
from sqlalchemy import event
from ._sshkey import SshKey  # noqa
from sqlalchemy import Column, Integer, Text
        # Remove option, replace comments.
                SshKey(userid=self.userid, fingerprint=key.fingerprint, key=key.getvalue()).add().flush()
        # Add the key to the user
        # Add the same key

Fixed code:
* Make sure that all ssh keys are unique, regardless of the user - credit to [Nehal Pillai](https://www.linkedin.com/in/nehal-pillai-02a854172)
from sqlalchemy import event, func
from ._sshkey import SshKey, sshkey_fingerprint_index  # noqa

    # Fix SSH Key uniqueness - since 2.5.4
    if not _index_exists(connection, 'sshkey_fingerprint_index'):
        duplicate_sshkeys = (
            SshKey.query.with_entities(SshKey.fingerprint)
            .group_by(SshKey.fingerprint)
            .having(func.count(SshKey.fingerprint) > 1)
        ).all()
        try:
            sshkey_fingerprint_index.create()
        except IntegrityError:
            msg = (
                'Failure to upgrade your database to make SSH Keys unique. '
                'You must downgrade and deleted duplicate SSH Keys. '
                '%s' % '\n'.join([str(k) for k in duplicate_sshkeys]),
            )
            logger.error(msg)
            print(msg, file=sys.stderr)
            raise SystemExit(12)
from sqlalchemy import Column, Index, Integer, Text


# Make finger print unique
sshkey_fingerprint_index = Index('sshkey_fingerprint_index', SshKey.fingerprint, unique=True)
        # Remove option & Remove comment for SQL storage
                sshkey = SshKey(userid=self.userid, fingerprint=key.fingerprint, key=key.getvalue())
                sshkey.add().flush()
        # Given a user with a SSH Key

        # When adding the same identical key.
        # Then an error is raised
    def test_add_authorizedkey_duplicate_new_comment(self):
        # Read the pub key
        key = self._read_ssh_key()
        # Given a user with a SSH Key
        userobj = UserObject.get_user(self.USERNAME)
        userobj.add_authorizedkey(key)
        userobj.commit()

        # When adding the same key with a different comment
        # Then an error is raised
        with self.assertRaises(DuplicateSSHKeyError):
            userobj.add_authorizedkey(key, comment="new comment")
            userobj.commit()

    def test_add_authorizedkey_duplicate_new_user(self):
        # Read the pub key
        key = self._read_ssh_key()
        # Given a user with a SSH Key
        userobj = UserObject.get_user(self.USERNAME)
        userobj.add_authorizedkey(key)
        userobj.commit()

        # When adding the same key to a different user
        # Then an error is raised
        newuser = UserObject.add_user("newuser")
        newuser.commit()
        with self.assertRaises(DuplicateSSHKeyError):
            newuser.add_authorizedkey(key, comment="new comment")
            newuser.commit()