ome / omero-web

Django-based OMERO.web client
https://www.openmicroscopy.org/omero
17 stars 31 forks source link

updateMyAccount SecurityViolation #445

Closed will-moore closed 10 months ago

will-moore commented 1 year ago

See https://www.openmicroscopy.org/qa2/qa/feedback/32570/

Traceback (most recent call last):

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omeroweb/decorators.py", line 538, in wrapped
retval = f(request, *args, **kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omeroweb/decorators.py", line 597, in wrapper
context = f(request, *args, **kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omeroweb/webadmin/views.py", line 1075, in my_account
institution,

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omeroweb/webclient/webclient_gateway.py", line 1542, in updateMyAccount
admin_serv.updateSelf(up_exp)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omero/gateway/__init__.py", line 4858, in __call__
return self.handle_exception(e, *args, **kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omeroweb/webclient/webclient_gateway.py", line 2109, in handle_exception
super(OmeroWebSafeCallWrapper, self).handle_exception(e, *args, **kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omero/gateway/__init__.py", line 4855, in __call__
return self.f(*args, **kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omero_api_IAdmin_ice.py", line 1359, in updateSelf
return _M_omero.api.IAdmin._op_updateSelf.invoke(self, ((experimenter, ), _ctx))

omero.SecurityViolation: exception ::omero::SecurityViolation
{
serverStackTrace = ome.conditions.SecurityViolation: Current user is not admin for the given user(s)
at ome.logic.AdminImpl.throwNonAdmin(AdminImpl.java:1585)
will-moore commented 1 year ago

Seen again https://www.openmicroscopy.org/qa2/qa/feedback/32597/

Traceback (most recent call last):

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omeroweb/decorators.py", line 538, in wrapped
retval = f(request, *args, **kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omeroweb/decorators.py", line 597, in wrapper
context = f(request, *args, **kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omeroweb/webadmin/views.py", line 1075, in my_account
institution,

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omeroweb/webclient/webclient_gateway.py", line 1542, in updateMyAccount
admin_serv.updateSelf(up_exp)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omero/gateway/__init__.py", line 4858, in __call__
return self.handle_exception(e, *args, **kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omeroweb/webclient/webclient_gateway.py", line 2109, in handle_exception
super(OmeroWebSafeCallWrapper, self).handle_exception(e, *args, **kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omero/gateway/__init__.py", line 4855, in __call__
return self.f(*args, **kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omero_api_IAdmin_ice.py", line 1359, in updateSelf
return _M_omero.api.IAdmin._op_updateSelf.invoke(self, ((experimenter, ), _ctx))

omero.SecurityViolation: exception ::omero::SecurityViolation
{
serverStackTrace = ome.conditions.SecurityViolation: Current user is not admin for the given user(s)
at ome.logic.AdminImpl.throwNonAdmin(AdminImpl.java:1585)
at ome.logic.AdminImpl.adminOfUser(AdminImpl.java:1597)
at ome.logic.AdminImpl.updateSelf(AdminImpl.java:450)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at ome.security.basic.EventHandler.invoke(EventHandler.java:154)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.orm.hibernate3.HibernateInterceptor.invoke(HibernateInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at ome.tools.hibernate.ProxyCleanupFilter$Interceptor.invoke(ProxyCleanupFilter.java:249)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at ome.services.util.ServiceHandler.invoke(ServiceHandler.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy97.updateSelf(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at ome.security.basic.BasicSecurityWiring.invoke(BasicSecurityWiring.java:93)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at ome.services.blitz.fire.AopContextInitializer.invoke(AopContextInitializer.java:43)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy97.updateSelf(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at ome.services.blitz.util.IceMethodInvoker.invoke(IceMethodInvoker.java:172)
at ome.services.throttling.Callback.run(Callback.java:56)
at ome.services.throttling.InThreadThrottlingStrategy.callInvokerOnRawArgs(InThreadThrottlingStrategy.java:56)
at ome.services.blitz.impl.AbstractAmdServant.callInvokerOnRawArgs(AbstractAmdServant.java:140)
at ome.services.blitz.impl.AdminI.updateSelf_async(AdminI.java:370)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at omero.cmd.CallContext.invoke(CallContext.java:85)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy98.updateSelf_async(Unknown Source)
at omero.api._IAdminTie.updateSelf_async(_IAdminTie.java:374)
at omero.api._IAdminDisp.___updateSelf(_IAdminDisp.java:1253)
at omero.api._IAdminDisp.__dispatch(_IAdminDisp.java:2412)
at IceInternal.Incoming.invoke(Incoming.java:221)
at Ice.ConnectionI.invokeAll(ConnectionI.java:2536)
at Ice.ConnectionI.dispatch(ConnectionI.java:1145)
at Ice.ConnectionI.message(ConnectionI.java:1056)
at IceInternal.ThreadPool.run(ThreadPool.java:395)
at IceInternal.ThreadPool.access$300(ThreadPool.java:12)
at IceInternal.ThreadPool$EventHandlerThread.run(ThreadPool.java:832)
at java.lang.Thread.run(Thread.java:750)

serverExceptionClass = ome.conditions.SecurityViolation
message = Current user is not admin for the given user(s)
}
will-moore commented 1 year ago

Seen at https://www.openmicroscopy.org/qa2/qa/feedback/32651/

Traceback (most recent call last):

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omeroweb/decorators.py", line 538, in wrapped
retval = f(request, *args, **kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omeroweb/decorators.py", line 597, in wrapper
context = f(request, *args, **kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omeroweb/webadmin/views.py", line 1075, in my_account
institution,

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omeroweb/webclient/webclient_gateway.py", line 1542, in updateMyAccount
admin_serv.updateSelf(up_exp)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omero/gateway/__init__.py", line 4858, in __call__
return self.handle_exception(e, *args, **kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omeroweb/webclient/webclient_gateway.py", line 2109, in handle_exception
super(OmeroWebSafeCallWrapper, self).handle_exception(e, *args, **kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omero/gateway/__init__.py", line 4855, in __call__
return self.f(*args, **kwargs)

File "/opt/omero/OMERO.venv/lib/python3.6/site-packages/omero_api_IAdmin_ice.py", line 1359, in updateSelf
return _M_omero.api.IAdmin._op_updateSelf.invoke(self, ((experimenter, ), _ctx))

omero.SecurityViolation: exception ::omero::SecurityViolation
{
serverStackTrace = ome.conditions.SecurityViolation: Current user is not admin for the given user(s)
will-moore commented 1 year ago

Seen at https://www.openmicroscopy.org/qa2/qa/feedback/32899/

sbesson commented 1 year ago

I found a minimal scenario to reproduce this issue. The underlying problem is that the server API IAdmin.updateSelf makes additional checks on the provenance of the session.

In some examples, a session might have been created in a sudo manner e.g. using an admin account or a group owner. This is the strategy of the prototype omero-oauth app which uses an admin user to create an OEMRO session after authenticating with the identify provider. A minimal workflow to reproduce the issue using a simple OMERO.web deployment is to create such a session via the CLI:

omero login <user>@localhost --sudo root
omero sessions key

and use the sessions key both as the username and password to log into OMERO.web. From the user settings menu, clicking on Save suffices to reproduce the stack trace above.

I think the clearest resolution would be to fully disable (hide or grey out) the Save button in this type of scenario. Additionally, I would vote for disabling the Change password button similarly to what happens with LDAP. If a user is created via a sudo, it is fair to assume the old password is unknown and IAdmin.changePasswordWithOldPassword cannot be used.