Protecting new fields to userEditor (stored at ./profile/...) for user administration
- March 31, 2016
- 2 replies
- 863 views
A app that I'm working on requires a couple of additional fields be added to a user's profile:
- ./profile/approvers (used to programmatically construct an approver group for use in workflows)
- ./profile/contactReassign, ./profile/authorReassign -- used to change news articles listing the user as the author or contact to another user after they have departed the organization (or some other event requiring such a reassignment)
I have the field added to the UI alright, and the data successfully saves, but I need to restrict the ability to edit these fields to members of the group "newsadmins." Since a user may edit their own profile node, I need to edit the request to exclude the above parameters.
[img]http://i.imgur.com/kUjXdFk.png[/img]
I will be hiding these fields from non-newsadmins, that's no problem, but this might still leave me open to attack if the user is smart enough to modify the dom before submitting the form.
Obviosuly a user could just run a curl command:
curl -u aaron.mcdonald@mailinator.com:password -X POST --data "./profile/approvers=someone" http://localhost:4502/home/users/geometrixx-outdoors/aaron.mcdonald@mailinator.com.rw.userprops.html
My initial thought was to create a filter servlet and then somehow modify the submitted parameters:
@Component(immediate=true, metatype=false) @Service(value=javax.servlet.Filter.class) @Properties({ @Property(name="service.pid", value="org.uc.news.core.filters.UserEditorFilter",propertyPrivate=false), @Property(name="service.description",value="User Editor Filter", propertyPrivate=false), @Property(name="filter.scope",value="request", propertyPrivate=false), @Property(name="service.ranking",intValue = 20, propertyPrivate=false), @Property(name="servlet.filter.patter",value=".*rw\\.userprops\\.html$", propertyPrivate=false) }) public class UserEditorFilter implements Filter { ... }The filter gets registered and called on the request, but I'm running into a wall when I come to figuring out how to actually get at the parameters and remove them.
So far, I've tried using the method of wrapping the request before I pass it on described here: http://stackoverflow.com/questions/1413129/modify-request-parameter-with-servlet-filter
//in doFilter():
if(!newsAdmin) { logger.info("using filtered request"); filterChain.doFilter(new FilteredRequest(request), response); return; } ... static class FilteredRequest extends HttpServletRequestWrapper { private final Logger logger = LoggerFactory.getLogger(getClass()); public FilteredRequest(ServletRequest request) { super((HttpServletRequest)request); } @Override public Map getParameterMap() { Map params = super.getParameterMap(); try { params.remove("./profile/approvers"); } catch (Exception e) { logger.info("no approver to remove"); } try { params.remove("./profile/contactReassign"); } catch (Exception e) { logger.info("no contact reassign to remove"); } try { params.remove("./profile/authorReassign"); } catch (Exception e) { logger.info("no contact reassign to remove"); } return params; } }My FilteredRequest is called initialized and passed down the chain, however, getParameterMap() never seems to get called--so those parameters aren't removed, and the parameters end up being saved to the node like normal.
@Component(immediate=true, metatype=false) @Service(value=javax.servlet.Filter.class) @Properties({ @Property(name="service.pid", value="org.uc.news.core.filters.UserEditorFilter",propertyPrivate=false), @Property(name="service.description",value="User Editor Filter", propertyPrivate=false), @Property(name="filter.scope",value="request", propertyPrivate=false), @Property(name="service.ranking",intValue = 20, propertyPrivate=false), @Property(name="servlet.filter.patter",value=".*rw\\.userprops\\.html$", propertyPrivate=false) }) public class UserEditorFilter implements Filter { ... }This more or less works how I want it to. I'm running into a wall when I come to figuring out how to actually get at the parameters and remove them.
So far, I've tried using the method of wrapping the request before I pass it on described here: http://stackoverflow.com/questions/1413129/modify-request-parameter-with-servlet-filter
if(!newsAdmin) { logger.info("useing filtered request"); filterChain.doFilter(new FilteredRequest(request), response); return; } ... static class FilteredRequest extends HttpServletRequestWrapper { private final Logger logger = LoggerFactory.getLogger(getClass()); public FilteredRequest(ServletRequest request) { super((HttpServletRequest)request); } @Override public Map getParameterMap() { Map params = super.getParameterMap(); try { params.remove("./profile/approvers"); } catch (Exception e) { logger.info("no approver to remove"); } try { params.remove("./profile/contactReassign"); } catch (Exception e) { logger.info("no contact reassign to remove"); } try { params.remove("./profile/authorReassign"); } catch (Exception e) { logger.info("no contact reassign to remove"); } return params; } }My FilteredRequest is called initialized and passed down the chain, however, getParameterMap() never seems to get called--so those parameters aren't removed, and the parameters end up being saved to the node like normal.
Perhaps im going about this the wrong way, or maybe I need to override another method in the wrapper. Any help is appreciated.