1313
1414package org .openmetadata .service .socket ;
1515
16- import java .net .URL ;
17- import jakarta .servlet .ServletRequest ;
18- import jakarta .servlet .ServletResponse ;
19- import jakarta .servlet .http .HttpServletRequestWrapper ;
20- import jakarta .servlet .http .HttpServletResponseWrapper ;
21-
2216import static org .openmetadata .service .exception .OMErrorPageHandler .setSecurityHeader ;
2317
2418import io .dropwizard .servlets .assets .AssetServlet ;
2519import jakarta .servlet .ServletException ;
2620import jakarta .servlet .http .HttpServletRequest ;
21+ import jakarta .servlet .http .HttpServletRequestWrapper ;
2722import jakarta .servlet .http .HttpServletResponse ;
23+ import jakarta .servlet .http .HttpServletResponseWrapper ;
2824import java .io .IOException ;
25+ import java .net .URL ;
2926import java .nio .charset .StandardCharsets ;
27+ import java .nio .file .Path ;
28+ import java .nio .file .Paths ;
3029import org .jetbrains .annotations .Nullable ;
3130import org .openmetadata .service .config .OMWebConfiguration ;
3231import org .openmetadata .service .resources .system .IndexResource ;
@@ -66,27 +65,31 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
6665
6766 // 1. Check for Brotli (br)
6867 if (acceptEncoding != null && acceptEncoding .contains ("br" )) {
69- try {
70- String fullResourcePath = getPathToCheck (req , requestUri , ".br" );
71- URL url = this .getClass ().getResource (fullResourcePath );
72- if (url != null ) {
73- serveCompressed (req , resp , requestUri , "br" , "br" );
74- return ;
75- }
76- } catch (Exception e ) {
77- // Ignore and try next
78- }
68+ try {
69+ String fullResourcePath = getPathToCheck (req , requestUri , ".br" );
70+ if (fullResourcePath != null ) {
71+ URL url = this .getClass ().getResource (fullResourcePath );
72+ if (url != null ) {
73+ serveCompressed (req , resp , requestUri , "br" , "br" );
74+ return ;
75+ }
76+ }
77+ } catch (Exception e ) {
78+ // Ignore and try next
79+ }
7980 }
8081
8182 // 2. Check for Gzip
8283 if (acceptEncoding != null && acceptEncoding .contains ("gzip" )) {
8384 try {
8485 String fullResourcePath = getPathToCheck (req , requestUri , ".gz" );
85- URL url = this .getClass ().getResource (fullResourcePath );
86-
87- if (url != null ) {
88- serveCompressed (req , resp , requestUri , "gzip" , "gz" );
89- return ;
86+ if (fullResourcePath != null ) {
87+ URL url = this .getClass ().getResource (fullResourcePath );
88+
89+ if (url != null ) {
90+ serveCompressed (req , resp , requestUri , "gzip" , "gz" );
91+ return ;
92+ }
9093 }
9194 } catch (Exception e ) {
9295 // Fallback to default behavior
@@ -109,43 +112,67 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
109112 }
110113
111114 private String getPathToCheck (HttpServletRequest req , String requestUri , String extension ) {
112- String pathToCheck = requestUri ;
113- String contextPath = req .getContextPath ();
114- if (contextPath != null && requestUri .startsWith (contextPath )) {
115- pathToCheck = requestUri .substring (contextPath .length ());
116- }
117- return this .resourcePath + (pathToCheck .startsWith ("/" ) ? "" : "/" ) + pathToCheck + extension ;
118- }
115+ String pathToCheck = requestUri ;
116+ String contextPath = req .getContextPath ();
117+ if (contextPath != null && requestUri .startsWith (contextPath )) {
118+ pathToCheck = requestUri .substring (contextPath .length ());
119+ }
119120
120- private void serveCompressed (HttpServletRequest req , HttpServletResponse resp , String requestUri , String contentEncoding , String extension ) throws ServletException , IOException {
121- resp .setHeader ("Content-Encoding" , contentEncoding );
122- String mimeType = req .getServletContext ().getMimeType (requestUri );
121+ String fullPath =
122+ this .resourcePath + (pathToCheck .startsWith ("/" ) ? "" : "/" ) + pathToCheck + extension ;
123123
124- HttpServletRequestWrapper compressedReq = new HttpServletRequestWrapper (req ) {
125- @ Override
126- public String getPathInfo () {
127- String pathInfo = super .getPathInfo ();
128- return pathInfo != null ? pathInfo + "." + extension : null ;
129- }
124+ // Validate against path traversal attacks
125+ try {
126+ Path normalizedPath = Paths .get (fullPath ).normalize ();
127+ Path baseResourcePath = Paths .get (this .resourcePath ).normalize ();
130128
131- @ Override
132- public String getRequestURI () {
133- return super .getRequestURI () + "." + extension ;
134- }
135- };
129+ if (!normalizedPath .startsWith (baseResourcePath )) {
130+ return null ;
131+ }
132+ } catch (Exception e ) {
133+ return null ;
134+ }
135+
136+ return fullPath ;
137+ }
136138
137- HttpServletResponseWrapper compressedResp = new HttpServletResponseWrapper (resp ) {
138- @ Override
139- public void setContentType (String type ) {
140- if (mimeType != null ) {
139+ private void serveCompressed (
140+ HttpServletRequest req ,
141+ HttpServletResponse resp ,
142+ String requestUri ,
143+ String contentEncoding ,
144+ String extension )
145+ throws ServletException , IOException {
146+ resp .setHeader ("Content-Encoding" , contentEncoding );
147+ String mimeType = req .getServletContext ().getMimeType (requestUri );
148+
149+ HttpServletRequestWrapper compressedReq =
150+ new HttpServletRequestWrapper (req ) {
151+ @ Override
152+ public String getPathInfo () {
153+ String pathInfo = super .getPathInfo ();
154+ return pathInfo != null ? pathInfo + "." + extension : null ;
155+ }
156+
157+ @ Override
158+ public String getRequestURI () {
159+ return super .getRequestURI () + "." + extension ;
160+ }
161+ };
162+
163+ HttpServletResponseWrapper compressedResp =
164+ new HttpServletResponseWrapper (resp ) {
165+ @ Override
166+ public void setContentType (String type ) {
167+ if (mimeType != null ) {
141168 super .setContentType (mimeType );
142- } else {
169+ } else {
143170 super .setContentType (type );
144- }
145- }
146- };
171+ }
172+ }
173+ };
147174
148- super .doGet (compressedReq , compressedResp );
175+ super .doGet (compressedReq , compressedResp );
149176 }
150177
151178 /**
0 commit comments