git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@915384 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Bosanac Dejan 2010-02-23 15:24:30 +00:00
parent f24edca190
commit 9dc43f3ffe
15 changed files with 58 additions and 16 deletions

View File

@ -39,4 +39,10 @@ public class CreateDestination extends DestinationFacade implements Controller {
return redirectToBrowseView();
}
public String[] getSupportedHttpMethods() {
return new String[]{"POST"};
}
}

View File

@ -50,5 +50,9 @@ public class CreateSubscriber extends DurableSubscriberFacade implements Control
getBrokerAdmin().createDurableSubscriber(getClientId(), getSubscriberName(), getValidDestination(), selector);
return new ModelAndView("redirect:subscribers.jsp");
}
public String[] getSupportedHttpMethods() {
return new String[]{"POST"};
}
}

View File

@ -230,4 +230,8 @@ public class SendMessage extends DestinationFacade implements Controller {
// allow JMSX extensions or non JMS properties
return name.startsWith("JMSX") || !name.startsWith("JMS");
}
public String[] getSupportedHttpMethods() {
return new String[]{"POST"};
}
}

View File

@ -16,8 +16,12 @@
*/
package org.apache.activemq.web.handler;
import java.util.Arrays;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.activemq.web.DestinationFacade;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.bind.ServletRequestDataBinder;
@ -41,8 +45,21 @@ public class BindingBeanNameUrlHandlerMapping extends BeanNameUrlHandlerMapping
HandlerExecutionChain handlerExecutionChain = (HandlerExecutionChain) object;
object = handlerExecutionChain.getHandler();
}
if (object != null) {
// prevent CSRF attacks
if (object instanceof DestinationFacade) {
// check supported methods
if (!Arrays.asList(((DestinationFacade)object).getSupportedHttpMethods()).contains(request.getMethod())) {
throw new UnsupportedOperationException("Unsupported method " + request.getMethod() + " for path " + request.getRequestURI());
}
// check the 'secret'
if (!request.getSession().getAttribute("secret").equals(request.getParameter("secret"))) {
throw new UnsupportedOperationException("Possible CSRF attack");
}
}
ServletRequestDataBinder binder = new ServletRequestDataBinder(object, "request");
try {
binder.bind(request);
@ -56,6 +73,7 @@ public class BindingBeanNameUrlHandlerMapping extends BeanNameUrlHandlerMapping
throw e;
}
}
return object;
}
}

View File

@ -50,7 +50,7 @@
<filter-mapping>
<filter-name>spring</filter-name>
<url-pattern>/*</url-pattern>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
@ -101,7 +101,7 @@
<filter-mapping>
<filter-name>session</filter-name>
<url-pattern>/*</url-pattern>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>spring-rq</filter-name>

View File

@ -49,7 +49,7 @@
<td><jms:formatTimestamp timestamp="${row.JMSTimestamp}"/></td>
<td>${row.JMSType}</td>
<td>
<a href="deleteMessage.action?JMSDestination=<c:out value="${row.JMSDestination}"/>&messageId=${row.JMSMessageID}">Delete</a>
<a href="deleteMessage.action?JMSDestination=<c:out value="${row.JMSDestination}"/>&messageId=${row.JMSMessageID}&secret=<c:out value='${sessionScope["secret"]}'/>">Delete</a>
</td>
</tr>
</jms:forEachMessage>

View File

@ -51,7 +51,7 @@
<td>${row.JMSTimestamp}</td>
<td>${row.JMSType}</td>
<td>
<a href="deleteDestination.action?destination=${row.JMSMessageID}">Delete</a>
<a href="deleteDestination.action?destination=${row.JMSMessageID}&secret=<c:out value='${sessionScope["secret"]}'/>">Delete</a>
</td>
</tr>
</jms:forEachMessage>

View File

@ -130,10 +130,10 @@ No message could be found for ID ${requestContext.messageQuery.id}
</thead>
<tbody>
<tr>
<td colspan="2"><a href="deleteMessage.action?JMSDestination=<c:out value="${row.JMSDestination}" />&messageId=${row.JMSMessageID}">Delete</a></td>
<td colspan="2"><a href="deleteMessage.action?JMSDestination=<c:out value="${row.JMSDestination}" />&messageId=${row.JMSMessageID}&secret=<c:out value='${sessionScope["secret"]}'/>">Delete</a></td>
</tr>
<tr class="odd">
<td><a href="javascript:confirmAction('queue', 'copyMessage.action?destination=%target%&JMSDestination=<c:out value="${row.JMSDestination}" />&messageId=${row.JMSMessageID}&JMSDestinationType=queue')">Copy</a></td>
<td><a href="javascript:confirmAction('queue', 'copyMessage.action?destination=%target%&JMSDestination=<c:out value="${row.JMSDestination}" />&messageId=${row.JMSMessageID}&JMSDestinationType=queue&secret=<c:out value='${sessionScope["secret"]}'/>')">Copy</a></td>
<td rowspan="2">
<select id="queue">
<option value=""> -- Please select --</option>
@ -147,7 +147,7 @@ No message could be found for ID ${requestContext.messageQuery.id}
</tr>
<tr class="odd">
<td><a href="javascript:confirmAction('queue', 'moveMessage.action?destination=%target%&JMSDestination=<c:out value="${row.JMSDestination}" />&messageId=${row.JMSMessageID}&JMSDestinationType=queue')">Move</a></td>
<td><a href="javascript:confirmAction('queue', 'moveMessage.action?destination=%target%&JMSDestination=<c:out value="${row.JMSDestination}" />&messageId=${row.JMSMessageID}&JMSDestinationType=queue&secret=<c:out value='${sessionScope["secret"]}'/>')">Move</a></td>
</tr>
</tbody>
</table>

View File

@ -21,8 +21,9 @@
<body>
<div>
<form action="createDestination.action" method="get">
<form action="createDestination.action" method="post">
<input type="hidden" name="JMSDestinationType" value="queue"/>
<input type="hidden" name="secret" value="<c:out value='${sessionScope["secret"]}'/>"/>
<label name="destination">Queue Name</label>
<input type="text" name="JMSDestination" value=""/>
@ -63,8 +64,8 @@
</td>
<td>
<a href="send.jsp?JMSDestination=<c:out value="${row.name}" />&JMSDestinationType=queue">Send To</a>
<a href="purgeDestination.action?JMSDestination=<c:out value="${row.name}" />&JMSDestinationType=queue">Purge</a>
<a href="deleteDestination.action?JMSDestination=<c:out value="${row.name}" />&JMSDestinationType=queue">Delete</a>
<a href="purgeDestination.action?JMSDestination=<c:out value="${row.name}" />&JMSDestinationType=queue&secret=<c:out value='${sessionScope["secret"]}'/>">Purge</a>
<a href="deleteDestination.action?JMSDestination=<c:out value="${row.name}" />&JMSDestinationType=queue&secret=<c:out value='${sessionScope["secret"]}'/>">Delete</a>
</td>
</tr>
</c:forEach>

View File

@ -45,7 +45,7 @@
<td>${row.period}</td>
<td>${row.repeat}</td>
<td>
<a href="deleteJob.action?jobId=${row.jobId}">Delete</a>
<a href="deleteJob.action?jobId=${row.jobId}&secret=<c:out value='${sessionScope["secret"]}'/>">Delete</a>
</td>
</tr>
</c:forEach>

View File

@ -23,6 +23,7 @@
<h2>Send a JMS Message</h2>
<form action="sendMessage.action" method="post">
<input type="hidden" name="secret" value="<c:out value='${sessionScope["secret"]}'/>"/>
<table id="headers" class="autostripe">
<thead>

View File

@ -20,8 +20,9 @@
</head>
<body>
<form action="createSubscriber.action" method="get">
<form action="createSubscriber.action" method="post">
<input type="hidden" name="JMSDestinationType" value="topic"/>
<input type="hidden" name="secret" value="<c:out value='${sessionScope["secret"]}'/>"/>
<table id="createSubscribers" class="sortable autostripe">
<thead>
@ -102,7 +103,7 @@
<td>${row.enqueueCounter}</td>
<td>${row.dequeueCounter}</td>
<td>
<a href="deleteSubscriber.action?clientId=${row.clientId}&subscriberName=${row.subscriptionName}">Delete</a>
<a href="deleteSubscriber.action?clientId=${row.clientId}&subscriberName=${row.subscriptionName}&secret=<c:out value='${sessionScope["secret"]}'/>">Delete</a>
</td>
</tr>
</c:forEach>

View File

@ -23,6 +23,7 @@
<div>
<form action="createDestination.action" method="get">
<input type="hidden" name="JMSDestinationType" value="topic"/>
<input type="hidden" name="secret" value="<c:out value='${sessionScope["secret"]}'/>"/>
<label name="destination">Topic Name</label>
<input type="text" name="JMSDestination" value=""/>
@ -52,7 +53,7 @@
<td>${row.dequeueCount}</td>
<td>
<a href="send.jsp?JMSDestination=<c:out value="${row.name}" />&JMSDestinationType=topic">Send To</a>
<a href="deleteDestination.action?JMSDestination=<c:out value="${row.name}" />&JMSDestinationType=topic">Delete</a>
<a href="deleteDestination.action?JMSDestination=<c:out value="${row.name}" />&JMSDestinationType=topic&secret=<c:out value='${sessionScope["secret"]}'/>">Delete</a>
</td>
</tr>
</c:forEach>

View File

@ -128,4 +128,8 @@ public class DestinationFacade {
protected String getPhysicalDestinationName() {
return createDestination().getPhysicalName();
}
public String[] getSupportedHttpMethods() {
return new String[]{"GET", "POST"};
}
}

View File

@ -18,6 +18,7 @@
package org.apache.activemq.web;
import java.io.IOException;
import java.util.UUID;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
@ -39,7 +40,8 @@ public class SessionFilter implements Filter {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
((HttpServletRequest)request).getSession(true);
// set secret to prevent CSRF attacks
((HttpServletRequest)request).getSession(true).setAttribute("secret", UUID.randomUUID().toString());;
chain.doFilter(request, response);
}