Delete file security issue in asp.net - asp.net

I use fileUpload control and i can save the image but when i try to delete it gives a security error like this :
Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
it works in my localhost but not in web.
I tried to add many kind of stuff to web config file but it didnt work i dont know why.
Why i can save file but cant delete. It might be about System.Security.Permissions.FileIOPermission maybe... here is my code :
protected void btnDelete_Click(object sender, EventArgs e)
{
try
{
if (!String.IsNullOrEmpty(imgLogo.ImageUrl))
{
int index = imgLogo.ImageUrl.LastIndexOf('.');
string fileExt = imgLogo.ImageUrl.Substring(index);
string defPath = Business.DefinitionsData.getDefaultLogoPath();
string entId = ((xOrgProject.DataAccess.EnterpriseUserTable)Session["Enterprise"]).EnterpriseUserId.ToString();
string FullPath = Server.MapPath(defPath) + entId + fileExt;
FileInfo file = new FileInfo(FullPath);
if (file.Exists)
{
file.GetAccessControl();
file.Delete();
Business.DefinitionsData.UpdateEntLogoPath(int.Parse(entId), null);
imgLogo.ImageUrl = null;
imgLogo.Visible = false;
btnDelete.Visible = false;
btnUpload.Visible = true;
Fu1.Enabled = true;
StatusLabel.Text = "Kaldırıldı.";
}
}
}
catch (Exception ex)
{ StatusLabel.Text = ex.Message; }
}

As it runs fine locally the issue is most likely due to the configuration on the web server. Or in my experience this has often been the case.
Have you tried modifying the trust level in the machine.config file on the web server?
Also what authentication are you using on the web server?
Running it locaally you will have access to your machine but if you are using impersonation on the web server that anonymous account ID may not have the relevant server permissions to delete files which will throw a security exception.

thank you for your answer, i got my solution. I have wrote this code in uploading button click event then its solved. I wasnt disposing before. but now its good. thanks again.
System.Drawing.Image img = System.Drawing.Image.FromFile(save);
img.Dispose();

Related

copy images from local machine to server in asp.net C#

I need to copy the images from C:/images folder to my web application folder which is running in the server.I used the following code which work well in local application but not work in server
string sourcePath = #"D:\images";
//string destinationPath = #"D:\a";
string destinationPath = Server.MapPath("SMSImages") + "\\";
if (System.IO.Directory.Exists(sourcePath))
{
string[] files = System.IO.Directory.GetFiles(sourcePath);
foreach (string s in files)
{
fileName = Path.GetFileName(s);
destFile = Path.Combine(destinationPath, fileName);
File.Copy(s, destFile, true);
}
how to copy
Servers often have a lot of security limitations for the IIS user.
Check if the user under which you are running your asp.net process has authorization to access this path.
You can log the exceptions that are occurring in this code to see if it is causing an access violation.
The following code can help you check if code if you have access
UserFileAccessRights rights = new UserFileAccessRights(sourcePath);
if (rights.canWrite() && rights.canRead()) {
lblLogMsg.Text = "R/W access";
} else {
if (rights.canWrite()) {
lblLogMsg.Text = "Only Write access";
} else if (rights.canRead()) {
lblLogMsg.Text = "Only Read access";
} else {
lblLogMsg.Text = rights.ToString();
}
}
It doesn't work because the program search a D:\ path in server not in local system.

Preventing asp.net pages from executing in a sub-folder

I have a dotnet site which contains a virtual directory (/ArticleImages) which maps to a file share on another server. The file share is accessible to a large number of people so, as a security measure, I do not want any asp.net pages to execute in this folder (e.g. putting default.aspx in the file share and browsing to site.com/ArticleImages/default.aspx should either not serve or, preferably, serve as a simple download rather than executing).
I'm using IIS 6.0 and added the virtual directory. If I remove the application from this folder, it uses the parent application and complains that it can't read web.config. If I add an application to this folder, even if I remove all application extensions, it complains that svc-xyzzy (the account used to access the share) doesn't have access to 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files'.
How do I have a sub folder of an application which does not execute dotnet code?
If the file share is readable by the user that your app pool is running under (Network Service by default) you can remove the virtual directory completely and create an ASP.NET application that will stream the files to the browser. If you're using MVC it's simply returning a file result. This has an added benefit in that you will be able to restrict the users from downloading the files. i.e. You can require that a user is logged in or has certain permissions to download the files. Also make sure you test for path traversal, you would not want a user entering ../../filename to download files they are not permitted to.
Option 1: ASP.NET MVC
public ActionResult Download(string file)
{
// Check for directory traversal attack
if(file.IndexOf('\\') > -1 || file.IndexOf('/') > -1)
{
return new HttpNotFoundResult();
}
file = System.IO.Path.Combine("\\FILE_SHARE_FOLDER\\", file);
if(!System.IO.File.Exists(file))
{
return new HttpNotFoundResult();
}
return this.File(file, GetMimeType(file));
}
Option 2: Webforms
private void DownloadFile(string file)
{
// Check for directory traversal attack
if(file.IndexOf('\\') > -1 || file.IndexOf('/') > -1)
{
Response.StatusCode = 404;
Response.End();
}
file = System.IO.Path.Combine("\\FILE_SHARE_FOLDER\\", file);
if (!System.IO.File.Exists(file))
{
Response.StatusCode = 404;
Response.End();
}
Response.ContentType = GetMimeType(file);
Response.TransmitFile(file);
}
Note You will need a method to get the MIME Types for both MVC and Webforms (MIME Type Method From KodeSharp)
private string GetMimeType(string fileName)
{
string mimeType = "application/unknown";
string ext = System.IO.Path.GetExtension(fileName).ToLower();
Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
if (regKey != null && regKey.GetValue("Content Type") != null)
mimeType = regKey.GetValue("Content Type").ToString();
return mimeType;
}
You can check on global.asax for the request, and if is coming from the directories that you not allow, then stop the processing as:
protected void Application_BeginRequest(Object sender, EventArgs e)
{
string cTheFile = HttpContext.Current.Request.Path;
if(cTheFile.StartsWith("/articleimages", StringComparison.CurrentCultureIgnoreCase)
{
HttpContext.Current.Response.TrySkipIisCustomErrors = true;
HttpContext.Current.Response.Write("Please start from home page");
HttpContext.Current.Response.StatusCode = 403;
HttpContext.Current.Response.End();
return ;
}
}
Of course you can simple place one extra web.config on the directory with this inside:
<configuration>
<system.web>
<authorization>
<deny users="*" />
</authorization>
</system.web>
</configuration>
but if they can delete it is not useful as the code.

Unable to get Core Service client working

I am trying to publish the component using core service, to do this, I just created a console application, and executed from the server. I am getting the below error message.
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Tridion.ContentManager.CoreService.Client, Version=6.1.0.996, Culture=neutral, PublicKeyToken=ddfc895746e5ee6b' or one of its dependencies. The system cannot find the file specified.
The below is my code, can anyone faced this issue?
static void Main(string[] args)
{
try
{
string compid = "tcm:56-935";
var client = new SessionAwareCoreServiceClient();
var readoption = new ReadOptions();
var component = (ComponentData)client.Read(compid, readoption);
var ItemToPublish = new List<string>();
ItemToPublish.Add(component.Id);
var instruction = new PublishInstructionData();
var pubtarget = (PublicationTargetData)client.Read(
"tcm:0-21-65537", readoption);
List<string> target = new List<string>();
target.Add(pubtarget.Id);
client.Publish(ItemToPublish.ToArray(), instruction, target.ToArray(),
PublishPriority.Normal, readoption);
Console.WriteLine("component published");
Console.WriteLine(component.Title);
Console.WriteLine(pubtarget.Title);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.ReadLine();
}
}
The error is clear, it says that you don't have dependency in place. You must place Tridion.ContentManager.CoreService.Client.dll into the same directory where your executable is (alternatively, you can place in GAC). Usually there is an option in Visual Studio on referenced assembly on your project "Copy Local", you can try to to set it to true and try to execute your code again.
Looks like (based on your comment to Igor's answer) you're missing some config. Check out Frank's wiki post on the Tridion Practice site - https://code.google.com/p/tridion-practice/wiki/GetCoreServiceClientWithoutConfigFile

Operation aborted (Exception from HRESULT: 0x80004004 (E_ABORT))

Code snippet :
public static void SendEmail(string _ToEmail, string _Subject, string _EmailBody)
{
oApp = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MailItem email = (Microsoft.Office.Interop.Outlook.MailItem)(oApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem));
email.Recipients.Add(_ToEmail);
email.Subject = _Subject;
email.Body = _EmailBody;
((Microsoft.Office.Interop.Outlook.MailItem)email).Send();
}
this method works well when i tested it in another project(located in file system) but when tried to test it from IIS (virtual site);It throw this exception in line : email.Recipients.Add(_ToEmail);
any help will be appreciated
P.S. the ASPNET account has the administrator permission
thanks in advance.
Make sure that the reference is set in your web.config

ASP.NET- using System.IO.File.Delete() to delete file(s) from directory inside wwwroot?

I have a ASP.NET SOAP web service whose web method creates a PDF file, writes it to the "Download" directory of the applicaton, and returns the URL to the user. Code:
//Create the map images (MapPrinter) and insert them on the PDF (PagePrinter).
MemoryStream mstream = null;
FileStream fs = null;
try
{
//Create the memorystream storing the pdf created.
mstream = pgPrinter.GenerateMapImage();
//Convert the memorystream to an array of bytes.
byte[] byteArray = mstream.ToArray();
//return byteArray;
//Save PDF file to site's Download folder with a unique name.
System.Text.StringBuilder sb = new System.Text.StringBuilder(Global.PhysicalDownloadPath);
sb.Append("\\");
string fileName = Guid.NewGuid().ToString() + ".pdf";
sb.Append(fileName);
string filePath = sb.ToString();
fs = new FileStream(filePath, FileMode.CreateNew);
fs.Write(byteArray, 0, byteArray.Length);
string requestURI = this.Context.Request.Url.AbsoluteUri;
string virtPath = requestURI.Remove(requestURI.IndexOf("Service.asmx")) + "Download/" + fileName;
return virtPath;
}
catch (Exception ex)
{
throw new Exception("An error has occurred creating the map pdf.", ex);
}
finally
{
if (mstream != null) mstream.Close();
if (fs != null) fs.Close();
//Clean up resources
if (pgPrinter != null) pgPrinter.Dispose();
}
Then in the Global.asax file of the web service, I set up a Timer in the Application_Start event listener. In the Timer's ElapsedEvent listener I look for any files in the Download directory that are older than the Timer interval (for testing = 1 min., for deployment ~20 min.) and delete them. Code:
//Interval to check for old files (milliseconds), also set to delete files older than now minus this interval.
private static double deleteTimeInterval;
private static System.Timers.Timer timer;
//Physical path to Download folder. Everything in this folder will be checked for deletion.
public static string PhysicalDownloadPath;
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
deleteTimeInterval = Convert.ToDouble(System.Configuration.ConfigurationManager.AppSettings["FileDeleteInterval"]);
//Create timer with interval (milliseconds) whose elapse event will trigger the delete of old files
//in the Download directory.
timer = new System.Timers.Timer(deleteTimeInterval);
timer.Enabled = true;
timer.AutoReset = true;
timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
PhysicalDownloadPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + "Download";
}
private static void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
{
//Delete the files older than the time interval in the Download folder.
var folder = new System.IO.DirectoryInfo(PhysicalDownloadPath);
System.IO.FileInfo[] files = folder.GetFiles();
foreach (var file in files)
{
if (file.CreationTime < DateTime.Now.AddMilliseconds(-deleteTimeInterval))
{
string path = PhysicalDownloadPath + "\\" + file.Name;
System.IO.File.Delete(path);
}
}
}
This works perfectly, with one exception. When I publish the web service application to inetpub\wwwroot (Windows 7, IIS7) it does not delete the old files in the Download directory. The app works perfect when I publish to IIS from a physical directory not in wwwroot. Obviously, it seems IIS places some sort of lock on files in the web root. I have tested impersonating an admin user to run the app and it still does not work. Any tips on how to circumvent the lock programmatically when in wwwroot? The client will probably want the app published to the root directory.
Your problem may be related to the fact that IIS reloads the Web Service Application if the directory or files contained in the main folder changes.
Try creating / deleting files in a temporary folder which is outside the root folder of your application (be aware of permissions on the folder to allow IIS to read/write files).
Instead of writing directly to the file system, why not use isolated storage?
http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstorage.aspx
This should solve any location or permission based issues that you are having
I forgot to come back and answer my question.
I had to give the IIS_IUSRS group Modify permissions to the directory where I was reading/writing files.
Thanks to all those who answered.

Resources