namespace bs = boost::system;
namespace bpo = boost::program_options;
+namespace {
+
+bool IsPathTraversal(const std::string& path) {
+ if (path.size() == 0)
+ return true;
+
+ if (path.find("..", 0) != std::string::npos) {
+ LOG(ERROR) << "Invalid path : " << path;
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace
+
namespace res_handler {
ParamChecker::ParamChecker(int argc, char* argv[]) {
if (!ValidatePkgID())
return false;
- if (req_type_ != ReqType::REQ_TYPE_UNINSTALL) {
- if (path_info_list_.size() == 0) {
- LOG(ERROR) << "Path is not given";
- return false;
- }
- }
+ if (!ValidatePathList())
+ return false;
return true;
}
return true;
}
+bool ParamChecker::ValidatePathList() {
+ if (req_type_ != ReqType::REQ_TYPE_UNINSTALL) {
+ if (path_info_list_.size() == 0) {
+ LOG(ERROR) << "Path is not given";
+ return false;
+ }
+ }
+
+ for (auto& path_info : path_info_list_) {
+ if (!IsPathTraversal(path_info.GetSrcPath()) ||
+ !IsPathTraversal(path_info.GetDstPath()))
+ return false;
+ }
+
+ return true;
+}
+
} // namespace res_handler
virtual ~ParamCheckerTest() {}
virtual void SetUp() {
- EXPECT_CALL(GetMock<PkgMgrInfoMock>(), pkgmgrinfo_pkginfo_get_usr_pkginfo(_, _, _))
+ EXPECT_CALL(GetMock<PkgMgrInfoMock>(),
+ pkgmgrinfo_pkginfo_get_usr_pkginfo(_, _, _))
.WillRepeatedly(Return(0));
- EXPECT_CALL(GetMock<PkgMgrInfoMock>(), pkgmgrinfo_pkginfo_destroy_pkginfo(_))
- .WillRepeatedly(Return(0)) ;
+ EXPECT_CALL(GetMock<PkgMgrInfoMock>(),
+ pkgmgrinfo_pkginfo_destroy_pkginfo(_))
+ .WillRepeatedly(Return(0)) ;
}
virtual void TearDown() {}
};
}
TEST_F(ParamCheckerTest, CopyRes) {
- const char *argv[] = { "/bin/res-copy", "--uid", "5001", "-p", "srcpath", "dstpath",
- "--copy", "org.test.targetpkgid", nullptr};
+ const char *argv[] = { "/bin/res-copy", "--uid", "5001",
+ "-p", "srcpath", "dstpath", "--copy", "org.test.targetpkgid", nullptr};
ParamChecker checker(8, (char**)argv);
ParamChecker checker(5, (char**)argv);
EXPECT_EQ(checker.Validate(), true);
- EXPECT_EQ(checker.GetRequestType(), res_handler::ReqType::REQ_TYPE_UNINSTALL);
+ EXPECT_EQ(checker.GetRequestType(),
+ res_handler::ReqType::REQ_TYPE_UNINSTALL);
EXPECT_EQ(checker.GetPkgID(), "org.test.targetpkgid");
EXPECT_EQ(checker.GetPathList().size(), 0);
EXPECT_EQ(checker.GetUID(), 5001);
EXPECT_EQ(checker.Validate(), false);
}
+
+TEST_F(ParamCheckerTest, CopyRes_SrcPathTraverseAttack) {
+ const char *argv[] = { "/bin/res-copy", "--uid",
+ "5001", "-p", "data/../../attackpath", "dstpath",
+ "--copy", "org.test.targetpkgid", nullptr};
+
+ ParamChecker checker(8, (char**)argv);
+
+ EXPECT_FALSE(checker.Validate());
+}
+
+TEST_F(ParamCheckerTest, CopyRes_DstPathTraverseAttack) {
+ const char *argv[] = { "/bin/res-copy", "--uid",
+ "5001", "-p", "data/normal_path", "../../attackpath",
+ "--copy", "org.test.targetpkgid", nullptr};
+
+ ParamChecker checker(8, (char**)argv);
+
+ EXPECT_FALSE(checker.Validate());
+}
+
+TEST_F(ParamCheckerTest, RemoveRes_PathTraverseAttack) {
+ const char *argv[] = { "/bin/res-copy", "--uid",
+ "5001", "-p", "../../../attackpath", "",
+ "--remove", "org.test.targetpkgid", nullptr};
+
+ ParamChecker checker(8, (char**)argv);
+
+ EXPECT_FALSE(checker.Validate());
+}