提交 b21c6503 authored 作者: Thomas Mueller's avatar Thomas Mueller

If baseDir is set, and a database name is given which points to a directory…

If baseDir is set, and a database name is given which points to a directory above (eg. "../dbname"), an exception is thrown.
上级 b0206a3b
...@@ -960,8 +960,9 @@ the TCP server, or the PG server. Remote access can be enabled using the command ...@@ -960,8 +960,9 @@ the TCP server, or the PG server. Remote access can be enabled using the command
options <code>-webAllowOthers, -tcpAllowOthers, -pgAllowOthers</code>. options <code>-webAllowOthers, -tcpAllowOthers, -pgAllowOthers</code>.
If you enable remote access, please also consider using the options If you enable remote access, please also consider using the options
<code>-baseDir, -ifExists</code>, so that remote <code>-baseDir, -ifExists</code>, so that remote
users can not create new databases or access existing databases with weak passwords. Also, users can not create new databases or access existing databases with weak passwords.
ensure the existing accessible databases are protected using a strong password. When using the option <code>-baseDir</code>, only databases within that directory may be accessed.
Ensure the existing accessible databases are protected using strong passwords.
</p> </p>
<h2 id="restricting_classes">Restricting Class Loading and Usage</h2> <h2 id="restricting_classes">Restricting Class Loading and Usage</h2>
......
...@@ -25,8 +25,8 @@ Change Log ...@@ -25,8 +25,8 @@ Change Log
</li><li>The functions isBeforeFirst() and isAfterLast() were not compliant to the </li><li>The functions isBeforeFirst() and isAfterLast() were not compliant to the
JDBC spec. If the ResultSet contains no rows, they must return false. Fixed. JDBC spec. If the ResultSet contains no rows, they must return false. Fixed.
</li><li>Filesystem parameters like "split:" didn't work in server mode with baseDir set. </li><li>Filesystem parameters like "split:" didn't work in server mode with baseDir set.
</li><li>If baseDir is set, and a database name is given which points to a directory above </li><li>If baseDir is set, and a database name is given which points to a directory outside
(eg. "../dbname"), an exception is thrown. the baseDir (eg. "../dbname"), an exception is thrown.
</li></ul> </li></ul>
<h2>Version 1.2.133 (2010-04-10)</h2> <h2>Version 1.2.133 (2010-04-10)</h2>
......
...@@ -134,23 +134,24 @@ public class ConnectionInfo implements Cloneable { ...@@ -134,23 +134,24 @@ public class ConnectionInfo implements Cloneable {
if (persistent) { if (persistent) {
String fileSystemPrefix = ""; String fileSystemPrefix = "";
int colonIndex = name.lastIndexOf(':'); int colonIndex = name.lastIndexOf(':');
if (colonIndex != -1) { if (colonIndex > 1) {
// cut "split:" and similar things // cut FileSystem prefixes, but not
// C: and D: (Microsoft Windows drive letters)
fileSystemPrefix = name.substring(0, colonIndex+1); fileSystemPrefix = name.substring(0, colonIndex+1);
name = name.substring(colonIndex+1); name = name.substring(colonIndex+1);
} }
String testDbFilename; String testFileName;
if (name.startsWith("~")) { if (name.startsWith("~")) {
testDbFilename = System.getProperty("user.home") + SysProperties.FILE_SEPARATOR + name.substring(1); testFileName = System.getProperty("user.home") + SysProperties.FILE_SEPARATOR + name.substring(1);
} else { } else {
testDbFilename = dir + SysProperties.FILE_SEPARATOR + name; testFileName = dir + SysProperties.FILE_SEPARATOR + name;
} }
File dbFile = new File(testDbFilename); File testFile = new File(testFileName);
File baseDirFile = new File(dir); File baseDir = new File(dir);
if (!Utils.isInDir(dbFile, baseDirFile)) { if (!IOUtils.isInDir(testFile, baseDir)) {
throw DbException.get(ErrorCode.IO_EXCEPTION_1, dbFile.getAbsolutePath() + " outside " + throw DbException.get(ErrorCode.IO_EXCEPTION_1, testFile.getAbsolutePath() + " outside " +
baseDirFile.getAbsolutePath()); baseDir.getAbsolutePath());
} }
if (name.startsWith("~")) { if (name.startsWith("~")) {
name = fileSystemPrefix + name; name = fileSystemPrefix + name;
......
...@@ -398,7 +398,7 @@ public class FileSystemDisk extends FileSystem { ...@@ -398,7 +398,7 @@ public class FileSystemDisk extends FileSystem {
public InputStream openFileInputStream(String fileName) throws IOException { public InputStream openFileInputStream(String fileName) throws IOException {
if (fileName.indexOf(':') > 1) { if (fileName.indexOf(':') > 1) {
// if the : is in position 1, a windows file access is assumed: C:.. or D: // if the : is in position 1, a windows file access is assumed: C:.. or D:
// otherwise a URL is assumed // otherwise an URL is assumed
URL url = new URL(fileName); URL url = new URL(fileName);
InputStream in = url.openStream(); InputStream in = url.openStream();
return in; return in;
......
...@@ -691,4 +691,25 @@ public class IOUtils { ...@@ -691,4 +691,25 @@ public class IOUtils {
} }
} }
/**
* Checks if a file is below a given directory
*
* @param file the file to check
* @param dir the directory the file must be in
* @return true if the file is within the directory
*/
public static boolean isInDir(File file, File dir) {
try {
String canonicalFileName = file.getCanonicalPath();
String canonicalDirName = dir.getCanonicalPath();
if (canonicalFileName.equals(canonicalDirName)) {
// the file is the directory: not allowed (file "../test" in dir "test")
return false;
}
return canonicalFileName.startsWith(canonicalDirName);
} catch (IOException e) {
return false;
}
}
} }
...@@ -8,7 +8,6 @@ package org.h2.util; ...@@ -8,7 +8,6 @@ package org.h2.util;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
...@@ -531,26 +530,5 @@ public class Utils { ...@@ -531,26 +530,5 @@ public class Utils {
e.printStackTrace(); e.printStackTrace();
} }
} }
/**
* Checks if a file is below a given directory
*
* @param file the file to check
* @param dir the directory the file must be in
* @return true if the file is below the directory
*/
public static boolean isInDir(File file, File dir) {
try {
String canonicalFilename = file.getCanonicalPath();
String canonicalDirname = dir.getCanonicalPath();
if (canonicalFilename.equals(canonicalDirname)) {
// the file is the dir => not allowed (file "../test" in dir "test")
return false;
}
return canonicalFilename.startsWith(canonicalDirname);
} catch (IOException e) {
return false;
}
}
} }
...@@ -673,23 +673,23 @@ public class TestTools extends TestBase { ...@@ -673,23 +673,23 @@ public class TestTools extends TestBase {
// ignore // ignore
} }
// Test filesystem prefix and escape from baseDir // Test filesystem prefix and escape from baseDir
deleteDb("testsplit"); deleteDb("testSplit");
server = Server.createTcpServer( server = Server.createTcpServer(
"-baseDir", baseDir, "-baseDir", baseDir,
"-tcpPort", "9192", "-tcpPort", "9192",
"-tcpAllowOthers").start(); "-tcpAllowOthers").start();
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9192/split:testsplit", "sa", ""); conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9192/split:testSplit", "sa", "");
conn.close(); conn.close();
try { try {
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9192/../test", "sa", ""); conn = DriverManager.getConnection("jdbc:h2:tcp://localhost:9192/../test", "sa", "");
fail("Should throw an exception!"); fail("Should throw an exception!");
} catch (Throwable e) { } catch (Throwable e) {
// Expected // Expected
} }
server.stop(); server.stop();
deleteDb("testsplit"); deleteDb("testSplit");
} }
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论