Path Traversal Security Feature
Overview
An application is vulnerable to Path Traversal (also known as Directory Traversal) attacks when unvalidated or unsanitized user input is used to construct a path that is intended to identify a file or directory located underneath a restricted parent directory. For such an application, the user can construct a path name that traverses the file system to a location outside the scope of the restricted parent directory.
There are two types of Path Traversal attacks:
-
Relative Path Traversal
-
Absolute Path Traversal
Path Traversal vulnerabilities are covered by CWE-22. Specifically, Relative Path Traversal is covered by CWE-23 and Absolute Path Traversal is covered by CWE-36.
The Path Traversal rule can be used to protect against both relative and absolute path traversal attacks. That is:
-
Protect against file operations where a user-constructed path allows the user to traverse back to the parent path.
-
Protect against file operations where a user-constructed path allows the user to specify an absolute path to a file or a directory.
Given (Condition)
The Path Traversal security feature is enabled using the ARMR filesytem
rule. With this rule the user can specify a single condition - input
.
input | This allows the user to specify the source of the untrusted data. The following three sources are supported:- http data introduced via HTTP/HTTPS requests |
-
database
data introduced via JDBC connections -
deserialization
data introduced via Java or XML deserializationThe rule will trigger if the source of the untrusted data matches that specified in the rule.If no value is specified then a default value ofhttp
is used.An exception will be thrown if an unsupported value is provided. |
This rule provides protection only when user input is received via an API that is enabled in the input
declaration of the rule.
When (Event)
traversal | This is a mandatory condition that allows the user to specify the type of path traversal protection to enable. The following protection types are supported:- relative |
absolute
Each rule may contain a single protection type.If no value is specified then by default protection will be enabled for bothrelative
andabsolute
path traversal attacks. |
Then (Action)
protect | Path traversal attacks are blocked by the agent.If configured, a log message is generated with details of the event. |
detect | Monitoring mode: the application behaves as normal. Path Traversal attacks are allowed by the agent.If configured, a log message is generated with details of the event.A log message must be specified with this action. |
As part of the action statement, the user may optionally specify the parameter stacktrace: “full”
. When this parameter is specified, the stacktrace of the location of the attempted exploit is included in the security log entry.
Example
The following filesystem
rule is used to protect an application from both relative and absolute path traversal attacks.
The input
declaration is satisfied when the untrusted data originates from an HTTP/HTTPS request. Since no value is specified inside the traversal
declaration, the rule will trigger when the resulting path either allows the user to traverse back to the parent path, or to specify an absolute path to a file or a directory.
An action of protect
is defined to ensure that the agent blocks such requests. A log message and severity are both specified which will be included in any generated log entries if an attack is detected.
app("Path Traversal mod"):
requires(version: ARMR/2.7)
filesystem("Protect against relative and absolute path traversal attacks"):
input(http)
traversal()
protect(message: "Path Traversal attack blocked", severity: 8)
endfilesystem
endapp
Logging
When the above filesystem
rule is triggered a log entry similar to the following is generated:
-
relative
<10>1 2021-03-30T17:31:15.236+01:00 userX_system java 32008 - - CEF:0|ARMR:Path Traversal mod|Path Traversal mod|2.7|Protect against relative and absolute path traversal attacks|Execute Rule|High|rt=Mar 30 2021 17:31:15.234 +0100 dvchost=userX_system procid=32008 appVersion=1 ruleType=filesystem securityFeature=filesystem path traversal act=protect msg=Path Traversal attack blocked path=/tmp/tomcat/webapps/spiracle/pathTraversal/testFilesParent/testFilesChild/../TestFile httpSessionId=3153E581A645E2A54D3C12D3928473BC taintSource=HTTP_SERVLET httpRequestUri=/spiracle/FileServlet01 internalHttpRequestUri=/spiracle/FileServlet01 httpCookies=JSESSIONID\=3153E581A645E2A54D3C12D3928473BC remoteIpAddress=0:0:0:0:0:0:0:1
-
absolute
<10>1 2021-03-30T17:32:30.903+01:00 userX_system java 32008 - - CEF:0|ARMR:Path Traversal mod|Path Traversal mod|2.7|Protect against relative and absolute path traversal attacks|Execute Rule|High|rt=Mar 30 2021 17:32:30.903 +0100 dvchost=userX_system procid=32008 appVersion=1 ruleType=filesystem securityFeature=filesystem path traversal act=protect msg=Path Traversal attack blocked path=/tmp/somefile.txt httpSessionId=3153E581A645E2A54D3C12D3928473BC taintSource=HTTP_SERVLET httpRequestUri=/spiracle/FileServlet03 internalHttpRequestUri=/spiracle/FileServlet03 httpCookies=JSESSIONID\=3153E581A645E2A54D3C12D3928473BC remoteIpAddress=0:0:0:0:0:0:0:1
Further Examples
The following mod is the same as the previous example, with the stacktrace also logged:
app("Path Traversal mod - with stacktrace"):
requires(version: ARMR/2.7)
filesystem("Protect against relative and absolute path traversal attacks"):
input(http)
traversal()
protect(message: "Path Traversal attack blocked", severity: 8, stacktrace: "full")
endfilesystem
endapp
Logging
When the above filesystem
rule is triggered a log entry similar to the following is generated:
-
relative
<10>1 2021-04-01T11:37:24.203+01:00 userX_system java 25024 - - CEF:0|ARMR:Path Traversal mod - with stacktrace|Path Traversal mod - with stacktrace|2.7|Protect against relative and absolute path traversal attacks|Execute Rule|High|rt=Apr 01 2021 11:37:24.201 +0100 dvchost=userX_system procid=25024 appVersion=1 ruleType=filesystem securityFeature=filesystem path traversal act=protect msg=Path Traversal attack blocked stacktrace=com.waratek.spiracle.path_traversal.FileServlet01.doPost(FileServlet01.java:71)\njavax.servlet.http.HttpServlet.service(HttpServlet.java:650)\njavax.servlet.http.HttpServlet.service(HttpServlet.java:731)\nsun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\nsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\nsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\njava.lang.reflect.Method.invoke(Method.java:498)\norg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)\norg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)\norg.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)\nsun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\nsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\nsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\njava.lang.reflect.Method.invoke(Method.java:498)\norg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)\norg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)\norg.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)\norg.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)\norg.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)\norg.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)\norg.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)\norg.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)\norg.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)\norg.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442)\norg.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1082)\norg.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:623)\norg.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)\njava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\njava.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\norg.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\njava.lang.Thread.run(Thread.java:748) path=/tmp/tomcat/webapps/spiracle/pathTraversal/testFilesParent/testFilesChild/../TestFile httpSessionId=2912BD6B199C8B891244E63DC7DBCDE3 taintSource=HTTP_SERVLET httpRequestUri=/spiracle/FileServlet01 internalHttpRequestUri=/spiracle/FileServlet01 httpCookies=JSESSIONID\=2912BD6B199C8B891244E63DC7DBCDE3 remoteIpAddress=0:0:0:0:0:0:0:1
-
absolute
<10>1 2021-04-01T12:02:26.629+01:00 userX_system java 25024 - - CEF:0|ARMR:Path Traversal mod - with stacktrace|Path Traversal mod - with stacktrace|2.7|Protect against relative and absolute path traversal attacks|Execute Rule|High|rt=Apr 01 2021 12:02:26.627 +0100 dvchost=userX_system procid=25024 appVersion=1 ruleType=filesystem securityFeature=filesystem path traversal act=protect msg=Path Traversal attack blocked stacktrace=com.waratek.spiracle.path_traversal.FileServlet03.doPost(FileServlet03.java:68)\njavax.servlet.http.HttpServlet.service(HttpServlet.java:650)\njavax.servlet.http.HttpServlet.service(HttpServlet.java:731)\nsun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\nsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\nsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\njava.lang.reflect.Method.invoke(Method.java:498)\norg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)\norg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)\norg.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)\nsun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\nsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\nsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\njava.lang.reflect.Method.invoke(Method.java:498)\norg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)\norg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)\norg.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)\norg.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)\norg.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)\norg.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)\norg.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)\norg.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)\norg.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)\norg.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442)\norg.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1082)\norg.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:623)\norg.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)\njava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\njava.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\norg.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\njava.lang.Thread.run(Thread.java:748) path=/tmp/somefile.txt httpSessionId=2912BD6B199C8B891244E63DC7DBCDE3 taintSource=HTTP_SERVLET httpRequestUri=/spiracle/FileServlet03 internalHttpRequestUri=/spiracle/FileServlet03 httpCookies=JSESSIONID\=2912BD6B199C8B891244E63DC7DBCDE3 remoteIpAddress=0:0:0:0:0:0:0:1
The following mod protects against relative path traversal attacks that originate from a JDBC connection:
app("Path Traversal mod 2"):
requires(version: ARMR/2.7)
filesystem("Protect against relative path traversal attacks"):
input(database)
traversal(relative)
protect(message: "Path Traversal attack blocked", severity: High)
endfilesystem
endapp
The following mod monitors for absolute path traversal attacks that originate from an HTTP/HTTPS request:
app("Path Traversal mod 3"):
requires(version: ARMR/2.7)
filesystem("Detect and log absolute path traversal attacks"):
input(http)
traversal(absolute)
detect(message: "Path Traversal attack detected", severity: Medium)
endfilesystem
endapp
The following mod protects against both relative path traversal attacks that originate from various untrusted sources. Logging is switched off by the omission of the log message parameter.
app("Path Traversal mod 4"):
requires(version: ARMR/2.7)
filesystem("Protect against relative and absolute path traversal attacks"):
input(deserialization, http, database)
traversal()
protect()
endfilesystem
endapp