Change Ignition Project Location

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.

1 Like

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