-
Notifications
You must be signed in to change notification settings - Fork 460
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#23900 fixing ajax vulnerabilities reported by sonar #23911
Changes from all commits
d27b002
8439ab7
3733f4c
d07c834
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,14 +3,19 @@ | |
import com.dotcms.api.web.HttpServletRequestThreadLocal; | ||
import com.dotmarketing.business.APILocator; | ||
import com.dotmarketing.cms.factories.PublicCompanyFactory; | ||
import com.dotmarketing.exception.DotDataException; | ||
import com.dotmarketing.exception.DotRuntimeException; | ||
import com.dotmarketing.exception.DotSecurityException; | ||
import com.dotmarketing.servlets.ajax.AjaxAction; | ||
import com.dotmarketing.util.Logger; | ||
import com.dotmarketing.util.UtilMethods; | ||
import com.dotmarketing.util.WebKeys; | ||
import com.google.common.annotations.VisibleForTesting; | ||
import com.liferay.portal.language.LanguageUtil; | ||
import com.liferay.portal.model.User; | ||
import java.io.IOException; | ||
import java.lang.reflect.Method; | ||
import java.util.Set; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
@@ -31,9 +36,9 @@ public boolean validateUser() { | |
throw new DotRuntimeException (e.getMessage()); | ||
} | ||
} | ||
|
||
|
||
protected abstract Set<String> getAllowedCommands(); | ||
|
||
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { | ||
|
||
|
@@ -46,20 +51,23 @@ public void service(HttpServletRequest request, HttpServletResponse response) th | |
Class partypes[] = new Class[] { HttpServletRequest.class, HttpServletResponse.class }; | ||
Object arglist[] = new Object[] { request, response }; | ||
try { | ||
if(getUser()==null || !APILocator.getLayoutAPI().doesUserHaveAccessToPortlet("dynamic-plugins", getUser())){ | ||
if(getUser()==null || !doesUserHaveAccessToPortlet(getUser())){ | ||
response.sendError(401); | ||
return; | ||
} | ||
|
||
|
||
|
||
meth = this.getClass().getMethod(cmd, partypes); | ||
if(getAllowedCommands().contains(cmd)) { | ||
meth = getMethod(cmd, partypes); | ||
} else if (UtilMethods.isSet(cmd)){ | ||
Logger.error(this.getClass(), String.format("Attempt to run Invalid command %s :",cmd)); | ||
return; | ||
} | ||
|
||
} catch (Exception e) { | ||
|
||
try { | ||
cmd = "action"; | ||
meth = this.getClass().getMethod(cmd, partypes); | ||
meth = getMethod(cmd, partypes); | ||
} catch (Exception ex) { | ||
Logger.error(this.getClass(), "Trying to run method:" + cmd); | ||
Logger.error(this.getClass(), e.getMessage(), e.getCause()); | ||
|
@@ -77,6 +85,30 @@ public void service(HttpServletRequest request, HttpServletResponse response) th | |
|
||
} | ||
|
||
/** | ||
* Extracted so it can be mocked | ||
* @param user | ||
* @return | ||
* @throws DotDataException | ||
*/ | ||
@VisibleForTesting | ||
boolean doesUserHaveAccessToPortlet(final User user) throws DotDataException { | ||
return APILocator.getLayoutAPI().doesUserHaveAccessToPortlet("dynamic-plugins", user); | ||
} | ||
|
||
/** | ||
* extracted as a separated method, so it can be verified when called | ||
* @param method | ||
* @param parameterTypes | ||
* @return | ||
* @throws NoSuchMethodException | ||
*/ | ||
@VisibleForTesting | ||
Method getMethod(String method, Class<?>... parameterTypes ) throws NoSuchMethodException { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have a ReflectionUtils, may be better there There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. First this is a deprecated class Im not spending too much effort on it.. and the only reason I extracted that logic into a separate method was to verify that the method gets called using mokito @jdotcms |
||
return this.getClass().getMethod(method, parameterTypes); | ||
} | ||
|
||
|
||
public void writeError(HttpServletResponse response, String error) throws IOException { | ||
String ret = null; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ | |
import java.io.IOException; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
|
||
@Deprecated | ||
|
@@ -137,4 +138,15 @@ public void save(final HttpServletRequest request, | |
writeError(response, e.getMessage()); | ||
} | ||
} // save. | ||
|
||
/** | ||
* Security check demanded by Sonar | ||
* We register all the allowed methods down here | ||
* | ||
* @return allowed method names | ||
*/ | ||
@Override | ||
protected Set<String> getAllowedCommands() { | ||
return Set.of( "action", "reorder", "delete", "add", "save", "deleteActionForStep" ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same constant |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
package com.dotmarketing.portlets.workflows.ajax; | ||
|
||
import java.io.IOException; | ||
import java.lang.reflect.Method; | ||
import java.util.Set; | ||
|
||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
|
@@ -9,11 +11,15 @@ | |
import com.dotmarketing.cms.factories.PublicCompanyFactory; | ||
import com.dotmarketing.servlets.ajax.AjaxAction; | ||
import com.dotmarketing.util.Logger; | ||
import com.dotmarketing.util.UtilMethods; | ||
import com.google.common.annotations.VisibleForTesting; | ||
import com.liferay.portal.language.LanguageUtil; | ||
|
||
@Deprecated | ||
abstract class WfBaseAction extends AjaxAction { | ||
|
||
protected abstract Set<String> getAllowedCommands(); | ||
|
||
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { | ||
String cmd = request.getParameter("cmd"); | ||
java.lang.reflect.Method meth = null; | ||
|
@@ -25,13 +31,18 @@ public void service(HttpServletRequest request, HttpServletResponse response) th | |
return; | ||
} | ||
|
||
meth = this.getClass().getMethod(cmd, partypes); | ||
if(getAllowedCommands().contains(cmd)) { | ||
meth = getMethod(cmd, partypes); | ||
} else if (UtilMethods.isSet(cmd)){ | ||
Logger.error(this.getClass(), String.format("Attempt to run Invalid command %s :",cmd)); | ||
return; | ||
} | ||
|
||
} catch (Exception e) { | ||
|
||
try { | ||
cmd = "action"; | ||
meth = this.getClass().getMethod(cmd, partypes); | ||
meth = getMethod(cmd, partypes); | ||
} catch (Exception ex) { | ||
Logger.error(this.getClass(), "Trying to run method:" + cmd); | ||
Logger.error(this.getClass(), e.getMessage(), e.getCause()); | ||
|
@@ -49,6 +60,18 @@ public void service(HttpServletRequest request, HttpServletResponse response) th | |
|
||
} | ||
|
||
/** | ||
* extracted as a separated method, so it can be verified when called | ||
* @param method | ||
* @param parameterTypes | ||
* @return | ||
* @throws NoSuchMethodException | ||
*/ | ||
@VisibleForTesting | ||
Method getMethod(String method, Class<?>... parameterTypes ) throws NoSuchMethodException { | ||
return this.getClass().getMethod(method, parameterTypes); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it seems the method is repeat |
||
} | ||
|
||
public void writeError(HttpServletResponse response, String error) throws IOException { | ||
String ret = null; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't be a constant static
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had it as a class field. non-static but Mockito wouldnt see the results when calling the real method so ended up inlining the Set instantiation. It isn't a big penalti performance wise @jdotcms