Try setting the log level for gateway.ProjectManager
and gateway.IgnitionProjectManager
(whichever exists, or both if they both exist) to TRACE before doing a save, then let's see the logs.
surprisingly no additional (useful anyway) logs on save:
(also set com.inductiveautomation.ignition.gateway.project.IgnitionProjectManager
to TRACE)
INFO | jvm 1 | 2024/02/15 10:53:35 | D [g.IgnitionProjectManager ] [16:53:35]: Acquiring scan lock... request-origin=127.0.0.1, session-user=hunterdg, session-project=ProjectName, session-id=44169EB6
INFO | jvm 1 | 2024/02/15 10:53:35 | D [g.IgnitionProjectManager ] [16:53:35]: push(2 operations) request-origin=127.0.0.1, session-user=hunterdg, session-project=ProjectName, session-id=44169EB6
INFO | jvm 1 | 2024/02/15 10:53:35 | D [g.IgnitionProjectManager ] [16:53:35]: Releasing scan lock request-origin=127.0.0.1, session-user=hunterdg, session-project=ProjectName, session-id=44169EB6
on a whim, creating new projects (from both designer and gw) gives User path escapes the base path
Gateway
INFO | jvm 1 | 2024/02/15 10:47:37 | java.lang.IllegalArgumentException: User path escapes the base path
INFO | jvm 1 | 2024/02/15 10:47:37 | at com.inductiveautomation.ignition.common.util.SecurePathUtils.resolvePath(SecurePathUtils.java:46)
INFO | jvm 1 | 2024/02/15 10:47:37 | at com.inductiveautomation.ignition.common.util.SecurePathUtils.resolvePath(SecurePathUtils.java:69)
INFO | jvm 1 | 2024/02/15 10:47:37 | at com.inductiveautomation.ignition.gateway.project.BaseProjectManager.getProjectDir(BaseProjectManager.java:1253)
INFO | jvm 1 | 2024/02/15 10:47:37 | at com.inductiveautomation.ignition.gateway.project.BaseProjectManager.createProject(BaseProjectManager.java:304)
INFO | jvm 1 | 2024/02/15 10:47:37 | at com.inductiveautomation.ignition.gateway.project.IgnitionProjectManager.createProject(IgnitionProjectManager.java:203)
INFO | jvm 1 | 2024/02/15 10:47:37 | at com.inductiveautomation.ignition.gateway.project.ProjectManagerBase.createProjectSafe(ProjectManagerBase.java:114)
INFO | jvm 1 | 2024/02/15 10:47:37 | at com.inductiveautomation.ignition.gateway.project.IgnitionProjectManager.createProjectSafe(IgnitionProjectManager.java:212)
INFO | jvm 1 | 2024/02/15 10:47:37 | at com.inductiveautomation.ignition.gateway.project.ProjectManagerBase.createProjectSafe(ProjectManagerBase.java:82)
INFO | jvm 1 | 2024/02/15 10:47:37 | at com.inductiveautomation.ignition.gateway.web.pages.config.routes.ProjectRoutes.addProject(ProjectRoutes.java:339)
INFO | jvm 1 | 2024/02/15 10:47:37 | at com.inductiveautomation.ignition.gateway.dataroutes.Route.service(Route.java:254)
INFO | jvm 1 | 2024/02/15 10:47:37 | at com.inductiveautomation.ignition.gateway.dataroutes.RouteGroupImpl.service(RouteGroupImpl.java:61)
INFO | jvm 1 | 2024/02/15 10:47:37 | at com.inductiveautomation.ignition.gateway.dataroutes.RouteGroupCollectionServlet.serviceInternal(RouteGroupCollectionServlet.java:59)
INFO | jvm 1 | 2024/02/15 10:47:37 | at com.inductiveautomation.ignition.gateway.dataroutes.AbstractRouteGroupServlet.service(AbstractRouteGroupServlet.java:38)
INFO | jvm 1 | 2024/02/15 10:47:37 | at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1450)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1631)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
INFO | jvm 1 | 2024/02/15 10:47:37 | at com.inductiveautomation.catapult.handlers.RemoteHostNameLookupHandler.handle(RemoteHostNameLookupHandler.java:121)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:322)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:59)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.Server.handle(Server.java:516)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
INFO | jvm 1 | 2024/02/15 10:47:37 | at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
INFO | jvm 1 | 2024/02/15 10:47:37 | at java.base/java.lang.Thread.run(Unknown Source)
Designer
java.util.concurrent.ExecutionException: com.inductiveautomation.ignition.client.gateway_interface.GatewayException: java.lang.IllegalArgumentException: User path escapes the base path
at java.base/java.util.concurrent.FutureTask.report(Unknown Source)
at java.base/java.util.concurrent.FutureTask.get(Unknown Source)
at java.desktop/javax.swing.SwingWorker.get(Unknown Source)
at com.inductiveautomation.ignition.designer.ProjectDialog$4.done(ProjectDialog.java:402)
at java.desktop/javax.swing.SwingWorker$5.run(Unknown Source)
at java.desktop/javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(Unknown Source)
at java.desktop/sun.swing.AccumulativeRunnable.run(Unknown Source)
at java.desktop/javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(Unknown Source)
at java.desktop/javax.swing.Timer.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.Timer$DoPostEvent.run(Unknown Source)
at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.desktop/java.awt.WaitDispatchSupport$2.run(Unknown Source)
at java.desktop/java.awt.WaitDispatchSupport$4.run(Unknown Source)
at java.desktop/java.awt.WaitDispatchSupport$4.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.desktop/java.awt.WaitDispatchSupport.enter(Unknown Source)
at java.desktop/java.awt.Dialog.show(Unknown Source)
at java.desktop/java.awt.Component.show(Unknown Source)
at java.desktop/java.awt.Component.setVisible(Unknown Source)
at java.desktop/java.awt.Window.setVisible(Unknown Source)
at java.desktop/java.awt.Dialog.setVisible(Unknown Source)
at com.inductiveautomation.ignition.designer.IgnitionDesigner$Handler.handleOpen(IgnitionDesigner.java:2985)
at com.inductiveautomation.ignition.designer.IgnitionDesigner$Handler.handleNew(IgnitionDesigner.java:2959)
at com.inductiveautomation.ignition.designer.IgnitionDesigner$Handler$3.actionPerformed(IgnitionDesigner.java:2355)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at java.desktop/javax.swing.AbstractButton.doClick(Unknown Source)
at java.desktop/javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at java.desktop/javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.desktop/java.awt.Component.processEvent(Unknown Source)
at java.desktop/java.awt.Container.processEvent(Unknown Source)
at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Caused by: com.inductiveautomation.ignition.client.gateway_interface.GatewayException: java.lang.IllegalArgumentException: User path escapes the base path
at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.newGatewayException(GatewayInterface.java:351)
at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.sendMessage(GatewayInterface.java:325)
at com.inductiveautomation.ignition.designer.gateway.PriviledgedDesignerTask$GatewayMessageTask.execute(PriviledgedDesignerTask.java:440)
at com.inductiveautomation.ignition.designer.gateway.PriviledgedDesignerTask$TaskThread.run(PriviledgedDesignerTask.java:328)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: com.inductiveautomation.ignition.gateway.servlets.gateway.functions.GatewayFunctionException: java.lang.IllegalArgumentException: User path escapes the base path
at com.inductiveautomation.ignition.gateway.servlets.gateway.functions.Projects.create(Projects.java:648)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(null)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(null)
at java.lang.reflect.Method.invoke(null)
at com.inductiveautomation.ignition.gateway.servlets.gateway.AbstractGatewayFunction.invoke(AbstractGatewayFunction.java:228)
at com.inductiveautomation.ignition.gateway.servlets.Gateway.doPost(Gateway.java:431)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at com.inductiveautomation.ignition.gateway.bootstrap.MapServlet.service(MapServlet.java:86)
at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1450)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799)
at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1631)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at com.inductiveautomation.catapult.handlers.RemoteHostNameLookupHandler.handle(RemoteHostNameLookupHandler.java:121)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:322)
at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:59)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:516)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
at java.lang.Thread.run(null)
Ignition v8.1.21 (b2022092908)
Java: Azul Systems, Inc. 11.0.15
Okay, SecurePathUtils
trying to prevent directory traversal looks like the underlying problem... it's just not being caught/logged on the push.
You'll have to use absolute paths for now. Not sure how intentional this is, in this case, for this directory.
ok, thanks!
I googled and found stuff about path traversal attacks: Filtering upwards path traversal in Java
Of course this "upward path traversal" works fine via absolute paths - though I guess maybe that's exactly the point/intended defense/solution
I might try again via enabling git (windows) to handle symlinks.
Edit - that worked