/// <summary> /// Validates whether a <see cref="LocalFileSystemProvider"/> was configured /// with access restricted to a given <see cref="LocalFileSystemProvider.RootDirectory"/>, /// and makes sure that the requested <paramref name="resource"/> is indeed contained /// within that folder. /// </summary> /// <param name="resource">The requested resource.</param> /// <exception cref="ResourceAccessException">If the requested resource is not /// a descendant of a configured <see cref="LocalFileSystemProvider.RootDirectory"/>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="resource"/> /// is a null reference.</exception> private void ValidateResourceAccess(VirtualResourceInfo resource) { if (resource == null) { throw new ArgumentNullException("resource"); } //if there isn't a restricted custom root, every file resource can be accessed //(if the path is invalid, this will fail later, depending on the action) if (RootDirectory == null) { return; } try { string path = PathUtil.GetAbsolutePath(resource.FullName, RootDirectory); //if the root path was submitted, we're within the scope, too if (IsRootPath(path)) { return; } //if we have a custom root, make sure the resource is indeed a descendant of the root if (RootDirectory.IsParentOf(path)) { return; } } catch (ResourceAccessException e) { //just bubble a resource access exception if (e.Resource == null) { e.Resource = resource; } throw; } catch (Exception e) { //exceptions can happen in case of invalid file paths //log detailed info string error = "Resource request for '{0}' caused exception when validating against root directory '{1}'."; error = String.Format(error, resource.FullName, RootDirectory.FullName); VfsLog.Debug(e, error); //do not expose too much path information (e.g. absolute paths if disabled) error = String.Format("Invalid resource path: '{0}'.", resource.FullName); throw new ResourceAccessException(error) { Resource = resource }; } //if none of the above is true, the request is invalid //log detailed info string msg = "Resource request for '{0}' was blocked. The resource is outside the root directory '{1}'."; msg = String.Format(msg, resource.FullName, RootDirectory.FullName); VfsLog.Debug(msg); //do not expose too much path information (e.g. absolute paths if disabled) msg = String.Format("Invalid resource path: '{0}'.", resource.FullName); throw new ResourceAccessException(msg) { Resource = resource }; }