نسخة آمنة من Path.Combine
-
03-07-2019 - |
سؤال
ولدي rootPath
أنني على ثقة وrelativePath
أنني لا. أريد أن الجمع بينهما في مثل هذه الطريقة التي يمكنني التأكد من أن النتيجة هي تحت rootPath
والتي لا يمكن للمستخدم استخدام ..
أن نعود الماضي نقطة البداية. I <م> لا م> تريد المسار النسبي للسماح للأشياء مثل: hello\..\world
== world
المحلول
لتوسيع: استخدام Path.Combine، ثم استدعاء GetFullPath على النتيجة والتحقق من أن تلك النتيجة تبدأ rootPath
وانها لن حمايتك ضد hardlinks، ولكن يجب أن يمسك الأشياء البسيطة مثل مزدوجة النقاط.
ما سبق كرمز:
string Resolve(string fileName)
{
string root = FileRoot();
string ret = Path.GetFullPath(Path.Combine(root, fileName));
if (ret.StartsWith(root.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar)) return ret;
throw new ArgumentException("path resolved to out of accesable directroy");
}
نصائح أخرى
هل يمكن أن مجرد دعوة Path.GetFullPath()
ومعرفة ما اذا كان يبدأ مع rootPath
الموثوق بها. إذا كنت تميل إلى جنون العظمة، وتحقق أيضا متجذر أن rootPath
.
public Boolean IsPathSafe(String rootPath, String relativePath)
{
return rootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) &&
Path.IsPathRooted(rootPath) &&
Patch.Combine(rootPath, relativePath).GetFullPath().StartsWith(rootPath);
}
للحصول على شرح لأول اختبار نرى تعليق أليكس مارتيلي على الجواب technophile ل.
وشيء واحد يمكنك القيام به هو لحساب عدد من الخطوط المائلة العكسية (\
) والنقاط المزدوجة (..
)، وتأكد من أن عدد مزدوج النقاط أصغر من عدد من الخطوط المائلة العكسية. لكي تذهب فوق rootPath
في بنية المجلد الخاص بك، ستحتاج على الأقل يصل الى الخطوط المائلة العكسية كنقاط مزدوجة - وبالتالي، إذا سمحت فقط relativePath
s مع واحد على الأقل مائل، يجب أن تكون آمنة