blob: ff5fda209d3e3a8c7c5be061ae6a90f96274d99c [file] [log] [blame]
/*
* 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.axis2.webapp;
import java.util.Map;
import java.util.Random;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletResponseWrapper;
import jakarta.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
final class CSRFPreventionResponseWrapper extends HttpServletResponseWrapper {
private static final Log log = LogFactory.getLog(CSRFPreventionResponseWrapper.class);
private final HttpServletRequest request;
private final Map<String,ActionHandler> actionHandlers;
private final Random random;
private String token;
CSRFPreventionResponseWrapper(HttpServletRequest request, HttpServletResponse response, Map<String,ActionHandler> actionHandlers, Random random) {
super(response);
this.request = request;
this.actionHandlers = actionHandlers;
this.random = random;
}
protected String getToken() {
if (token == null) {
HttpSession session = request.getSession(false);
if (session == null) {
throw new IllegalStateException();
}
CSRFTokenCache tokenCache;
synchronized (session) {
tokenCache = (CSRFTokenCache)session.getAttribute(CSRFTokenCache.class.getName());
if (tokenCache == null) {
tokenCache = new CSRFTokenCache();
session.setAttribute(CSRFTokenCache.class.getName(), tokenCache);
}
}
byte[] bytes = new byte[16];
StringBuilder buffer = new StringBuilder();
random.nextBytes(bytes);
for (int j = 0; j < bytes.length; j++) {
byte b1 = (byte)((bytes[j] & 0xf0) >> 4);
byte b2 = (byte)(bytes[j] & 0x0f);
if (b1 < 10) {
buffer.append((char)('0' + b1));
} else {
buffer.append((char)('A' + (b1 - 10)));
}
if (b2 < 10) {
buffer.append((char)('0' + b2));
} else {
buffer.append((char)('A' + (b2 - 10)));
}
}
token = buffer.toString();
tokenCache.add(token);
}
return token;
}
@Override
public String encodeURL(String url) {
int idx = url.indexOf('?');
String path = idx == -1 ? url : url.substring(0, idx);
String action = path.substring(path.lastIndexOf('/')+1);
ActionHandler actionHandler = actionHandlers.get(action);
if (actionHandler == null) {
log.warn("Unknown action: " + action);
} else if (actionHandler.isCSRFTokenRequired()) {
url = url + (idx == -1 ? '?' : '&') + "token=" + getToken();
}
return super.encodeURL(url);
}
}