Skip to content
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

MM-893: Solved Authentication Bypass to System Administration #169

Closed
wants to merge 2 commits into from

Conversation

jnsereko
Copy link
Contributor

@jnsereko jnsereko commented Jul 30, 2021

A user without the privilege could access the administration page and all other functionalities.
I have just created a Filter to redirect every user, without the above privilege, to the home page.

cc @isears @sherrif10

69ca3ccd-5a45-4d3b-bc40-cbcc4f576dc5.mp4

/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig filterConfig) throws ServletException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this method do ?

Copy link
Contributor Author

@jnsereko jnsereko Jul 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @sherrif10, I think It generally does nothing other than obeying java laws.
As far as I know, javax.servelt.Filter class is an interface so when implementing it, I have to implement all its methods otherwise the java-compiler will complain

Copy link
Member

@isears isears left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mostly looks good to me, just had a few small adjustments.

@dkayiwa would you mind taking a look at this as well? This is a solution to the problem mentioned here (https://talk.openmrs.org/t/proposal-for-securing-the-legacy-ui-system-administration-pages/33988) although we took a slightly different approach to avoid having to edit every single admin page.

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) req;
String requestURI = httpReq.getRequestURI();
if (requestURI.contains("/admin/")) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that the filter is already limited to /admin/* in WebComponentRegistrar.java, is this check really necessary?

@isears isears self-assigned this Jul 31, 2021
String requestURI = httpReq.getRequestURI();
if (requestURI.contains("/admin/")) {
User user = Context.getAuthenticatedUser();
if (user != null && !user.hasPrivilege("App: coreapps.systemAdministration")) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about those using the legacyui module without the reference application modules?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah! I knew we were missing something! Could we instead implement this filter in the refapp module?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank @isears and @dkayiwa for the rewie. I have really been thinking a lot about this.
what if we try something like

if (!(user.isSuperUser() || user.hasRole("Organizational: System Administrator") || user.hasRole("Organizational: Hospital Administrator"))) 

Will it also depend on the reference application

MM-893: Solved Authentication Bypass to System Administration
@jnsereko
Copy link
Contributor Author

jnsereko commented Aug 2, 2021

02.08.2021_17.30.39_REC.mp4

Everything seems to be working fine
cc @isears @dkayiwa @sherrif10

Copy link
Member

@isears isears left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jnsereko let me know if any of the above is unclear. If necessary we can set up a call to talk things through.

User user = Context.getAuthenticatedUser();

if (!(user.isSuperUser() || user.hasRole("Organizational: System Administrator") || user.hasRole("Organizational: Hospital Administrator"))) {
httpReq.getSession().setAttribute(WebConstants.DENIED_PAGE, httpReq.getRequestURI());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have to revert to checking for only App: coreapps.systemAdministration, like you had before.

To resolve the issue that @dkayiwa mentioned, let's just check for the existence of the App: coreapps.systemAdministration privilege before we do anything else. So there will be three cases:

  1. The App: coreapps.systemAdministration privilege exists, and the user has it. Therefore, the user should be allowed to view the /admin/* pages
  2. The App: coreapps.systemAdministration privilege exists, and the user does not have it. Therefore, the user should be prevented from viewing the /admin/* pages
  3. The App: coreapps.systemAdministration does not exist, because the implementation is legacy-ui only. Therefore, we should let the user view the /admin/* pages to maintain backward compatibility.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks very clear to me @isears and am sure it will work for us. I need to come up with a way of checking if the system has the App: coreapps.systemAdministration privilege

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) req;
Collection<Module> modules = ModuleFactory.getLoadedModules();
if (modules.contains(ModuleFactory.getModuleById(COREAPPS_MODULE_ID))) {
Copy link
Contributor Author

@jnsereko jnsereko Aug 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hello @isears @sherrif10 @dkayiwa

@dkayiwa, won't this line cater for those using the legacyui module without reference application modules.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course it would. But it is not a good practise for the legacyui module to be aware of any other modules.

@jnsereko
Copy link
Contributor Author

jnsereko commented Aug 3, 2021

It is still working fine

03.08.2021_15.42.16_REC.mp4


private static final String COREAPPS_MODULE_ID = "coreapps";

private static final String COREAPPS_SYSTEM_ADMINISTRATOR_PRIVELEGE = "App: coreapps.systemAdministration";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish the privilege did not have coreapps in its name because the legacyui module should not be aware of any module.

@jnsereko
Copy link
Contributor Author

jnsereko commented Aug 4, 2021

i have created migrated this to coreapps basing on the discussion I had https://talk.openmrs.org/t/mm-893-solved-authentication-bypass-to-system-administration/34290/11

@jnsereko jnsereko closed this Aug 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants