Portal Setup - App issue
[portal.git] / ecomp-portal-BE-os / src / main / java / org / onap / portalapp / filter / SecurityXssFilter.java
1
2 /*-
3  * ============LICENSE_START==========================================
4  * ONAP Portal
5  * ===================================================================
6  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
7  * ===================================================================
8  *
9  * Unless otherwise specified, all software contained herein is licensed
10  * under the Apache License, Version 2.0 (the "License");
11  * you may not use this software except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *             http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  * Unless otherwise specified, all documentation contained herein is licensed
23  * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
24  * you may not use this documentation except in compliance with the License.
25  * You may obtain a copy of the License at
26  *
27  *             https://creativecommons.org/licenses/by/4.0/
28  *
29  * Unless required by applicable law or agreed to in writing, documentation
30  * distributed under the License is distributed on an "AS IS" BASIS,
31  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32  * See the License for the specific language governing permissions and
33  * limitations under the License.
34  *
35  * ============LICENSE_END============================================
36  *
37  * 
38  */
39 package org.onap.portalapp.filter;
40
41 import java.io.BufferedReader;
42 import java.io.ByteArrayInputStream;
43 import java.io.ByteArrayOutputStream;
44 import java.io.IOException;
45 import java.io.InputStreamReader;
46 import java.nio.charset.StandardCharsets;
47 import java.util.Enumeration;
48
49 import javax.servlet.FilterChain;
50 import javax.servlet.ReadListener;
51 import javax.servlet.ServletException;
52 import javax.servlet.ServletInputStream;
53 import javax.servlet.http.HttpServletRequest;
54 import javax.servlet.http.HttpServletRequestWrapper;
55 import javax.servlet.http.HttpServletResponse;
56
57 import org.apache.commons.io.IOUtils;
58 import org.apache.commons.lang.StringUtils;
59 import org.apache.http.HttpStatus;
60 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
61 import org.springframework.web.filter.OncePerRequestFilter;
62
63 public class SecurityXssFilter extends OncePerRequestFilter {
64
65         private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SecurityXssFilter.class);
66
67         private static final String APPLICATION_JSON = "application/json";
68
69         private static final String ERROR_BAD_REQUEST = "{\"error\":\"BAD_REQUEST\"}";
70
71         private SecurityXssValidator validator = SecurityXssValidator.getInstance();
72
73         public class RequestWrapper extends HttpServletRequestWrapper {
74
75                 private ByteArrayOutputStream cachedBytes;
76
77                 public RequestWrapper(HttpServletRequest request) {
78                         super(request);
79                 }
80
81                 @Override
82                 public ServletInputStream getInputStream() throws IOException {
83                         if (cachedBytes == null)
84                                 cacheInputStream();
85
86                         return new CachedServletInputStream();
87                 }
88
89                 @Override
90                 public BufferedReader getReader() throws IOException {
91                         return new BufferedReader(new InputStreamReader(getInputStream()));
92                 }
93
94                 private void cacheInputStream() throws IOException {
95                         cachedBytes = new ByteArrayOutputStream();
96                         IOUtils.copy(super.getInputStream(), cachedBytes);
97                 }
98
99                 public class CachedServletInputStream extends ServletInputStream {
100                         private ByteArrayInputStream input;
101
102                         public CachedServletInputStream() {
103                                 input = new ByteArrayInputStream(cachedBytes.toByteArray());
104                         }
105
106                         @Override
107                         public int read() throws IOException {
108                                 return input.read();
109                         }
110
111                         @Override
112                         public boolean isFinished() {
113                                 return false;
114                         }
115
116                         @Override
117                         public boolean isReady() {
118                                 return false;
119                         }
120
121                         @Override
122                         public void setReadListener(ReadListener readListener) {
123
124                         }
125
126                 }
127         }
128
129         @Override
130         protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
131                         throws ServletException, IOException {
132                 StringBuilder requestURL = new StringBuilder(request.getRequestURL().toString());
133             String queryString = request.getQueryString();
134             String requestUrl = "";
135             if (queryString == null) {
136                 requestUrl = requestURL.toString();
137             } else {
138                 requestUrl = requestURL.append('?').append(queryString).toString();
139             }
140             validateRequest(requestUrl, response);
141                 StringBuilder headerValues = new StringBuilder();
142                 Enumeration<String> headerNames = request.getHeaderNames();
143                 while (headerNames.hasMoreElements()) {
144                         String key = (String) headerNames.nextElement();
145                         String value = request.getHeader(key);
146                         headerValues.append(key + ":" + value + ";");
147                 }
148                 validateRequest(headerValues.toString(), response);
149                 if (validateRequestType(request)) {
150                         request = new RequestWrapper(request);
151                         String requestData = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8.toString());
152                         validateRequest(requestData, response);
153                         filterChain.doFilter(request, response);
154
155                 } else {
156                         filterChain.doFilter(request, response);
157                 }
158         }
159
160         private boolean validateRequestType(HttpServletRequest request) {
161                 return (request.getMethod().equalsIgnoreCase("POST") || request.getMethod().equalsIgnoreCase("PUT")
162                                 || request.getMethod().equalsIgnoreCase("DELETE"));
163         }
164         
165         private void validateRequest(String text, HttpServletResponse response) throws IOException {
166                 try {
167                         if (StringUtils.isNotBlank(text) && validator.denyXSS(text)) {
168                                 response.setContentType(APPLICATION_JSON);
169                                 response.setStatus(HttpStatus.SC_BAD_REQUEST);
170                                 response.getWriter().write(ERROR_BAD_REQUEST);
171                                 throw new SecurityException(ERROR_BAD_REQUEST);
172                         }
173                 } catch (Exception e) {
174                         logger.error(EELFLoggerDelegate.errorLogger, "doFilterInternal() failed due to BAD_REQUEST", e);
175                         response.getWriter().close();
176                         return;
177                 }
178         }
179 }