{"id":65793,"date":"2023-04-17T12:07:06","date_gmt":"2023-04-17T04:07:06","guid":{"rendered":"https:\/\/version-2.com.sg\/?p=65793"},"modified":"2024-09-13T16:31:21","modified_gmt":"2024-09-13T08:31:21","slug":"cve-2020-17519-apache-flink-directory-traversal-vulnerability","status":"publish","type":"post","link":"https:\/\/version-2.com\/zh\/2023\/04\/cve-2020-17519-apache-flink-directory-traversal-vulnerability\/","title":{"rendered":"CVE-2020-17519: Apache Flink Directory Traversal Vulnerability"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"65793\" class=\"elementor elementor-65793\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-4da8c5f9 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"4da8c5f9\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[{&quot;jet_parallax_layout_image&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;_id&quot;:&quot;decf9c3&quot;,&quot;jet_parallax_layout_image_tablet&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_mobile&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_speed&quot;:{&quot;unit&quot;:&quot;%&quot;,&quot;size&quot;:50,&quot;sizes&quot;:[]},&quot;jet_parallax_layout_type&quot;:&quot;scroll&quot;,&quot;jet_parallax_layout_direction&quot;:&quot;1&quot;,&quot;jet_parallax_layout_fx_direction&quot;:null,&quot;jet_parallax_layout_z_index&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x&quot;:50,&quot;jet_parallax_layout_bg_x_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y&quot;:50,&quot;jet_parallax_layout_bg_y_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size&quot;:&quot;auto&quot;,&quot;jet_parallax_layout_bg_size_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_animation_prop&quot;:&quot;transform&quot;,&quot;jet_parallax_layout_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;]}]}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-133ba185\" data-id=\"133ba185\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-fc2da8d post-content elementor-widget elementor-widget-text-editor\" data-id=\"fc2da8d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span style=\"color: #000000;\"><img fetchpriority=\"high\" decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjszio81g880ks10up19n0l.gif?tr=w-1800,c-at_max\" width=\"600\" height=\"338\" \/><\/span><\/p><div class=\"news-detail-inner-content\" data-v-85c4bf60=\"\" data-v-0bbc59dc=\"\"><h1><span style=\"color: #000000;\">Introduction<\/span><\/h1><p><span style=\"color: #000000;\">Directory Traversal in Apache Flink version 1.11.0, 1.11.1, and 1.11.2 has been found and registered as #CVE-2020-17519<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjifeyk33ja0jmj1fqjhjpg.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">What is Apache Flink?<\/span><\/p><p><span style=\"color: #000000;\">#Apache #Flink is an #open-source, unified stream-processing and batch-processing framework developed by the Apache Software Foundation. The core of Apache Flink is a distributed streaming data-flow engine written in Java and Scala. Flink executes arbitrary dataflow programs in a data-parallel and pipelined manner.<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjy6txf1jtp0ks10sg83z28.png\" \/><\/span><\/p><p><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/www.shodan.io\/search?query=flink+port%3A8081\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/www.shodan.io\/search?query=flink+port%3A8081<\/a><\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjigzse33jw0jmjgnij9snd.png\" \/><\/span><\/p><h3><span style=\"color: #000000;\">Background Story<\/span><\/h3><p><span style=\"color: #000000;\">After I figured out how to debug Apache Flink and edit the configuration so I can debug it remotely which gives the huge advantage of following the request step by step. However I had to figure out where I want to set the breakpoints, I started reading through the code (I almost read everything :D), and from previous experience and reading the API doc I figured out to check the router class, and there I found 6 classes.<\/span><\/p><p><span style=\"color: #000000;\">The classes are not directly related however one of them handles and process the incoming HTTP requests and routes them to the right handler also to build more of a clear idea I had to understand those 6 classes more in detail.<\/span><\/p><p><span style=\"color: #000000;\">After that being said, I found that <strong>channelRead0<\/strong> it&#8217;s an interesting method, so I added a breakpoint there, I sent the request that triggers the vulnerability, and I started to step-in the program.<\/span><\/p><p><span style=\"color: #000000;\">After a lot of stepping-in, I found the implemented method that decodes the URL and gets the path from it, also I found the method that read the file and how it gets loaded.<\/span><\/p><h3><span style=\"color: #000000;\">Build the\u00a0lab<\/span><\/h3><h4><span style=\"color: #000000;\">Install the system and prerequisites<\/span><\/h4><ul><li><p><span style=\"color: #000000;\">OS: Ubuntu Server 20.04<\/span><\/p><\/li><li><p><span style=\"color: #000000;\">You will need to install maven<\/span><\/p><ul><li><p><span style=\"color: #000000;\"><code>sudo apt update<\/code><\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>sudo apt install default-jdk<\/code><\/span><\/p><\/li><li><p><span style=\"color: #000000;\">Download it from the following link: <a style=\"color: #000000;\" href=\"https:\/\/dlcdn.apache.org\/maven\/maven-3\/3.2.5\/binaries\/apache-maven-3.2.5-bin.tar.gz\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/dlcdn.apache.org\/maven\/maven-3\/3.2.5\/binaries\/apache-maven-3.2.5-bin.tar.gz<\/a><\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>sudo tar xf apache-maven-3.2.5-bin.tar.gz -C \/opt<\/code><\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>sudo ln -s \/opt\/apache-maven-3.2.5 \/opt\/maven<\/code><\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>sudo vim \/etc\/profile.d\/maven.sh<\/code><\/span><\/p><ul><li><p><span style=\"color: #000000;\"><code>export JAVA_HOME=\/usr\/lib\/jvm\/default-java<\/code><\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>export M2_HOME=\/opt\/maven<\/code><\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>export MAVEN_HOME=\/opt\/maven<\/code><\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>export PATH=${M2_HOME}\/bin:${PATH}<\/code><\/span><\/p><\/li><\/ul><\/li><li><p><span style=\"color: #000000;\"><code>sudo chmod +x \/etc\/profile.d\/maven.sh<\/code><\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>source \/etc\/profile.d\/maven.sh<\/code><\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>mvn -version<\/code><\/span><\/p><\/li><\/ul><\/li><li><p><span style=\"color: #000000;\">Install apache flink<\/span><\/p><ul><li><p><span style=\"color: #000000;\">Download apache flink from the following link:<\/span><\/p><p><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/github.com\/apache\/flink\/releases\/tag\/release-1.11.0\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/apache\/flink\/releases\/tag\/release-1.11.0<\/a><\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>unzip flink-release-1.11.0.zip<\/code><\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>cd flink-release-1.11.0<\/code><\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>mvn clean package -DskipTests<\/code><\/span><\/p><\/li><\/ul><\/li><\/ul><h4><span style=\"color: #000000;\">Setup the debugger<\/span><\/h4><ul><li><p><span style=\"color: #000000;\">Open flink-conf.yaml<\/span><\/p><\/li><\/ul><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjj44u718sh0ks19y7a2dnv.png\" \/><\/span><\/p><ul><li><p><span style=\"color: #000000;\">Add the following:<\/span><\/p><ul><li><p><span style=\"color: #000000;\"><code>env.java.opts: \"-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1337\"<\/code><\/span><\/p><\/li><\/ul><\/li><li><p><span style=\"color: #000000;\">By that, the debugger will be able to connect to port 1337.<\/span><\/p><\/li><\/ul><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjj63i518tk0ks16zsq3jfu.png\" \/><\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjj6dcu18tu0ks12m6d4ixm.png\" \/><\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjj7fcs33ym0jmj0c9y69e2.png\" \/><\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjj7n0p18ui0ks1fucsfyc6.png\" \/><\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjj8y3t18v70ks16i2jgto9.png\" \/><\/span><\/p><ul><li><p><span style=\"color: #000000;\">Now run the solution<\/span><\/p><ul><li><p><span style=\"color: #000000;\"><code>.\/build-target\/bin\/start-cluster.sh<\/code><\/span><\/p><\/li><\/ul><\/li><\/ul><ul><li><p><span style=\"color: #000000;\">You can check it in your browser<\/span><\/p><\/li><\/ul><p><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"http:\/\/localhost:8081\/#\/overview\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost:8081\/#\/overview<\/a><\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjrsa4y1f890ks1es1z8ehe.png\" \/><\/span><\/p><ul><li><p><span style=\"color: #000000;\">Now run the debugger in this file<\/span><\/p><\/li><\/ul><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjja9di34000jmjb7vt17w7.png\" \/><\/span><\/p><h1><span style=\"color: #000000;\">Reproduce the vulnerability<\/span><\/h1><p><span style=\"color: #000000;\">Once it&#8217;s all installed and ready you should be able to easily reproduce the vulnerability by browsing the following link:<\/span><\/p><p><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"http:\/\/localhost:8081\/jobmanager\/logs\/..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252fetc%252fpasswd\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost:8081\/jobmanager\/logs\/..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252fetc%252fpasswd<\/a><\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjjlrug34700jmjaq1c9484.png\" \/><\/span><\/p><h1><span style=\"color: #000000;\">Static Analysis<\/span><\/h1><h3><span style=\"color: #000000;\">Explaining the code<\/span><\/h3><p><span style=\"color: #000000;\">From reading the document and going through whatever information I can find about this CVE, I know this is happening in the REST API.<\/span><\/p><p><span style=\"color: #000000;\">You can notice here that the endpoint &#8220;jobmanager\/logs&#8221; is part of the REST API.<\/span><\/p><p><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/nightlies.apache.org\/flink\/flink-docs-release-1.17\/docs\/ops\/rest_api\/\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/nightlies.apache.org\/flink\/flink-docs-release-1.17\/docs\/ops\/rest_api\/<\/a><\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjjo22n194g0ks1fbjp4lf0.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">While you are reading in the doc, especially here, you can find that the REST API backend is in the flink-runtime.<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjjp85a349h0jmj5flac8e7.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">From previous experience, for example, the analysis of Joomla CVE-2023\u201323752 (<a style=\"color: #000000;\" href=\"https:\/\/www.vicarius.io\/vsociety\/blog\/cve-2023-23752-joomla-unauthorized-access-vulnerability\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/www.vicarius.io\/vsociety\/blog\/cve-2023-23752-joomla-unauthorized-access-vulnerability<\/a>)<\/span><\/p><p><span style=\"color: #000000;\">I know that there is some routing function, and route handlers that handle and process the request.<\/span><\/p><p><span style=\"color: #000000;\">Going through the folders and files and reading a lot of code, under <strong>flink-runtime\/src\/main\/java\/org.apache.flink.runtime<\/strong>, I found a folder named &#8220;rest&#8221; and I figured out it may be referring to rest API, and I found a handler folder there and there I found <strong>route<\/strong><\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjjrmb7196l0ks1bx8l578e.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">I started to read the codes in each file one by one.<\/span><\/p><h4><span style=\"color: #000000;\">MethodlessRouter<\/span><\/h4><p><span style=\"color: #000000;\">The <code>MethodlessRouter<\/code> class has the following components:<\/span><\/p><ul><li><p><span style=\"color: #000000;\">The <code>routes<\/code> map is a map of <code>PathPattern<\/code> objects to target objects.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\">The <code>routes()<\/code> method returns an unmodifiable map of all routes in the router.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\">The <code>addRoute<\/code> method adds a new route to the router by creating a new <code>PathPattern<\/code> object for the specified path pattern and adding it to the map of routes.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\">The <code>removePathPattern<\/code> method removes the route specified by the path pattern.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\">The <code>route<\/code> method takes a URI, a decoded path, a map of query parameters, and an array of path tokens as input, and returns a <code>RouteResult<\/code> object that contains the target object for the matched route, along with any path parameters and query parameters. It loops through the map of routes and checks if the path tokens match any of the <code>PathPattern<\/code> objects. If a match is found, the target object is returned along with any path parameters and query parameters.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\">The <code>anyMatched<\/code> method checks if there is any matching route for the given array of path tokens. It loops through the map of routes and checks if the path tokens match any of the <code>PathPattern<\/code> objects. If a match is found, it returns <code>true<\/code>.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\">The <code>size<\/code> method returns the number of routes in the router.<\/span><\/p><\/li><\/ul><h4><span style=\"color: #000000;\">PathPattern<\/span><\/h4><ul><li><p><span style=\"color: #000000;\"><code>PathPattern<\/code> which represents a pattern used to match a URL path. The class takes a path pattern as input in its constructor and creates a list of tokens from the pattern. The pattern can contain constants or placeholders, and if it exists, the placeholder with the format <code>:*<\/code> is a special placeholder to catch the rest of the path (may include slashes).<\/span><\/p><\/li><\/ul><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjjw7v634dd0jmjas91b1jn.png\" \/><\/span><\/p><ul><li><p><span style=\"color: #000000;\">The class has two instance variables, <code>pattern<\/code> and <code>tokens<\/code>, both of which are final and set in the constructor. <code>pattern<\/code> is a string representing the pattern without slashes at both ends. <code>tokens<\/code> is an array of strings representing the pattern split by the <code>\/<\/code> character, for example: <code>constant1\/constant2?foo=bar<\/code><\/span><\/p><\/li><\/ul><ul><li><p><span style=\"color: #000000;\"><code>PathPattern()<\/code> constructor creates a new <code>PathPattern<\/code> object from a <code>String pattern<\/code>. It checks if the pattern contains a query, removes slashes from both ends of the pattern using <code>removeSlashesAtBothEnds()<\/code>, and splits the pattern into tokens.<\/span><\/p><\/li><\/ul><ul><li><p><span style=\"color: #000000;\"><code>removeSlashesAtBothEnds()<\/code> This is a static utility method that removes slashes from both ends of a path. It takes a <code>String path<\/code>, checks if it is empty, finds the first non-slash character, finds the last non-slash character, and returns the substring between them.<\/span><\/p><\/li><\/ul><ul><li><p><span style=\"color: #000000;\"><code>Match()<\/code><\/span><\/p><p><span style=\"color: #000000;\">Params will be updated with params embedded in the request path.<\/span><\/p><p><span style=\"color: #000000;\">This method is designed so that requestPathTokens and params can be created only once then reused, to optimize for performance when a large number of path patterns need to be matched.<\/span><\/p><p><span style=\"color: #000000;\">Returns: false if not matched; in this case params should be reset<\/span><\/p><\/li><\/ul><h4><span style=\"color: #000000;\">RoutedRequest.Java<\/span><\/h4><p><span style=\"color: #000000;\">This contains <code>PathPattern<\/code> and this is the same class as we explained it before and <code>RoutedRequest<\/code> class and this class is for handling <code>HttpRequest<\/code> with associated <code>RouteResult<\/code>.<\/span><\/p><h4><span style=\"color: #000000;\">Router<\/span><\/h4><p><span style=\"color: #000000;\">I will not go through the code for this, the doc explaining it in a very well way.<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjk1z3n19cq0ks1a7298pjh.png\" \/><\/span><\/p><h4><span style=\"color: #000000;\">RouteResult<\/span><\/h4><p><span style=\"color: #000000;\"><code>RouteResult<\/code> is a class that represents the result of calling the <code>Router#route(HttpMethod, String)<\/code> method. It contains information about the matched route, such as the original request URI, the decoded request path, path parameters, and query parameters. It also holds a reference to the target that will handle the request.<\/span><\/p><ul><li><p><span style=\"color: #000000;\">The <code>RouteResult<\/code> class is defined with a generic type <code>T<\/code> which represents the target that will handle the request.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\">The <code>RouteResult<\/code> class has several instance variables:<\/span><\/p><ul><li><p><span style=\"color: #000000;\"><code>uri<\/code>: represents the original request URI.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>decodedPath<\/code>: represents the decoded request path.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>pathParams<\/code>: a map that contains all the path parameters embedded in the request path.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>queryParams<\/code>: a map that contains all the query parameters in the request URI.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>target<\/code>: the target that will handle the request.<\/span><\/p><\/li><\/ul><\/li><\/ul><ul><li><p><span style=\"color: #000000;\">The <code>RouteResult<\/code> class provides several methods to get the parameters from the path and query parameters:<\/span><\/p><ul><li><p><span style=\"color: #000000;\"><code>queryParam(name)<\/code>: extracts the first matching parameter in the <code>queryParams<\/code>.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>param(name)<\/code>: extracts the parameter in <code>pathParams<\/code> first, then falls back to the first matching parameter in <code>queryParams<\/code>.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>params(name)<\/code>: extracts all parameters in <code>pathParams<\/code> and <code>queryParams<\/code> matching the name.<\/span><\/p><\/li><\/ul><\/li><\/ul><h4><span style=\"color: #000000;\">RouteHandler<\/span><\/h4><p><span style=\"color: #000000;\"><code>RouterHandler<\/code> class is an inbound handler that converts a <code>HttpRequest<\/code> to a <code>RoutedRequest<\/code> and passes the <code>RoutedRequest<\/code> to the matched handler. It also replaces the standard error response to be identical with those sent by the <code>AbstractRestHandler<\/code>.<\/span><\/p><ul><li><p><span style=\"color: #000000;\"><code>ROUTER_HANDLER_NAME<\/code> and <code>ROUTED_HANDLER_NAME<\/code> are constants used as names for the handler in the Netty pipeline.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>LOG<\/code> is a logger instance for logging debug or trace information about the handler.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>responseHeaders<\/code> is a map containing headers to be included in the HTTP response.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>router<\/code> is an instance of the <code>Router<\/code> class which is used to route incoming requests to their respective handlers.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\">The <code>RouterHandler<\/code> constructor takes a <code>Router<\/code> and a map of headers as parameters and initializes the <code>router<\/code> and <code>responseHeaders<\/code> fields accordingly.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>getName()<\/code> is a method that returns the name of the handler.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\">The <code>RouterHandler<\/code> class overrides the <code>channelRead0<\/code> method, which is called by Netty whenever a new message is received on the channel. This method is responsible for routing incoming requests to their respective handlers and generating responses.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\">The overridden <code>channelRead0<\/code> method first checks if the request expects 100-continue, and if so, sends a continue response and returns.<\/span><\/p><\/li><\/ul><p><span style=\"color: #000000;\">The HTTP 100 Continue informational status response code indicates that everything so far is OK and that the client should continue with the request or ignore it if it is already finished.<\/span><\/p><ul><li><p><span style=\"color: #000000;\">It then extracts the HTTP method and path from the request using <code>httpRequest.getMethod()<\/code> and <code>httpRequest.uri()<\/code>, respectively. It passes the method and path to the <code>router.route<\/code> method to obtain a <code>RouteResult<\/code> object, which contains the matched handler and any path or query parameters.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\">If the <code>routeResult<\/code> object is not <code>null<\/code>, the <code>routed<\/code> method is called to pass the request to the matched handler, otherwise, it will call <code>respondNotFound<\/code> and send <code>Not Found<\/code> response.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\">The <code>routed<\/code> method retrieves the handler from the <code>routeResult<\/code> object, and adds it to the Netty pipeline using <code>pipeline.addAfter<\/code> or <code>pipeline.replace<\/code>, depending on whether the handler was already added to the pipeline.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\">Finally, it creates a new <code>RoutedRequest<\/code> object using the <code>routeResult<\/code> and <code>httpRequest<\/code>, and passes it to the next channel handler in the pipeline using <code>channelHandlerContext.fireChannelRead<\/code>.<\/span><\/p><\/li><\/ul><p><span style=\"color: #000000;\">After we explained all the involved classes, you can understand why I thought <code>RouterHandler<\/code> is the most interesting one for me.<\/span><\/p><h1><span style=\"color: #000000;\">Debugging<\/span><\/h1><p><span style=\"color: #000000;\">Before we start the debugging, don&#8217;t forget to run the debugger you added before<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjl1g0719xu0ks1035o979b.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">Add a breakpoint here:<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjl2hji19za0ks1dcj2bykr.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">Now send the request, or just simply go to<\/span><\/p><p><span style=\"color: #000000;\"><code>http:\/\/localhost:8081\/jobmanager\/logs\/..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252fetc%252fpasswd<\/code><\/span><\/p><p><span style=\"color: #000000;\">instantly, you will see something like this, and you can notice the httpRequest with everything else related such as method, URI&#8230;etc.<\/span><\/p><p><span style=\"color: #000000;\">Keep your eyes on the code and debugger.<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjl6wk2357i0jmj3qz352js.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">Now step-in.<\/span><\/p><h4><span style=\"color: #000000;\">How does the URL get decoded and read as path<\/span><\/h4><p><span style=\"color: #000000;\">Once you reach to this line number 82 in RouterHandler.java<\/span><\/p><p><span style=\"color: #000000;\"><code>RouteResult&lt;?&gt; routeResult = router.route(method, qsd.path(), qsd.parameters());<\/code><\/span><\/p><p><span style=\"color: #000000;\">Click the step-in button, and you will notice that route, path(), and parameter got highlighted.<\/span><\/p><p><span style=\"color: #000000;\">Click on <code>path()<\/code><\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjl9m5u35af0jmjdwsv3ahn.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">This will lead you to <code>QueryStringDecoder.class<\/code> this method:<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjlac0635ao0jmj3jgedq98.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">Now click step-in<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjlbzmf1a890ks1dq2440ry.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">Step in again and this will take you to <code>decodeComponent<\/code> method<\/span><\/p><p><span style=\"color: #000000;\">This is basically a method that decodes a portion of a string that may contain URL-encoded characters.<\/span><\/p><pre><span style=\"color: #000000;\"><code>    private static String decodeComponent(String s, int from, int toExcluded, Charset charset, boolean isPath) {\n\n        int len = toExcluded - from;\n\n        if (len &lt;= 0) {\n\n            return \"\";\n\n        } else {\n\n            int firstEscaped = -1;\n\n            int decodedCapacity;\n\n            for(int i = from; i &lt; toExcluded; ++i) {\n\n                decodedCapacity = s.charAt(i);\n\n                if (decodedCapacity == 37 || decodedCapacity == 43 &amp;&amp; !isPath) {\n\n                    firstEscaped = i;\n\n                    break;\n\n                }\n\n            }\n\n            if (firstEscaped == -1) {\n\n                return s.substring(from, toExcluded);\n\n            } else {\n\n                CharsetDecoder decoder = CharsetUtil.decoder(charset);\n\n                decodedCapacity = (toExcluded - firstEscaped) \/ 3;\n\n                ByteBuffer byteBuf = ByteBuffer.allocate(decodedCapacity);\n\n                CharBuffer charBuf = CharBuffer.allocate(decodedCapacity);\n\n                StringBuilder strBuf = new StringBuilder(len);\n\n                strBuf.append(s, from, firstEscaped);\n\n                for(int i = firstEscaped; i &lt; toExcluded; ++i) {\n\n                    char c = s.charAt(i);\n\n                    if (c != '%') {\n\n                        strBuf.append(c == '+' &amp;&amp; !isPath ? ' ' : c);\n\n                    } else {\n\n                        byteBuf.clear();\n\n                        do {\n\n                            if (i + 3 &gt; toExcluded) {\n\n                                throw new IllegalArgumentException(\"unterminated escape sequence at index \" + i + \" of: \" + s);\n\n                            }\n\n                            byteBuf.put(StringUtil.decodeHexByte(s, i + 1));\n\n                            i += 3;\n\n                        } while(i &lt; toExcluded &amp;&amp; s.charAt(i) == '%');\n\n                        --i;\n\n                        byteBuf.flip();\n\n                        charBuf.clear();\n\n                        CoderResult result = decoder.reset().decode(byteBuf, charBuf, true);\n\n                        try {\n\n                            if (!result.isUnderflow()) {\n\n                                result.throwException();\n\n                            }\n\n                            result = decoder.flush(charBuf);\n\n                            if (!result.isUnderflow()) {\n\n                                result.throwException();\n\n                            }\n\n                        } catch (CharacterCodingException var16) {\n\n                            throw new IllegalStateException(var16);\n\n                        }\n\n                        strBuf.append(charBuf.flip());\n\n                    }\n\n                }\n\n                return strBuf.toString();\n\n            }\n\n        }\n\n    }<\/code><\/span><\/pre><p><span style=\"color: #000000;\">The method takes the following variables a string <code>s<\/code>, a starting index <code>from<\/code>, an ending index <code>toExcluded<\/code>, a character set <code>charset<\/code>, and a boolean <code>isPath<\/code>.<\/span><\/p><pre><span style=\"color: #000000;\"><code>private static String decodeComponent(String s, int from, int toExcluded, Charset charset, boolean isPath) {<\/code><\/span><\/pre><p><span style=\"color: #000000;\">The length of the portion of the string to decode is calculated as the difference between the ending index and the starting index. If the length is zero or negative, an empty string is returned. Otherwise, the decoding process begins.<\/span><\/p><pre><span style=\"color: #000000;\"><code>int len = toExcluded - from;\nif (len &lt;= 0) {\n    return \"\";\n} else {<\/code><\/span><\/pre><p><span style=\"color: #000000;\">The <code>firstEscaped<\/code> variable is set to -1 to indicate that no URL-encoded characters have been found yet. The loop iterates over the portion of the string to decode and checks each character. If a character is either a percent sign (`%`) or a plus sign (`+`) and the <code>isPath<\/code> flag is false (indicating that the string is not a URL path), the <code>firstEscaped<\/code> variable is set to the index of the character and the loop breaks.<\/span><\/p><pre><span style=\"color: #000000;\"><code>int firstEscaped = -1;\n\nint decodedCapacity;\nfor(int i = from; i &lt; toExcluded; ++i) {\n    decodedCapacity = s.charAt(i);\n    if (decodedCapacity == 37 || decodedCapacity == 43 &amp;&amp; !isPath) {\n        firstEscaped = i;\n        break;\n    }\n}<\/code><\/span><\/pre><p><span style=\"color: #000000;\">If no URL-encoded characters were found, the entire portion of the string is returned unmodified using the <code>substring<\/code> method. Otherwise, the decoding process continues.<\/span><\/p><pre><span style=\"color: #000000;\"><code>if (firstEscaped == -1) {\n    return s.substring(from, toExcluded);\n} else {\n    ...\n}<\/code><\/span><\/pre><ul><li><p><span style=\"color: #000000;\">A <code>CharsetDecoder<\/code> object is created using the provided character set. <\/span><\/p><\/li><li><p><span style=\"color: #000000;\">The <code>decodedCapacity<\/code> variable is set to the maximum number of bytes <\/span><br \/><span style=\"color: #000000;\">that could be required to represent the URL-encoded portion of the string in the given character set. <\/span><\/p><\/li><li><p><span style=\"color: #000000;\">Byte and character buffers are allocated to hold the decoded data. <\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><code>StringBuilder<\/code> is created to accumulate the decoded characters.<\/span><\/p><\/li><li><p><span style=\"color: #000000;\">Finally, <code>strBuf.append(s, from, firstEscaped)<\/code> that appends a substring of the original input string <code>s<\/code> to the <code>StringBuilder<\/code> object <code>strBuf<\/code>.<\/span><\/p><\/li><\/ul><pre><span style=\"color: #000000;\"><code>CharsetDecoder decoder = CharsetUtil.decoder(charset);\ndecodedCapacity = (toExcluded - firstEscaped) \/ 3;\nByteBuffer byteBuf = ByteBuffer.allocate(decodedCapacity);\nCharBuffer charBuf = CharBuffer.allocate(decodedCapacity);\nStringBuilder strBuf = new StringBuilder(len);\nstrBuf.append(s, from, firstEscaped);<\/code><\/span><\/pre><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjlj4bn1afd0ks1gy452ygy.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">The last part of the method decodes any URL-encoded characters found in the string and appends the resulting decoded characters to the <code>StringBuilder<\/code> that will be returned as the decoded string.<\/span><\/p><p><span style=\"color: #000000;\">The loop starts at the index of the first URL-encoded character found earlier (`firstEscaped`) and iterates over each character in the remaining portion of the string to decode. If the character is not a percent sign (`%`), it is appended to the <code>StringBuilder<\/code> directly. If it is a percent sign, it indicates the start of a URL-encoded sequence, and the byte buffer is cleared.<\/span><\/p><p><span style=\"color: #000000;\">The loop then reads the two hexadecimal digits that follow the percent sign in the input string, converts them to a byte value, and appends that byte to the byte buffer. This process continues until a non-percent character is found or the end of the string is reached. If the end of the string is reached before a terminating percent sign is found, an exception is thrown.<\/span><\/p><pre><span style=\"color: #000000;\"><code>for(int i = firstEscaped; i &lt; toExcluded; ++i) {\n    char c = s.charAt(i);\n    if (c != '%') {\n        strBuf.append(c == '+' &amp;&amp; !isPath ? ' ' : c);\n    } else {\n        byteBuf.clear();\n        \n        do {\n            if (i + 3 &gt; toExcluded) {\n                throw new IllegalArgumentException(\"unterminated escape sequence at index \" + i + \" of: \" + s);\n            }\n\n            byteBuf.put(StringUtil.decodeHexByte(s, i + 1));\n            i += 3;\n        } while(i &lt; toExcluded &amp;&amp; s.charAt(i) == '%');\n        \n        --i;\n        byteBuf.flip();\n        charBuf.clear();\n        CoderResult result = decoder.reset().decode(byteBuf, charBuf, true);\n        \n        try {\n            if (!result.isUnderflow()) {\n                result.throwException();\n            }\n            \n            result = decoder.flush(charBuf);\n            if (!result.isUnderflow()) {\n                result.throwException();<\/code><\/span><\/pre><p><span style=\"color: #000000;\">So in other words what happens is that it iterates through the URL or the path which you will see as a the value in variable <code>s<\/code> and It will decode it twice, once decode the double URL encoding, after that, it re-decodes it, so we have now the normal passwd path and that&#8217;s because it checks that there&#8217;s a character indicating that this is an URL-encoded value.<\/span><\/p><p><span style=\"color: #000000;\">You can see here, it&#8217;s getting decoded from <code>..%252f<\/code> to <code>..%2f<\/code><\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjlm6sw1aho0ks14rikedx9.png\" \/><\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjlmjgx35lw0jmjaa5gczcq.png\" \/><\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjlmuo835m00jmj33y049xy.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">Watch the video here for more understanding:<\/span><\/p><p><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/youtu.be\/j9-cP5JwY54\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/youtu.be\/j9-cP5JwY54<\/a><\/span><\/p><p><span style=\"color: #000000;\">Once you get here<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjlobgm35ms0jmj40ls0iye.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">Hit another step-in, you suppose to get here (if not, just go to MethodlessRouter.java and add a breakpoint at line 94)<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjlprto35nk0jmj30r0af29.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">You will find yourself here:<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjlsbm01akq0ks1d0uzcbws.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">You can see the <code>pathParams<\/code> variable it&#8217;s basically a filename and it maps to <code>..\/..\/..\/..\/..\/..\/..\/..\/..\/..\/..\/..\/etc\/passwd<\/code><\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjltj1g35pm0jmj1wmk48sc.png\" \/><\/span><\/p><ul><li><p><span style=\"color: #000000;\"><code>unmodifiableMap<\/code> Returns an unmodifiable view of the specified map. This method allows modules to provide users with &#8220;read-only&#8221; access to internal maps. Query operations on the returned map &#8220;read through&#8221; to the specified map, and attempts to modify the returned map, whether direct or via its collection views, result in an UnsupportedOperationException.<\/span><\/p><p><span style=\"color: #000000;\">The returned map will be serializable if the specified map is serializable.<\/span><\/p><\/li><\/ul><h4><span style=\"color: #000000;\">How is the file read and accessed<\/span><\/h4><p><span style=\"color: #000000;\">Keep following the debugger, you suppose to reach this line here:<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjlwa9u35r40jmj2zs85zl1.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">This is amazing because the value of <code>file<\/code> is<\/span><\/p><p><span style=\"color: #000000;\"><code>\/home\/us1\/Desktop\/flink-release-1.11.0\/flink-dist\/target\/flink-1.11.0-bin\/flink-1.11.0\/log\/..\/..\/..\/..\/..\/..\/..\/..\/..\/..\/..\/..\/etc\/passwd<\/code><\/span><\/p><p><span style=\"color: #000000;\">Just to show you how this work, go to your terminal and <code>cat<\/code> this path, and it will cat the passwd file.<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjlxcqo1anf0ks1eui10pw7.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">Keep stepping-in<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjly07p1ann0ks10al15b8g.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">You will start seeing information about the file in the debugger, such as the file length, the permissions (writable, readable, append), path, open or close ..etc.<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjlz2a11ao90ks1a31l975b.png\" \/><\/span><\/p><h4><span style=\"color: #000000;\">The function that loads the file<\/span><\/h4><p><span style=\"color: #000000;\">Keep following the debugger, and you will reach this snippet of code:<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjm158r1apr0ks12vze65ev.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">and from here, another step-in, you will get to the method where it loads the file.<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjnfdmq1bkg0ks1h6lpdsmm.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">You can see here the filename and the passwd path.<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjngahr36pj0jmj0gbed8gz.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">and just for extra information, this will use File. java which creates a new File instance from a parent abstract pathname and a child pathname string.<\/span><\/p><p><span style=\"color: #000000;\">Finally, you will notice that the content of passwd got sent to the browser<\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjno13j36xt0jmjfg9434pa.png\" \/><\/span><\/p><h1><span style=\"color: #000000;\">Mitigation<\/span><\/h1><p><span style=\"color: #000000;\">Any version after apache flink 1.11.2 is fixed.<\/span><\/p><h1><span style=\"color: #000000;\">Patch Diffing<\/span><\/h1><p><span style=\"color: #000000;\">We can see the changes here:<\/span><\/p><p><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/github.com\/apache\/flink\/commit\/b561010b0ee741543c3953306037f00d7a9f0801#diff-30c0c4f6e68367e426ab85ce42ff037bcb1ed50a27417e4e55bf4e17bc734c7d\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/apache\/flink\/commit\/b561010b0ee741543c3953306037f00d7a9f0801#diff-30c0c4f6e68367e426ab85ce42ff037bcb1ed50a27417e4e55bf4e17bc734c7d<\/a><\/span><\/p><p><span style=\"color: #000000;\"><img decoding=\"async\" src=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjnvjnn1c160ks159uxhr5p.png\" \/><\/span><\/p><p><span style=\"color: #000000;\">So basically they made changes on <code>JobManagerCustomLogHandler.java<\/code>.<\/span><\/p><p><span style=\"color: #000000;\">This line<\/span><\/p><pre><span style=\"color: #000000;\"><code>String filename = handlerRequest.getPathParameter(LogFileNamePathParameter.class);<\/code><\/span><\/pre><p><span style=\"color: #000000;\">This will get only the name of the file, so if the attacker tried to achieve directory traversal the path won&#8217;t be the following as we saw it before<\/span><\/p><p><span style=\"color: #000000;\"><code>\/home\/us1\/Desktop\/flink-release-1.11.0\/flink-dist\/target\/flink-1.11.0-bin\/flink-1.11.0\/log\/..\/..\/..\/..\/..\/..\/..\/..\/..\/..\/..\/..\/etc\/passwd<\/code><\/span><\/p><p><span style=\"color: #000000;\">we would get <code>passwd<\/code> only as the file name as a result, the method would not be able to access the sensitive file outside the intended directory structure, and the attack would be prevented.<\/span><\/p><h1><span style=\"color: #000000;\">Final Thoughts<\/span><\/h1><p><span style=\"color: #000000;\">It&#8217;s not really that complicated vulnerability as a concept, all that happened is that a get file function getting injected with a specific path <code>..\/..\/..\/..\/etc\/passwd<\/code> and it&#8217;s very normal that it will follow this path and load the file.<\/span><\/p><p><span style=\"color: #000000;\">However, what makes this breakdown complicated is that I&#8217;m trying to achieve what I like to call &#8220;deep understanding&#8221; and that&#8217;s because I&#8217;m VSOCIETY ELITE 1337 member \ud83d\ude08, but I like to understand what happened exactly, when, how, and why.<\/span><\/p><p><span style=\"color: #000000;\">I would suggest you follow the debugging steps because it will make sense along with the code explanation.<\/span><\/p><p><span style=\"color: #000000;\">The patch diffing was pretty much straightforward, I like patch diffing!<\/span><\/p><h1><span style=\"color: #000000;\">Resources:<\/span><\/h1><ul><li><p><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/lists.apache.org\/thread\/typ0h03zyfrzjqlnb7plh64df1g2383d\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/lists.apache.org\/thread\/typ0h03zyfrzjqlnb7plh64df1g2383d<\/a><\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/netty.io\/4.0\/api\/index.html\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/netty.io\/4.0\/api\/index.html<\/a><\/span><\/p><\/li><li><p><span style=\"color: #000000;\"><a style=\"color: #000000;\" href=\"https:\/\/phoenixnap.com\/kb\/install-maven-on-ubuntu\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\/\/phoenixnap.com\/kb\/install-maven-on-ubuntu<\/a><\/span><\/p><\/li><\/ul><\/div>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8085a61 post-content elementor-widget elementor-widget-shortcode\" data-id=\"8085a61\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">\t\t<div data-elementor-type=\"page\" data-elementor-id=\"18103\" class=\"elementor elementor-18103\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-748947f elementor-section-full_width elementor-section-height-default elementor-section-height-default\" data-id=\"748947f\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[{&quot;jet_parallax_layout_image&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;_id&quot;:&quot;c4f773e&quot;,&quot;jet_parallax_layout_image_tablet&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_mobile&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_speed&quot;:{&quot;unit&quot;:&quot;%&quot;,&quot;size&quot;:50,&quot;sizes&quot;:[]},&quot;jet_parallax_layout_type&quot;:&quot;scroll&quot;,&quot;jet_parallax_layout_direction&quot;:&quot;1&quot;,&quot;jet_parallax_layout_fx_direction&quot;:null,&quot;jet_parallax_layout_z_index&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x&quot;:50,&quot;jet_parallax_layout_bg_x_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y&quot;:50,&quot;jet_parallax_layout_bg_y_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size&quot;:&quot;auto&quot;,&quot;jet_parallax_layout_bg_size_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_animation_prop&quot;:&quot;transform&quot;,&quot;jet_parallax_layout_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;]}]}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-7995c19\" data-id=\"7995c19\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-a437045 elementor-widget elementor-widget-image-box\" data-id=\"a437045\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image-box.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"elementor-image-box-wrapper\"><div class=\"elementor-image-box-content\"><h3 class=\"elementor-image-box-title\">About Version 2 Digital<\/h3><p class=\"elementor-image-box-description\">Version 2 Digital is one of the most dynamic IT companies in Asia. The company distributes a wide range of IT products across various areas including cyber security, cloud, data protection, end points, infrastructures, system monitoring, storage, networking, business productivity and communication products.\n<br><br>\nThrough an extensive network of channels, point of sales, resellers, and partnership companies, Version 2 offers quality products and services which are highly acclaimed in the market. Its customers cover a wide spectrum which include Global 1000 enterprises, regional listed companies, different vertical industries, public utilities, Government, a vast number of successful SMEs, and consumers in various Asian cities.<\/p><\/div><\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t\n\t\t<div data-elementor-type=\"page\" data-elementor-id=\"39690\" class=\"elementor elementor-39690\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-748947f elementor-section-full_width elementor-section-height-default elementor-section-height-default\" data-id=\"748947f\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[{&quot;jet_parallax_layout_image&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;_id&quot;:&quot;c4f773e&quot;,&quot;jet_parallax_layout_image_tablet&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_mobile&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_speed&quot;:{&quot;unit&quot;:&quot;%&quot;,&quot;size&quot;:50,&quot;sizes&quot;:[]},&quot;jet_parallax_layout_type&quot;:&quot;scroll&quot;,&quot;jet_parallax_layout_direction&quot;:&quot;1&quot;,&quot;jet_parallax_layout_fx_direction&quot;:null,&quot;jet_parallax_layout_z_index&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x&quot;:50,&quot;jet_parallax_layout_bg_x_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y&quot;:50,&quot;jet_parallax_layout_bg_y_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size&quot;:&quot;auto&quot;,&quot;jet_parallax_layout_bg_size_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_animation_prop&quot;:&quot;transform&quot;,&quot;jet_parallax_layout_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;]}]}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-7995c19\" data-id=\"7995c19\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-ff2a228 elementor-widget elementor-widget-text-editor\" data-id=\"ff2a228\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><\/p>\n<p><b>About VRX<\/b><br><b>VRX&nbsp;<\/b>is a consolidated vulnerability management platform that protects assets in real time. Its rich, integrated features efficiently pinpoint and remediate the largest risks to your cyber infrastructure. Resolve the most pressing threats with efficient automation features and precise contextual analysis.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Introduction Directory Traversal in Apache Flink versio [&hellip;]<\/p>\n","protected":false},"author":148637484,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[476,1075,61],"tags":[477,1076],"class_list":["post-65793","post","type-post","status-publish","format-standard","hentry","category-vrx","category-year2023","category-press-release","tag-vrx","tag-1076"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>CVE-2020-17519: Apache Flink Directory Traversal Vulnerability - Version 2<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.vicarius.io\/blog\/cve-2020-17519-apache-flink-directory-traversal-vulnerability\" \/>\n<meta property=\"og:locale\" content=\"zh_HK\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"CVE-2020-17519: Apache Flink Directory Traversal Vulnerability - Version 2\" \/>\n<meta property=\"og:description\" content=\"Introduction Directory Traversal in Apache Flink versio [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.vicarius.io\/blog\/cve-2020-17519-apache-flink-directory-traversal-vulnerability\" \/>\n<meta property=\"og:site_name\" content=\"Version 2\" \/>\n<meta property=\"article:published_time\" content=\"2023-04-17T04:07:06+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-09-13T08:31:21+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjszio81g880ks10up19n0l.gif?tr=w-1800,c-at_max\" \/>\n<meta name=\"author\" content=\"versionpan\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"versionpan\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9810\u8a08\u95b1\u8b80\u6642\u9593\" \/>\n\t<meta name=\"twitter:data2\" content=\"20 \u5206\u9418\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/2023\\\/04\\\/cve-2020-17519-apache-flink-directory-traversal-vulnerability\\\/\"},\"author\":{\"name\":\"versionpan\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/person\\\/103ffe36f7fd34a1cc126a30431b94d8\"},\"headline\":\"CVE-2020-17519: Apache Flink Directory Traversal Vulnerability\",\"datePublished\":\"2023-04-17T04:07:06+00:00\",\"dateModified\":\"2024-09-13T08:31:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/2023\\\/04\\\/cve-2020-17519-apache-flink-directory-traversal-vulnerability\\\/\"},\"wordCount\":2658,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ik.imagekit.io\\\/14sfaswy6hrz\\\/blog-posts\\\/images\\\/clgjszio81g880ks10up19n0l.gif?tr=w-1800,c-at_max\",\"keywords\":[\"vRx\",\"2023\"],\"articleSection\":[\"vRx\",\"2023\",\"Press Release\"],\"inLanguage\":\"zh-HK\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/version-2.com\\\/2023\\\/04\\\/cve-2020-17519-apache-flink-directory-traversal-vulnerability\\\/\",\"url\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2020-17519-apache-flink-directory-traversal-vulnerability\",\"name\":\"CVE-2020-17519: Apache Flink Directory Traversal Vulnerability - Version 2\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ik.imagekit.io\\\/14sfaswy6hrz\\\/blog-posts\\\/images\\\/clgjszio81g880ks10up19n0l.gif?tr=w-1800,c-at_max\",\"datePublished\":\"2023-04-17T04:07:06+00:00\",\"dateModified\":\"2024-09-13T08:31:21+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#breadcrumb\"},\"inLanguage\":\"zh-HK\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2020-17519-apache-flink-directory-traversal-vulnerability\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-HK\",\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#primaryimage\",\"url\":\"https:\\\/\\\/ik.imagekit.io\\\/14sfaswy6hrz\\\/blog-posts\\\/images\\\/clgjszio81g880ks10up19n0l.gif?tr=w-1800,c-at_max\",\"contentUrl\":\"https:\\\/\\\/ik.imagekit.io\\\/14sfaswy6hrz\\\/blog-posts\\\/images\\\/clgjszio81g880ks10up19n0l.gif?tr=w-1800,c-at_max\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.vicarius.io\\\/blog\\\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9801\",\"item\":\"https:\\\/\\\/version-2.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"CVE-2020-17519: Apache Flink Directory Traversal Vulnerability\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#website\",\"url\":\"https:\\\/\\\/version-2.com\\\/zh\\\/\",\"name\":\"Version 2\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/version-2.com\\\/zh\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"zh-HK\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#organization\",\"name\":\"Version 2\",\"url\":\"https:\\\/\\\/version-2.com\\\/zh\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-HK\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/version-2.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/version-2.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1\",\"width\":1795,\"height\":335,\"caption\":\"Version 2\"},\"image\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/person\\\/103ffe36f7fd34a1cc126a30431b94d8\",\"name\":\"versionpan\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-HK\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g\",\"caption\":\"versionpan\"},\"url\":\"https:\\\/\\\/version-2.com\\\/zh\\\/author\\\/versionpan\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"CVE-2020-17519: Apache Flink Directory Traversal Vulnerability - Version 2","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.vicarius.io\/blog\/cve-2020-17519-apache-flink-directory-traversal-vulnerability","og_locale":"zh_HK","og_type":"article","og_title":"CVE-2020-17519: Apache Flink Directory Traversal Vulnerability - Version 2","og_description":"Introduction Directory Traversal in Apache Flink versio [&hellip;]","og_url":"https:\/\/www.vicarius.io\/blog\/cve-2020-17519-apache-flink-directory-traversal-vulnerability","og_site_name":"Version 2","article_published_time":"2023-04-17T04:07:06+00:00","article_modified_time":"2024-09-13T08:31:21+00:00","og_image":[{"url":"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjszio81g880ks10up19n0l.gif?tr=w-1800,c-at_max","type":"","width":"","height":""}],"author":"versionpan","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"versionpan","\u9810\u8a08\u95b1\u8b80\u6642\u9593":"20 \u5206\u9418"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.vicarius.io\/blog\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#article","isPartOf":{"@id":"https:\/\/version-2.com\/2023\/04\/cve-2020-17519-apache-flink-directory-traversal-vulnerability\/"},"author":{"name":"versionpan","@id":"https:\/\/version-2.com\/zh\/#\/schema\/person\/103ffe36f7fd34a1cc126a30431b94d8"},"headline":"CVE-2020-17519: Apache Flink Directory Traversal Vulnerability","datePublished":"2023-04-17T04:07:06+00:00","dateModified":"2024-09-13T08:31:21+00:00","mainEntityOfPage":{"@id":"https:\/\/version-2.com\/2023\/04\/cve-2020-17519-apache-flink-directory-traversal-vulnerability\/"},"wordCount":2658,"commentCount":0,"publisher":{"@id":"https:\/\/version-2.com\/zh\/#organization"},"image":{"@id":"https:\/\/www.vicarius.io\/blog\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#primaryimage"},"thumbnailUrl":"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjszio81g880ks10up19n0l.gif?tr=w-1800,c-at_max","keywords":["vRx","2023"],"articleSection":["vRx","2023","Press Release"],"inLanguage":"zh-HK","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.vicarius.io\/blog\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#respond"]}]},{"@type":"WebPage","@id":"https:\/\/version-2.com\/2023\/04\/cve-2020-17519-apache-flink-directory-traversal-vulnerability\/","url":"https:\/\/www.vicarius.io\/blog\/cve-2020-17519-apache-flink-directory-traversal-vulnerability","name":"CVE-2020-17519: Apache Flink Directory Traversal Vulnerability - Version 2","isPartOf":{"@id":"https:\/\/version-2.com\/zh\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.vicarius.io\/blog\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#primaryimage"},"image":{"@id":"https:\/\/www.vicarius.io\/blog\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#primaryimage"},"thumbnailUrl":"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjszio81g880ks10up19n0l.gif?tr=w-1800,c-at_max","datePublished":"2023-04-17T04:07:06+00:00","dateModified":"2024-09-13T08:31:21+00:00","breadcrumb":{"@id":"https:\/\/www.vicarius.io\/blog\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#breadcrumb"},"inLanguage":"zh-HK","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.vicarius.io\/blog\/cve-2020-17519-apache-flink-directory-traversal-vulnerability"]}]},{"@type":"ImageObject","inLanguage":"zh-HK","@id":"https:\/\/www.vicarius.io\/blog\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#primaryimage","url":"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjszio81g880ks10up19n0l.gif?tr=w-1800,c-at_max","contentUrl":"https:\/\/ik.imagekit.io\/14sfaswy6hrz\/blog-posts\/images\/clgjszio81g880ks10up19n0l.gif?tr=w-1800,c-at_max"},{"@type":"BreadcrumbList","@id":"https:\/\/www.vicarius.io\/blog\/cve-2020-17519-apache-flink-directory-traversal-vulnerability#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9801","item":"https:\/\/version-2.com\/"},{"@type":"ListItem","position":2,"name":"CVE-2020-17519: Apache Flink Directory Traversal Vulnerability"}]},{"@type":"WebSite","@id":"https:\/\/version-2.com\/zh\/#website","url":"https:\/\/version-2.com\/zh\/","name":"Version 2","description":"","publisher":{"@id":"https:\/\/version-2.com\/zh\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/version-2.com\/zh\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"zh-HK"},{"@type":"Organization","@id":"https:\/\/version-2.com\/zh\/#organization","name":"Version 2","url":"https:\/\/version-2.com\/zh\/","logo":{"@type":"ImageObject","inLanguage":"zh-HK","@id":"https:\/\/version-2.com\/zh\/#\/schema\/logo\/image\/","url":"https:\/\/i0.wp.com\/version-2.com\/wp-content\/uploads\/2020\/08\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1","contentUrl":"https:\/\/i0.wp.com\/version-2.com\/wp-content\/uploads\/2020\/08\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1","width":1795,"height":335,"caption":"Version 2"},"image":{"@id":"https:\/\/version-2.com\/zh\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/version-2.com\/zh\/#\/schema\/person\/103ffe36f7fd34a1cc126a30431b94d8","name":"versionpan","image":{"@type":"ImageObject","inLanguage":"zh-HK","@id":"https:\/\/secure.gravatar.com\/avatar\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g","caption":"versionpan"},"url":"https:\/\/version-2.com\/zh\/author\/versionpan\/"}]}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pbQRKm-h7b","post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts\/65793","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/users\/148637484"}],"replies":[{"embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/comments?post=65793"}],"version-history":[{"count":6,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts\/65793\/revisions"}],"predecessor-version":[{"id":69388,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts\/65793\/revisions\/69388"}],"wp:attachment":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/media?parent=65793"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/categories?post=65793"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/tags?post=65793"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}