Medium severity5.9NVD Advisory· Published Sep 25, 2017· Updated May 13, 2026
CVE-2015-7315
CVE-2015-7315
Description
Plone 3.3.0 through 3.3.6, 4.0.0 through 4.0.10, 4.1.0 through 4.1.6, 4.2.0 through 4.2.7, 4.3.0 through 4.3.6, and 5.0rc1 allows remote attackers to add a new member to a Plone site with registration enabled, without acknowledgment of site administrator.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
Products.CMFPlonePyPI | >= 3.3.0, < 4.3.7 | 4.3.7 |
Products.CMFPlonePyPI | >= 5.0a1, < 5.0rc2 | 5.0rc2 |
PlonePyPI | >= 3.3, <= 3.3.6 | — |
PlonePyPI | >= 4.0a1, <= 4.0.10 | — |
PlonePyPI | >= 4.1a1, <= 4.1.6 | — |
PlonePyPI | >= 4.2a1, <= 4.2.7 | — |
PlonePyPI | >= 4.3a1, <= 4.3.6 | — |
Patches
39f0111f85cd1Apply hotfixes from https://pypi.python.org/pypi/Products.PloneHotfix20150910
7 files changed · +65 −3
docs/CHANGES.rst+3 −0 modified@@ -8,6 +8,9 @@ Changelog 4.3.7 (unreleased) ------------------ +- Apply hotfixes from https://pypi.python.org/pypi/Products.PloneHotfix20150910 + [vangheem] + - Do not throw a 404 on site root RSS feeds [vangheem]
Products/CMFPlone/patches/addMember.py+8 −0 added@@ -0,0 +1,8 @@ +try: + from Products.CMFPlone import patches # noqa +except ImportError: + pass + +from Products.CMFCore.RegistrationTool import RegistrationTool +if hasattr(RegistrationTool.addMember.im_func, '__doc__'): + del RegistrationTool.addMember.im_func.__doc__
Products/CMFPlone/patches/__init__.py+8 −0 modified@@ -24,3 +24,11 @@ import sendmail sendmail.applyPatches() + +try: + # kupu may not be installed + import kupu +except ImportError: + pass + +import addMember \ No newline at end of file
Products/CMFPlone/patches/kupu.py+22 −0 added@@ -0,0 +1,22 @@ +##################### +# Newly created sites + +from AccessControl.Permission import _registeredPermissions +from AccessControl.Permission import ApplicationDefaultPermissions +from AccessControl.Permission import pname +from Products.kupu.plone import permissions + + +mangled = pname(permissions.ManageLibraries) +if hasattr(ApplicationDefaultPermissions, mangled): + delattr(ApplicationDefaultPermissions, mangled) + + +if permissions.ManageLibraries in _registeredPermissions: + del _registeredPermissions[permissions.ManageLibraries] + + +permissions.setDefaultRoles( + permissions.ManageLibraries, + ('Manager', 'Site Administrator',) + )
Products/CMFPlone/tests/testCSRFProtection.py+12 −3 modified@@ -63,9 +63,18 @@ def test_PloneTool_renameObjectsByPaths(self): self.assertTrue(self.portal.get('foo', None)) def test_RegistrationTool_addMember(self): - self.checkAuthenticator( - '/portal_registration/addMember', - 'id=john&password=y0d4Wg') + # self.checkAuthenticator( + # '/portal_registration/addMember', + # 'id=john&password=y0d4Wg') + # instead of authenticator, with latest patch, addMember should not + # be published + path = '/portal_registration/addMember' + path = '/' + self.portal.absolute_url(relative=True) + path + query = 'id=john&password=y0d4Wg' + data = StringIO(query) + response = self.publish(path=path, env={}, + request_method='POST', stdin=data) + self.assertEqual(response.getStatus(), 404) def test_RegistrationTool_editMember(self): self.checkAuthenticator(
Products/CMFPlone/tests/testURLTool.py+9 −0 modified@@ -96,3 +96,12 @@ def test_isURLInPortalExternal(self): self.assertFalse(iURLiP('http://external4/other')) self.assertFalse(iURLiP('http://external5')) self.assertFalse(iURLiP('http://external11')) + + def test_script_tag_url_not_in_portal(self): + self.assertFalse(self.portal.portal_url.isURLInPortal('<script>alert("hi");</script>')) + self.assertFalse( + self.portal.portal_url.isURLInPortal('%3Cscript%3Ealert(%22hi%22)%3B%3C%2Fscript%3E')) + + def test_inline_url_not_in_portal(self): + self.assertFalse(self.portal.portal_url.isURLInPortal('javascript%3Aalert(3)')) + self.assertFalse(self.portal.portal_url.isURLInPortal('javascript:alert(3)'))
Products/CMFPlone/URLTool.py+3 −0 modified@@ -30,6 +30,9 @@ def isURLInPortal(self, url, context=None): """ # sanitize url url = re.sub('^[\x00-\x20]+', '', url).strip() + if ('<script' in url or '%3Cscript' in url or 'javascript:' in url or + 'javascript%3A' in url): + return False p_url = self()
1845b0a92312Apply isURLInPortal fix from https://pypi.python.org/pypi/Products.PloneHotfix20150910
3 files changed · +15 −0
CHANGES.rst+3 −0 modified@@ -8,6 +8,9 @@ Changelog 5.0rc2 (unreleased) ------------------- +- Apply isURLInPortal fix from https://pypi.python.org/pypi/Products.PloneHotfix20150910 + [vangheem] + - Do not bother additional CRSF protection for addMember since all public users get same CSRF token and the method should be unpublished. See https://pypi.python.org/pypi/Products.PloneHotfix20150910
Products/CMFPlone/tests/testURLTool.py+9 −0 modified@@ -96,3 +96,12 @@ def test_isURLInPortalExternal(self): self.assertFalse(iURLiP('http://external4/other')) self.assertFalse(iURLiP('http://external5')) self.assertFalse(iURLiP('http://external11')) + + def test_script_tag_url_not_in_portal(self): + self.assertFalse(self.portal.portal_url.isURLInPortal('<script>alert("hi");</script>')) + self.assertFalse( + self.portal.portal_url.isURLInPortal('%3Cscript%3Ealert(%22hi%22)%3B%3C%2Fscript%3E')) + + def test_inline_url_not_in_portal(self): + self.assertFalse(self.portal.portal_url.isURLInPortal('javascript%3Aalert(3)')) + self.assertFalse(self.portal.portal_url.isURLInPortal('javascript:alert(3)'))
Products/CMFPlone/URLTool.py+3 −0 modified@@ -30,6 +30,9 @@ def isURLInPortal(self, url, context=None): """ # sanitize url url = re.sub('^[\x00-\x20]+', '', url).strip() + if ('<script' in url or '%3Cscript' in url or 'javascript:' in url or + 'javascript%3A' in url): + return False p_url = self()
e1d981bfa14bMake sure RegistrationTool.addMember is not published
2 files changed · +13 −9
Products/CMFCore/CHANGES.txt+2 −1 modified@@ -4,7 +4,8 @@ Products.CMFCore Changelog 2.3.1 (unreleased) ------------------ -- Nothing changed yet. +- Make sure RegistrationTool.addMember is not published + [vangheem] 2.3.0 (2015-02-20)
Products/CMFCore/RegistrationTool.py+11 −8 modified@@ -132,14 +132,17 @@ def generatePassword(self): @postonly def addMember(self, id, password, roles=('Member',), domains='', properties=None, REQUEST=None): - '''Creates a PortalMember and returns it. The properties argument - can be a mapping with additional member properties. Raises an - exception if the given id already exists, the password does not - comply with the policy in effect, or the authenticated user is not - allowed to grant one of the roles listed (where Member is a special - role that can always be granted); these conditions should be - detected before the fact so that a cleaner message can be printed. - ''' + # XXX Do not make this a normal method comment. Doing so makes + # this method publishable + + # Creates a PortalMember and returns it. The properties argument + # can be a mapping with additional member properties. Raises an + # exception if the given id already exists, the password does not + # comply with the policy in effect, or the authenticated user is not + # allowed to grant one of the roles listed (where Member is a special + # role that can always be granted); these conditions should be + # detected before the fact so that a cleaner message can be printed. + if not self.isMemberIdAllowed(id): raise ValueError(_(u'The login name you selected is already in ' u'use or is not valid. Please choose another.'))
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- www.openwall.com/lists/oss-security/2015/09/22/13nvdMailing ListPatchThird Party AdvisoryWEB
- bugzilla.redhat.com/show_bug.cginvdIssue TrackingPatchThird Party AdvisoryWEB
- github.com/zopefoundation/Products.CMFCore/commit/e1d981bfa14b664317285f0f36498f4be4a23406nvdIssue TrackingPatchThird Party AdvisoryWEB
- github.com/advisories/GHSA-984m-rj28-8c6xghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2015-7315ghsaADVISORY
- plone.org/security/hotfix/20150910/anonymous-is-able-to-create-plone-membersnvdVendor AdvisoryWEB
- github.com/plone/Products.CMFPlone/commit/1845b0a92312291811b68907bf2aa0fb448c4016ghsaWEB
- github.com/plone/Products.CMFPlone/commit/9f0111f85cd14f3f067044b59b93e2856c99d542ghsaWEB
- github.com/pypa/advisory-database/tree/main/vulns/plone/PYSEC-2017-52.yamlghsaWEB
- pypi.org/project/Products.PloneHotfix20150910ghsaWEB
News mentions
0No linked articles in our index yet.