Moderate severityNVD Advisory· Published Jul 9, 2012· Updated Apr 29, 2026
CVE-2012-2138
CVE-2012-2138
Description
The @CopyFrom operation in the POST servlet in the org.apache.sling.servlets.post bundle before 2.1.2 in Apache Sling does not prevent attempts to copy an ancestor node to a descendant node, which allows remote attackers to cause a denial of service (infinite loop) via a crafted HTTP request.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.sling:org.apache.sling.servlets.postMaven | < 2.1.2 | 2.1.2 |
Affected products
1- cpe:2.3:a:apache:org.apache.sling.servlets.post:*:*:*:*:*:*:*:*Range: <=2.1.0
Patches
10205892908d6SLING-2517 - validity checks for CopyFrom paths, with tests
https://github.com/apache/sling-org-apache-sling-servlets-postBertrand DelacretazJun 22, 2012via ghsa
2 files changed · +95 −0
src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java+18 −0 modified@@ -97,6 +97,11 @@ static Item copy(Item src, Node dstParent, String name) static Item copy(Node src, Node dstParent, String name) throws RepositoryException { + if(isAncestorOrSameNode(src, dstParent)) { + throw new RepositoryException( + "Cannot copy ancestor " + src.getPath() + " to descendant " + dstParent.getPath()); + } + // ensure destination name if (name == null) { name = src.getName(); @@ -127,6 +132,19 @@ static Item copy(Node src, Node dstParent, String name) } return dst; } + + /** @return true if src is an ancestor node of dest, or if + * both are the same node */ + static boolean isAncestorOrSameNode(Node src, Node dest) throws RepositoryException { + if(src.getPath().equals("/")) { + return true; + } else if(src.getPath().equals(dest.getPath())) { + return true; + } else if(dest.getPath().startsWith(src.getPath() + "/")) { + return true; + } + return false; + } /** * Copy the <code>src</code> property into the <code>dstParent</code>
src/test/java/org/apache/sling/servlets/post/impl/operations/CopyOperationTest.java+77 −0 added@@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.servlets.post.impl.operations; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import junit.framework.TestCase; + +import org.jmock.Expectations; +import org.jmock.Mockery; +import org.jmock.integration.junit4.JMock; +import org.jmock.integration.junit4.JUnit4Mockery; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(JMock.class) +public class CopyOperationTest extends TestCase { + private Mockery context = new JUnit4Mockery(); + private int counter; + + private void assertResult(final String srcPath, final String destPath, Boolean expectedResult) throws RepositoryException { + counter++; + final Node src = context.mock(Node.class, "src" + counter); + final Node dest = context.mock(Node.class, "dest" + counter); + + context.checking(new Expectations() { + { + allowing(src).getPath(); + will(returnValue(srcPath)); + allowing(dest).getPath(); + will(returnValue(destPath)); + } + }); + + final boolean result = CopyOperation.isAncestorOrSameNode(src, dest); + assertEquals( + "Expecting isAncestorOrSameNode to be " + expectedResult + " for " + srcPath + " and " + destPath, + expectedResult.booleanValue(), result); + } + + @Test + public void testIsAncestorOrSameNode() throws RepositoryException { + final Object [] testCases = { + "/", "/", true, + "/a", "/a", true, + "/a/bee/ceee", "/a/bee/ceee", true, + "/", "/tmp", true, + "/a", "/a/b", true, + "/a", "/a/b/c/dee/eeee", true, + "/a", "/ab", false, + "/ab/cd", "/ab/cde", false, + "/ab", "/cd", false, + }; + + for(int i=0; i < testCases.length; i+=3) { + assertResult((String)testCases[i], (String)testCases[i+1], (Boolean)(testCases[i+2])); + } + + } +} \ No newline at end of file
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-342c-f869-5m44ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2012-2138ghsaADVISORY
- mail-archives.apache.org/mod_mbox/www-announce/201207.mbox/%3CCAEWfVJ=PwoQmwJg0KmbrC17Gw51kgfKRsqgy=4RpMQsdGh0bVg@mail.gmail.com%3EghsaWEB
- svn.apache.org/viewvcnvdWEB
- github.com/apache/sling-org-apache-sling-servlets-post/commit/0205892908d6ea755645be5fc16e9df53e2e7261ghsaWEB
- issues.apache.org/jira/browse/SLING-2517nvdWEB
- mail-archives.apache.org/mod_mbox/www-announce/201207.mbox/%3CCAEWfVJ=PwoQmwJg0KmbrC17Gw51kgfKRsqgy=4RpMQsdGh0bVg%40mail.gmail.com%3Envd
News mentions
0No linked articles in our index yet.