VYPR
High severity7.5NVD Advisory· Published Aug 11, 2017· Updated May 13, 2026

CVE-2017-7675

CVE-2017-7675

Description

The HTTP/2 implementation in Apache Tomcat 9.0.0.M1 to 9.0.0.M21 and 8.5.0 to 8.5.15 bypassed a number of security checks that prevented directory traversal attacks. It was therefore possible to bypass security constraints using a specially crafted URL.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.tomcat:tomcatMaven
>= 9.0.0.M1, < 9.0.0.M229.0.0.M22
org.apache.tomcat:tomcatMaven
>= 8.5.0, < 8.5.168.5.16

Affected products

38
  • Apache/Tomcat37 versions
    cpe:2.3:a:apache:tomcat:8.5.0:*:*:*:*:*:*:*+ 36 more
    • cpe:2.3:a:apache:tomcat:8.5.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:8.5.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:8.5.10:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:8.5.11:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:8.5.12:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:8.5.13:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:8.5.14:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:8.5.15:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:8.5.2:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:8.5.3:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:8.5.4:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:8.5.5:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:8.5.6:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:8.5.7:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:8.5.8:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:8.5.9:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone1:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone10:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone11:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone12:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone13:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone14:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone15:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone16:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone17:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone18:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone19:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone2:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone20:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone21:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone3:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone4:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone5:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone6:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone7:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone8:*:*:*:*:*:*
    • cpe:2.3:a:apache:tomcat:9.0.0:milestone9:*:*:*:*:*:*
  • Apache Software Foundation/Apache Tomcatv5
    Range: 9.0.0.M1 to 9.0.0.M21

Patches

2
dacb030b85fe

Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=61120

https://github.com/apache/tomcatMark ThomasMay 24, 2017via ghsa
3 files changed · +109 7
  • java/org/apache/coyote/http2/Stream.java+8 7 modified
    @@ -18,6 +18,7 @@
     
     import java.io.IOException;
     import java.nio.ByteBuffer;
    +import java.nio.charset.StandardCharsets;
     import java.security.AccessController;
     import java.security.PrivilegedActionException;
     import java.security.PrivilegedExceptionAction;
    @@ -307,18 +308,18 @@ public final void emitHeader(String name, String value) throws HpackException {
                             getConnectionId(), getIdentifier()));
                 }
                 int queryStart = value.indexOf('?');
    +            String uri;
                 if (queryStart == -1) {
    -                coyoteRequest.requestURI().setString(value);
    -                coyoteRequest.decodedURI().setString(
    -                        coyoteRequest.getURLDecoder().convert(value, false));
    +                uri = value;
                 } else {
    -                String uri = value.substring(0, queryStart);
    +                uri = value.substring(0, queryStart);
                     String query = value.substring(queryStart + 1);
    -                coyoteRequest.requestURI().setString(uri);
    -                coyoteRequest.decodedURI().setString(
    -                        coyoteRequest.getURLDecoder().convert(uri, false));
                     coyoteRequest.queryString().setString(query);
                 }
    +            // Bug 61120. Set the URI as bytes rather than String so any path
    +            // parameters are correctly processed
    +            byte[] uriBytes = uri.getBytes(StandardCharsets.ISO_8859_1);
    +            coyoteRequest.requestURI().setBytes(uriBytes, 0, uriBytes.length);
                 break;
             }
             case ":authority": {
    
  • test/org/apache/coyote/http2/TestStream.java+97 0 added
    @@ -0,0 +1,97 @@
    +/*
    + *  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.coyote.http2;
    +
    +import java.io.IOException;
    +import java.nio.ByteBuffer;
    +
    +import javax.servlet.ServletException;
    +import javax.servlet.http.HttpServlet;
    +import javax.servlet.http.HttpServletRequest;
    +import javax.servlet.http.HttpServletResponse;
    +
    +import org.junit.Assert;
    +import org.junit.Test;
    +
    +import org.apache.catalina.Context;
    +import org.apache.catalina.startup.Tomcat;
    +
    +public class TestStream extends Http2TestBase {
    +
    +    /*
    +     * https://bz.apache.org/bugzilla/show_bug.cgi?id=61120
    +     */
    +    @Test
    +    public void testPathParam() throws Exception {
    +
    +        enableHttp2();
    +
    +        Tomcat tomcat = getTomcatInstance();
    +
    +        Context ctxt = tomcat.addContext("", null);
    +        Tomcat.addServlet(ctxt, "simple", new SimpleServlet());
    +        ctxt.addServletMappingDecoded("/simple", "simple");
    +        Tomcat.addServlet(ctxt, "pathparam", new PathParam());
    +        ctxt.addServletMappingDecoded("/pathparam", "pathparam");
    +
    +        tomcat.start();
    +
    +        openClientConnection();
    +        doHttpUpgrade();
    +        sendClientPreface();
    +        validateHttp2InitialResponse();
    +
    +        byte[] frameHeader = new byte[9];
    +        ByteBuffer headersPayload = ByteBuffer.allocate(128);
    +        buildGetRequest(frameHeader, headersPayload, null, 3,
    +                "/pathparam;jsessionid=" + PathParam.EXPECTED_SESSION_ID);
    +        writeFrame(frameHeader, headersPayload);
    +
    +        readSimpleGetResponse();
    +
    +        Assert.assertEquals(
    +                "3-HeadersStart\n" +
    +                "3-Header-[:status]-[200]\n" +
    +                "3-Header-[content-type]-[text/plain;charset=UTF-8]\n" +
    +                "3-Header-[date]-[Wed, 11 Nov 2015 19:18:42 GMT]\n" +
    +                "3-HeadersEnd\n" +
    +                "3-Body-2\n" +
    +                "3-EndOfStream\n", output.getTrace());
    +    }
    +
    +
    +    private static final class PathParam extends HttpServlet {
    +
    +        private static final long serialVersionUID = 1L;
    +
    +        public static final String EXPECTED_SESSION_ID = "0123456789ABCDEF";
    +
    +        @Override
    +        protected void doGet(HttpServletRequest request, HttpServletResponse response)
    +                throws ServletException, IOException {
    +
    +            response.setContentType("text/plain");
    +            response.setCharacterEncoding("UTF-8");
    +
    +            if (EXPECTED_SESSION_ID.equals(request.getRequestedSessionId())) {
    +                response.getWriter().write("OK");
    +            } else {
    +                response.getWriter().write("FAIL");
    +            }
    +        }
    +    }
    +}
    
  • webapps/docs/changelog.xml+4 0 modified
    @@ -69,6 +69,10 @@
             <bug>61086</bug>: Explicitly signal an empty request body for HTTP 205
             responses. (markt)
           </fix>
    +      <fix>
    +        <bug>61120</bug>: Do not ignore path parameters when processing HTTP/2
    +        requests. (markt)
    +      </fix>
         </changelog>
       </subsection>
       <subsection name="Other">
    
cf181edc9a8c

Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=61120

https://github.com/apache/tomcatMark ThomasMay 24, 2017via ghsa
3 files changed · +109 7
  • java/org/apache/coyote/http2/Stream.java+8 7 modified
    @@ -18,6 +18,7 @@
     
     import java.io.IOException;
     import java.nio.ByteBuffer;
    +import java.nio.charset.StandardCharsets;
     import java.security.AccessController;
     import java.security.PrivilegedActionException;
     import java.security.PrivilegedExceptionAction;
    @@ -299,18 +300,18 @@ public final void emitHeader(String name, String value) throws HpackException {
                             getConnectionId(), getIdentifier()));
                 }
                 int queryStart = value.indexOf('?');
    +            String uri;
                 if (queryStart == -1) {
    -                coyoteRequest.requestURI().setString(value);
    -                coyoteRequest.decodedURI().setString(
    -                        coyoteRequest.getURLDecoder().convert(value, false));
    +                uri = value;
                 } else {
    -                String uri = value.substring(0, queryStart);
    +                uri = value.substring(0, queryStart);
                     String query = value.substring(queryStart + 1);
    -                coyoteRequest.requestURI().setString(uri);
    -                coyoteRequest.decodedURI().setString(
    -                        coyoteRequest.getURLDecoder().convert(uri, false));
                     coyoteRequest.queryString().setString(query);
                 }
    +            // Bug 61120. Set the URI as bytes rather than String so any path
    +            // parameters are correctly processed
    +            byte[] uriBytes = uri.getBytes(StandardCharsets.ISO_8859_1);
    +            coyoteRequest.requestURI().setBytes(uriBytes, 0, uriBytes.length);
                 break;
             }
             case ":authority": {
    
  • test/org/apache/coyote/http2/TestStream.java+97 0 added
    @@ -0,0 +1,97 @@
    +/*
    + *  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.coyote.http2;
    +
    +import java.io.IOException;
    +import java.nio.ByteBuffer;
    +
    +import javax.servlet.ServletException;
    +import javax.servlet.http.HttpServlet;
    +import javax.servlet.http.HttpServletRequest;
    +import javax.servlet.http.HttpServletResponse;
    +
    +import org.junit.Assert;
    +import org.junit.Test;
    +
    +import org.apache.catalina.Context;
    +import org.apache.catalina.startup.Tomcat;
    +
    +public class TestStream extends Http2TestBase {
    +
    +    /*
    +     * https://bz.apache.org/bugzilla/show_bug.cgi?id=61120
    +     */
    +    @Test
    +    public void testPathParam() throws Exception {
    +
    +        enableHttp2();
    +
    +        Tomcat tomcat = getTomcatInstance();
    +
    +        Context ctxt = tomcat.addContext("", null);
    +        Tomcat.addServlet(ctxt, "simple", new SimpleServlet());
    +        ctxt.addServletMappingDecoded("/simple", "simple");
    +        Tomcat.addServlet(ctxt, "pathparam", new PathParam());
    +        ctxt.addServletMappingDecoded("/pathparam", "pathparam");
    +
    +        tomcat.start();
    +
    +        openClientConnection();
    +        doHttpUpgrade();
    +        sendClientPreface();
    +        validateHttp2InitialResponse();
    +
    +        byte[] frameHeader = new byte[9];
    +        ByteBuffer headersPayload = ByteBuffer.allocate(128);
    +        buildGetRequest(frameHeader, headersPayload, null, 3,
    +                "/pathparam;jsessionid=" + PathParam.EXPECTED_SESSION_ID);
    +        writeFrame(frameHeader, headersPayload);
    +
    +        readSimpleGetResponse();
    +
    +        Assert.assertEquals(
    +                "3-HeadersStart\n" +
    +                "3-Header-[:status]-[200]\n" +
    +                "3-Header-[content-type]-[text/plain;charset=UTF-8]\n" +
    +                "3-Header-[date]-[Wed, 11 Nov 2015 19:18:42 GMT]\n" +
    +                "3-HeadersEnd\n" +
    +                "3-Body-2\n" +
    +                "3-EndOfStream\n", output.getTrace());
    +    }
    +
    +
    +    private static final class PathParam extends HttpServlet {
    +
    +        private static final long serialVersionUID = 1L;
    +
    +        public static final String EXPECTED_SESSION_ID = "0123456789ABCDEF";
    +
    +        @Override
    +        protected void doGet(HttpServletRequest request, HttpServletResponse response)
    +                throws ServletException, IOException {
    +
    +            response.setContentType("text/plain");
    +            response.setCharacterEncoding("UTF-8");
    +
    +            if (EXPECTED_SESSION_ID.equals(request.getRequestedSessionId())) {
    +                response.getWriter().write("OK");
    +            } else {
    +                response.getWriter().write("FAIL");
    +            }
    +        }
    +    }
    +}
    
  • webapps/docs/changelog.xml+4 0 modified
    @@ -69,6 +69,10 @@
             <bug>61086</bug>: Explicitly signal an empty request body for HTTP 205
             responses. (markt)
           </fix>
    +      <fix>
    +        <bug>61120</bug>: Do not ignore path parameters when processing HTTP/2
    +        requests. (markt)
    +      </fix>
         </changelog>
       </subsection>
       <subsection name="Jasper">
    

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

35

News mentions

0

No linked articles in our index yet.