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