[camel] branch camel-2.21.x updated (7cf3a5e -> c7b772c)

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[camel] branch camel-2.21.x updated (7cf3a5e -> c7b772c)

davsclaus-2
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a change to branch camel-2.21.x
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from 7cf3a5e  [CAMEL-12980] Interact with Karaf's BundleStateService about Blueprint Camel Context problems
     new 5e1d70c  CAMEL-13042: File producer should by default only allow to write file… (#2700)
     new f337a98  CAMEL-13042: Polished
     new c7b772c  CAMEL-13042: Regen docs

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 camel-core/src/main/docs/file-component.adoc       |  3 +-
 .../camel/component/file/GenericFileEndpoint.java  | 15 ++++++
 .../camel/component/file/GenericFileProducer.java  | 11 ++++-
 .../component/file/FileProducerExpressionTest.java |  2 +-
 .../FileProducerJailStartingDirectoryTest.java}    | 57 ++++++++++------------
 .../camel-ftp/src/main/docs/ftp-component.adoc     |  3 +-
 .../camel-ftp/src/main/docs/ftps-component.adoc    |  3 +-
 .../camel-ftp/src/main/docs/sftp-component.adoc    |  3 +-
 .../file/remote/FtpProducerExpressionTest.java     |  2 +-
 .../FtpProducerJailStartingDirectoryTest.java}     | 45 ++++++++---------
 10 files changed, 83 insertions(+), 61 deletions(-)
 copy camel-core/src/test/java/org/apache/camel/{processor/EvaluateExpressionProcessorTest.java => component/file/FileProducerJailStartingDirectoryTest.java} (57%)
 copy components/{camel-ibatis/src/test/java/org/apache/camel/component/ibatis/IBatisQueryForDeleteTest.java => camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerJailStartingDirectoryTest.java} (56%)

Reply | Threaded
Open this post in threaded view
|

[camel] 01/03: CAMEL-13042: File producer should by default only allow to write file… (#2700)

davsclaus-2
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch camel-2.21.x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 5e1d70c6957703cdebbfe5d796462e5a89c8bc26
Author: Claus Ibsen <[hidden email]>
AuthorDate: Wed Jan 9 10:37:33 2019 +0100

    CAMEL-13042: File producer should by default only allow to write file… (#2700)
   
    * CAMEL-13042: File producer should by default only allow to write files in the starting directory (or subs). Added new option to turn this on|off.
   
    * CAMEL-13042: Regen docs
   
    * CAMEL-13042: Polished
---
 .../camel/component/file/GenericFileEndpoint.java  | 15 +++++
 .../camel/component/file/GenericFileProducer.java  | 12 +++-
 .../component/file/FileProducerExpressionTest.java |  2 +-
 .../FileProducerJailStartingDirectoryTest.java     | 73 ++++++++++++++++++++++
 .../file/remote/FtpProducerExpressionTest.java     |  2 +-
 .../FtpProducerJailStartingDirectoryTest.java      | 68 ++++++++++++++++++++
 6 files changed, 169 insertions(+), 3 deletions(-)

diff --git a/camel-core/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java b/camel-core/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java
index def2f60..dc96ece 100644
--- a/camel-core/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java
+++ b/camel-core/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java
@@ -91,6 +91,8 @@ public abstract class GenericFileEndpoint<T> extends ScheduledPollEndpoint imple
     protected boolean keepLastModified;
     @UriParam(label = "producer,advanced")
     protected boolean allowNullBody;
+    @UriParam(label = "producer", defaultValue = "true")
+    protected boolean jailStartingDirectory = true;
 
     // consumer options
 
@@ -1178,6 +1180,19 @@ public abstract class GenericFileEndpoint<T> extends ScheduledPollEndpoint imple
         this.allowNullBody = allowNullBody;
     }
 
+    public boolean isJailStartingDirectory() {
+        return jailStartingDirectory;
+    }
+
+    /**
+     * Used for jailing (restricting) writing files to the starting directory (and sub) only.
+     * This is enabled by default to not allow Camel to write files to outside directories (to be more secured out of the box).
+     * You can turn this off to allow writing files to directories outside the starting directory, such as parent or root folders.
+     */
+    public void setJailStartingDirectory(boolean jailStartingDirectory) {
+        this.jailStartingDirectory = jailStartingDirectory;
+    }
+
     public ExceptionHandler getOnCompletionExceptionHandler() {
         return onCompletionExceptionHandler;
     }
diff --git a/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java b/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java
index 2dec738..7cd2b66 100644
--- a/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java
+++ b/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java
@@ -20,6 +20,7 @@ import java.io.File;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
+import org.apache.camel.CamelExchangeException;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.impl.DefaultExchange;
@@ -331,7 +332,7 @@ public class GenericFileProducer<T> extends DefaultProducer {
             exchange.getIn().setHeader(Exchange.FILE_NAME, value);
         }
 
-        if (value != null && value instanceof String && StringHelper.hasStartToken((String) value, "simple")) {
+        if (value instanceof String && StringHelper.hasStartToken((String) value, "simple")) {
             log.warn("Simple expression: {} detected in header: {} of type String. This feature has been removed (see CAMEL-6748).", value, Exchange.FILE_NAME);
         }
 
@@ -378,6 +379,15 @@ public class GenericFileProducer<T> extends DefaultProducer {
             answer = baseDir + endpoint.getGeneratedFileName(exchange.getIn());
         }
 
+        if (endpoint.isJailStartingDirectory()) {
+            // check for file must be within starting directory (need to compact first as the name can be using relative paths via ../ etc)
+            String compatchAnswer = FileUtil.compactPath(answer);
+            String compatchBaseDir = FileUtil.compactPath(baseDir);
+            if (!compatchAnswer.startsWith(compatchBaseDir)) {
+                throw new IllegalArgumentException("Cannot write file with name: " + compatchAnswer + " as the filename is jailed to the starting directory: " + compatchBaseDir);
+            }
+        }
+
         if (endpoint.getConfiguration().needToNormalize()) {
             // must normalize path to cater for Windows and other OS
             answer = normalizePath(answer);
diff --git a/camel-core/src/test/java/org/apache/camel/component/file/FileProducerExpressionTest.java b/camel-core/src/test/java/org/apache/camel/component/file/FileProducerExpressionTest.java
index ac7b8d7..b56f419 100644
--- a/camel-core/src/test/java/org/apache/camel/component/file/FileProducerExpressionTest.java
+++ b/camel-core/src/test/java/org/apache/camel/component/file/FileProducerExpressionTest.java
@@ -74,7 +74,7 @@ public class FileProducerExpressionTest extends ContextTestSupport {
 
     public void testProducerComplexByExpression() throws Exception {
         String expression = "../filelanguageinbox/myfile-${bean:myguidgenerator.guid}-${date:now:yyyyMMdd}.txt";
-        template.sendBody("file://target/filelanguage?fileName=" + expression, "Hello World");
+        template.sendBody("file://target/filelanguage?jailStartingDirectory=false&fileName=" + expression, "Hello World");
 
         String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
         assertFileExists("target/filelanguageinbox/myfile-123-" + date + ".txt");
diff --git a/camel-core/src/test/java/org/apache/camel/component/file/FileProducerJailStartingDirectoryTest.java b/camel-core/src/test/java/org/apache/camel/component/file/FileProducerJailStartingDirectoryTest.java
new file mode 100644
index 0000000..becbf18
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/component/file/FileProducerJailStartingDirectoryTest.java
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Before;
+import org.junit.Test;
+
+public class FileProducerJailStartingDirectoryTest extends ContextTestSupport {
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        deleteDirectory("target/jail");
+        super.setUp();
+    }
+
+    @Test
+    public void testWriteOutsideStartingDirectory() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(0);
+
+        try {
+            template.sendBodyAndHeader("direct:start", "Hello World", Exchange.FILE_NAME, "hello.txt");
+            fail("Should have thrown exception");
+        } catch (Exception e) {
+            IllegalArgumentException iae = assertIsInstanceOf(IllegalArgumentException.class, e.getCause());
+            assertTrue(iae.getMessage().contains("as the filename is jailed to the starting directory"));
+        }
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testWriteInsideStartingDirectory() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+
+        template.sendBodyAndHeader("direct:start", "Bye World", Exchange.FILE_NAME, "outbox/bye.txt");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .setHeader(Exchange.FILE_NAME, simple("../${file:name}"))
+                    .to("file:target/jail/outbox")
+                    .to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerExpressionTest.java b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerExpressionTest.java
index 435a1b4..06b8b38 100644
--- a/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerExpressionTest.java
+++ b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerExpressionTest.java
@@ -85,7 +85,7 @@ public class FtpProducerExpressionTest extends FtpServerTestSupport {
     @Test
     public void testProducerComplexByExpression() throws Exception {
         // need one extra subdirectory (=foo) to be able to start with .. in the fileName option
-        String url = "ftp://admin@localhost:" + getPort() + "/filelanguage/foo?password=admin";
+        String url = "ftp://admin@localhost:" + getPort() + "/filelanguage/foo?password=admin&jailStartingDirectory=false";
         
         String expression = "../filelanguageinbox/myfile-${bean:myguidgenerator.guid}-${date:now:yyyyMMdd}.txt";
         template.sendBody(url + "&fileName=" + expression, "Hello World");
diff --git a/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerJailStartingDirectoryTest.java b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerJailStartingDirectoryTest.java
new file mode 100644
index 0000000..7cb677a
--- /dev/null
+++ b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerJailStartingDirectoryTest.java
@@ -0,0 +1,68 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Test;
+
+public class FtpProducerJailStartingDirectoryTest extends FtpServerTestSupport {
+
+    private String getFtpUrl() {
+        return "ftp://admin@localhost:" + getPort() + "/upload/jail?binary=false&password=admin&tempPrefix=.uploading";
+    }
+
+    @Test
+    public void testWriteOutsideStartingDirectory() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(0);
+
+        try {
+            template.sendBodyAndHeader("direct:start", "Hello World", Exchange.FILE_NAME, "hello.txt");
+            fail("Should have thrown exception");
+        } catch (Exception e) {
+            IllegalArgumentException iae = assertIsInstanceOf(IllegalArgumentException.class, e.getCause());
+            assertTrue(iae.getMessage().contains("as the filename is jailed to the starting directory"));
+        }
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testWriteInsideStartingDirectory() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+
+        template.sendBodyAndHeader("direct:start", "Bye World", Exchange.FILE_NAME, "jail/bye.txt");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .setHeader(Exchange.FILE_NAME, simple("../${file:name}"))
+                    .to(getFtpUrl())
+                    .to("mock:result");
+            }
+        };
+    }
+}
\ No newline at end of file

Reply | Threaded
Open this post in threaded view
|

[camel] 02/03: CAMEL-13042: Polished

davsclaus-2
In reply to this post by davsclaus-2
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch camel-2.21.x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit f337a98e86ef18611b14570e6780053fe3ddcc02
Author: Claus Ibsen <[hidden email]>
AuthorDate: Wed Jan 9 10:41:12 2019 +0100

    CAMEL-13042: Polished
---
 .../main/java/org/apache/camel/component/file/GenericFileProducer.java   | 1 -
 1 file changed, 1 deletion(-)

diff --git a/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java b/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java
index 7cd2b66..c22cf5e 100644
--- a/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java
+++ b/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java
@@ -20,7 +20,6 @@ import java.io.File;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
-import org.apache.camel.CamelExchangeException;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.impl.DefaultExchange;

Reply | Threaded
Open this post in threaded view
|

[camel] 03/03: CAMEL-13042: Regen docs

davsclaus-2
In reply to this post by davsclaus-2
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch camel-2.21.x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit c7b772c8b5d759a0f04a2f21b97f0e09509bfbff
Author: Claus Ibsen <[hidden email]>
AuthorDate: Fri Jan 11 11:33:42 2019 +0100

    CAMEL-13042: Regen docs
---
 camel-core/src/main/docs/file-component.adoc           | 3 ++-
 components/camel-ftp/src/main/docs/ftp-component.adoc  | 3 ++-
 components/camel-ftp/src/main/docs/ftps-component.adoc | 3 ++-
 components/camel-ftp/src/main/docs/sftp-component.adoc | 3 ++-
 4 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/camel-core/src/main/docs/file-component.adoc b/camel-core/src/main/docs/file-component.adoc
index 574ac13..d94026d 100644
--- a/camel-core/src/main/docs/file-component.adoc
+++ b/camel-core/src/main/docs/file-component.adoc
@@ -72,7 +72,7 @@ with the following path and query parameters:
 |===
 
 
-==== Query Parameters (81 parameters):
+==== Query Parameters (82 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -102,6 +102,7 @@ with the following path and query parameters:
 | *startingDirectoryMustExist* (consumer) | Whether the starting directory must exist. Mind that the autoCreate option is default enabled, which means the starting directory is normally auto created if it doesn't exist. You can disable autoCreate and enable this to ensure the starting directory must exist. Will thrown an exception if the directory doesn't exist. | false | boolean
 | *fileExist* (producer) | What to do if a file already exists with the same name. Override, which is the default, replaces the existing file. Append - adds content to the existing file. Fail - throws a GenericFileOperationException, indicating that there is already an existing file. Ignore - silently ignores the problem and does not override the existing file, but assumes everything is okay. Move - option requires to use the moveExisting option to be configured as well. The option eager [...]
 | *flatten* (producer) | Flatten is used to flatten the file name path to strip any leading paths, so it's just the file name. This allows you to consume recursively into sub-directories, but when you eg write the files to another directory they will be written in a single directory. Setting this to true on the producer enforces that any file name in CamelFileName header will be stripped for any leading paths. | false | boolean
+| *jailStartingDirectory* (producer) | Used for jailing (restricting) writing files to the starting directory (and sub) only. This is enabled by default to not allow Camel to write files to outside directories (to be more secured out of the box). You can turn this off to allow writing files to directories outside the starting directory, such as parent or root folders. | true | boolean
 | *moveExisting* (producer) | Expression (such as File Language) used to compute file name to use when fileExist=Move is configured. To move files into a backup subdirectory just enter backup. This option only supports the following File Language tokens: file:name, file:name.ext, file:name.noext, file:onlyname, file:onlyname.noext, file:ext, and file:parent. Notice the file:parent is not supported by the FTP component, as the FTP component can only move any existing files to a relative d [...]
 | *tempFileName* (producer) | The same as tempPrefix option but offering a more fine grained control on the naming of the temporary filename as it uses the File Language. |  | String
 | *tempPrefix* (producer) | This option is used to write the file using a temporary name and then, after the write is complete, rename it to the real name. Can be used to identify files being written and also avoid consumers (not using exclusive read locks) reading in progress files. Is often used by FTP when uploading big files. |  | String
diff --git a/components/camel-ftp/src/main/docs/ftp-component.adoc b/components/camel-ftp/src/main/docs/ftp-component.adoc
index 9821eca..a7ed02d 100644
--- a/components/camel-ftp/src/main/docs/ftp-component.adoc
+++ b/components/camel-ftp/src/main/docs/ftp-component.adoc
@@ -100,7 +100,7 @@ with the following path and query parameters:
 |===
 
 
-==== Query Parameters (108 parameters):
+==== Query Parameters (109 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -143,6 +143,7 @@ with the following path and query parameters:
 | *useList* (consumer) | Whether to allow using LIST command when downloading a file. Default is true. In some use cases you may want to download a specific file and are not allowed to use the LIST command, and therefore you can set this option to false. Notice when using this option, then the specific file to download does not include meta-data information such as file size, timestamp, permissions etc, because those information is only possible to retrieve when LIST command is in use. | [...]
 | *fileExist* (producer) | What to do if a file already exists with the same name. Override, which is the default, replaces the existing file. Append - adds content to the existing file. Fail - throws a GenericFileOperationException, indicating that there is already an existing file. Ignore - silently ignores the problem and does not override the existing file, but assumes everything is okay. Move - option requires to use the moveExisting option to be configured as well. The option eager [...]
 | *flatten* (producer) | Flatten is used to flatten the file name path to strip any leading paths, so it's just the file name. This allows you to consume recursively into sub-directories, but when you eg write the files to another directory they will be written in a single directory. Setting this to true on the producer enforces that any file name in CamelFileName header will be stripped for any leading paths. | false | boolean
+| *jailStartingDirectory* (producer) | Used for jailing (restricting) writing files to the starting directory (and sub) only. This is enabled by default to not allow Camel to write files to outside directories (to be more secured out of the box). You can turn this off to allow writing files to directories outside the starting directory, such as parent or root folders. | true | boolean
 | *moveExisting* (producer) | Expression (such as File Language) used to compute file name to use when fileExist=Move is configured. To move files into a backup subdirectory just enter backup. This option only supports the following File Language tokens: file:name, file:name.ext, file:name.noext, file:onlyname, file:onlyname.noext, file:ext, and file:parent. Notice the file:parent is not supported by the FTP component, as the FTP component can only move any existing files to a relative d [...]
 | *tempFileName* (producer) | The same as tempPrefix option but offering a more fine grained control on the naming of the temporary filename as it uses the File Language. |  | String
 | *tempPrefix* (producer) | This option is used to write the file using a temporary name and then, after the write is complete, rename it to the real name. Can be used to identify files being written and also avoid consumers (not using exclusive read locks) reading in progress files. Is often used by FTP when uploading big files. |  | String
diff --git a/components/camel-ftp/src/main/docs/ftps-component.adoc b/components/camel-ftp/src/main/docs/ftps-component.adoc
index 106fd53..916a6d1 100644
--- a/components/camel-ftp/src/main/docs/ftps-component.adoc
+++ b/components/camel-ftp/src/main/docs/ftps-component.adoc
@@ -60,7 +60,7 @@ with the following path and query parameters:
 |===
 
 
-==== Query Parameters (116 parameters):
+==== Query Parameters (117 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -103,6 +103,7 @@ with the following path and query parameters:
 | *useList* (consumer) | Whether to allow using LIST command when downloading a file. Default is true. In some use cases you may want to download a specific file and are not allowed to use the LIST command, and therefore you can set this option to false. Notice when using this option, then the specific file to download does not include meta-data information such as file size, timestamp, permissions etc, because those information is only possible to retrieve when LIST command is in use. | [...]
 | *fileExist* (producer) | What to do if a file already exists with the same name. Override, which is the default, replaces the existing file. Append - adds content to the existing file. Fail - throws a GenericFileOperationException, indicating that there is already an existing file. Ignore - silently ignores the problem and does not override the existing file, but assumes everything is okay. Move - option requires to use the moveExisting option to be configured as well. The option eager [...]
 | *flatten* (producer) | Flatten is used to flatten the file name path to strip any leading paths, so it's just the file name. This allows you to consume recursively into sub-directories, but when you eg write the files to another directory they will be written in a single directory. Setting this to true on the producer enforces that any file name in CamelFileName header will be stripped for any leading paths. | false | boolean
+| *jailStartingDirectory* (producer) | Used for jailing (restricting) writing files to the starting directory (and sub) only. This is enabled by default to not allow Camel to write files to outside directories (to be more secured out of the box). You can turn this off to allow writing files to directories outside the starting directory, such as parent or root folders. | true | boolean
 | *moveExisting* (producer) | Expression (such as File Language) used to compute file name to use when fileExist=Move is configured. To move files into a backup subdirectory just enter backup. This option only supports the following File Language tokens: file:name, file:name.ext, file:name.noext, file:onlyname, file:onlyname.noext, file:ext, and file:parent. Notice the file:parent is not supported by the FTP component, as the FTP component can only move any existing files to a relative d [...]
 | *tempFileName* (producer) | The same as tempPrefix option but offering a more fine grained control on the naming of the temporary filename as it uses the File Language. |  | String
 | *tempPrefix* (producer) | This option is used to write the file using a temporary name and then, after the write is complete, rename it to the real name. Can be used to identify files being written and also avoid consumers (not using exclusive read locks) reading in progress files. Is often used by FTP when uploading big files. |  | String
diff --git a/components/camel-ftp/src/main/docs/sftp-component.adoc b/components/camel-ftp/src/main/docs/sftp-component.adoc
index 9743837..6deea35 100644
--- a/components/camel-ftp/src/main/docs/sftp-component.adoc
+++ b/components/camel-ftp/src/main/docs/sftp-component.adoc
@@ -51,7 +51,7 @@ with the following path and query parameters:
 |===
 
 
-==== Query Parameters (111 parameters):
+==== Query Parameters (112 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -87,6 +87,7 @@ with the following path and query parameters:
 | *useList* (consumer) | Whether to allow using LIST command when downloading a file. Default is true. In some use cases you may want to download a specific file and are not allowed to use the LIST command, and therefore you can set this option to false. Notice when using this option, then the specific file to download does not include meta-data information such as file size, timestamp, permissions etc, because those information is only possible to retrieve when LIST command is in use. | [...]
 | *fileExist* (producer) | What to do if a file already exists with the same name. Override, which is the default, replaces the existing file. Append - adds content to the existing file. Fail - throws a GenericFileOperationException, indicating that there is already an existing file. Ignore - silently ignores the problem and does not override the existing file, but assumes everything is okay. Move - option requires to use the moveExisting option to be configured as well. The option eager [...]
 | *flatten* (producer) | Flatten is used to flatten the file name path to strip any leading paths, so it's just the file name. This allows you to consume recursively into sub-directories, but when you eg write the files to another directory they will be written in a single directory. Setting this to true on the producer enforces that any file name in CamelFileName header will be stripped for any leading paths. | false | boolean
+| *jailStartingDirectory* (producer) | Used for jailing (restricting) writing files to the starting directory (and sub) only. This is enabled by default to not allow Camel to write files to outside directories (to be more secured out of the box). You can turn this off to allow writing files to directories outside the starting directory, such as parent or root folders. | true | boolean
 | *moveExisting* (producer) | Expression (such as File Language) used to compute file name to use when fileExist=Move is configured. To move files into a backup subdirectory just enter backup. This option only supports the following File Language tokens: file:name, file:name.ext, file:name.noext, file:onlyname, file:onlyname.noext, file:ext, and file:parent. Notice the file:parent is not supported by the FTP component, as the FTP component can only move any existing files to a relative d [...]
 | *tempFileName* (producer) | The same as tempPrefix option but offering a more fine grained control on the naming of the temporary filename as it uses the File Language. |  | String
 | *tempPrefix* (producer) | This option is used to write the file using a temporary name and then, after the write is complete, rename it to the real name. Can be used to identify files being written and also avoid consumers (not using exclusive read locks) reading in progress files. Is often used by FTP when uploading big files. |  | String