View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.xml.secure;
19  
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertNotNull;
22  import static org.junit.jupiter.api.Assertions.assertTrue;
23  
24  import java.io.StringWriter;
25  
26  import javax.xml.transform.Templates;
27  import javax.xml.transform.Transformer;
28  import javax.xml.transform.TransformerFactory;
29  import javax.xml.transform.sax.SAXTransformerFactory;
30  import javax.xml.transform.sax.TemplatesHandler;
31  import javax.xml.transform.stream.StreamResult;
32  
33  import org.junit.jupiter.api.Tag;
34  import org.junit.jupiter.api.Test;
35  
36  /**
37   * {@link TemplatesHandler} products of the secure factory: {@code xsl:include} resolution during the SAX-driven compile sits on the factory's resolver floor,
38   * and the {@link Templates} returned by {@link TemplatesHandler#getTemplates()} produce Transformers that carry the floor. The unconfigured control proves the
39   * vector leaks without the securing.
40   */
41  @Tag("trax")
42  class TemplatesHandlerTest {
43  
44      private static String compileAndTransform(final TemplatesHandler handler, final String stylesheet) throws Exception {
45          handler.setSystemId(AttackTestSupport.resourceUrl(stylesheet).toString());
46          SaxSurfaceTestSupport.feed(handler, SaxSurfaceTestSupport.resourceInput(stylesheet));
47          final Templates templates = handler.getTemplates();
48          assertNotNull(templates, "stylesheet failed to compile");
49          // Build the Transformer: a failed compile does not always throw, only building the transformer surfaces it.
50          final Transformer transformer = templates.newTransformer();
51          final StringWriter sink = new StringWriter();
52          transformer.transform(AttackTestSupport.streamSource("<root/>"), new StreamResult(sink));
53          return sink.toString();
54      }
55  
56      @Test
57      void secureTemplatesHandlerDoesNotLeakDocument() throws Exception {
58          // The f004 product path: the Templates from getTemplates() must produce floored Transformers for runtime document().
59          final TemplatesHandler handler = SaxSurfaceTestSupport.secureFactory().newTemplatesHandler();
60          assertFalse(compileAndTransform(handler, "with-document.xsl").contains(AttackTestSupport.LEAKED_MARKER),
61                  "document() through TemplatesHandler.getTemplates() leaked");
62      }
63  
64      @Test
65      void secureTemplatesHandlerDoesNotLeakInclude() throws Exception {
66          final TemplatesHandler handler = SaxSurfaceTestSupport.secureFactory().newTemplatesHandler();
67          assertFalse(compileAndTransform(handler, "with-include.xsl").contains(AttackTestSupport.LEAKED_MARKER),
68                  "xsl:include through TemplatesHandler leaked");
69      }
70  
71      @Test
72      void unconfiguredTemplatesHandlerLeaksDocument() throws Exception {
73          final TemplatesHandler handler = ((SAXTransformerFactory) TransformerFactory.newInstance()).newTemplatesHandler();
74          assertTrue(compileAndTransform(handler, "with-document.xsl").contains(AttackTestSupport.LEAKED_MARKER),
75                  "unconfigured TemplatesHandler should resolve document()");
76      }
77  }