System.Security.Permissions.FileIOPermission Error When Trying to Upload a File Based on Trust Levels

Ömer Kaya picture Ömer Kaya · Feb 1, 2017 · Viewed 10.8k times · Source

I am developing a web application on Visual Studio 2013. In my application, users are able to upload images(saving to computer's file system for local, saving to server's file system after publishing). I published web site to my hosting. But there was a problem on uploading. I contacted with the support and they told me that they don't allow Full Tust, they allow Medium Trust level for application. I added following line to set application's trust level to medium in my web.config:

<trust level="Medium" originUrl=""/>

But when I upload file to try, I encountered with following error:

Description: The application attempted to perform an operation not allowed by the security policy. To grant this application the required permission please contact your system administrator or change the application's trust level in the configuration file.

Exception Details: System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

Is there a way to give myself fileiopermission on medium trust level? I am searching for the solution for weeks but nothing come in handy.

Here is the code that causing problem.

foreach (var file in uploadImages.PostedFiles)
{
    //this line causes the problem
    string filename = Path.GetFileName(new FileInfo(file.FileName).Name);
    string[] extension = filename.Split('.'); 
    string path = Server.MapPath("~/fortunePictures/" + randomString(16) + "." + extension.Last().ToString());
    file.SaveAs(path); 
    DateTime now = DateTime.Now;
    string date = (now.ToString("u"));
    date = date.Substring(0,date.Length-1);
    System.Drawing.Image img = System.Drawing.Image.FromFile(path);
    insertImage(file, path, date, img, userID, fortuneID);
}

Here is the stack trace:

[SecurityException: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.]
   System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet) +0
   System.Security.CodeAccessSecurityEngine.Check(CodeAccessPermission cap, StackCrawlMark& stackMark) +34
   System.Security.CodeAccessPermission.Demand() +46
   System.Security.Permissions.FileIOPermission.QuickDemand(FileIOPermissionAccess access, String fullPath, Boolean checkForDuplicates, Boolean needFullPath) +157
   System.IO.FileInfo.Init(String fileName, Boolean checkHost) +42
   System.IO.FileInfo..ctor(String fileName) +46
   Fal_Sitesi.kahve.btnUpload_Click(Object sender, EventArgs e) in c:\Users\Ömer\Documents\Visual Studio 2013\Projects\Fal Sitesi\Fal Sitesi\kahve.aspx.cs:84
   System.EventHandler.Invoke(Object sender, EventArgs e) +0
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +9717914
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +108
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +12
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +15
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +35
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +6720
   System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +245
   System.Web.UI.Page.ProcessRequest() +72
   System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) +22
   System.Web.UI.Page.ProcessRequest(HttpContext context) +58
   ASP.kahve_aspx.ProcessRequest(HttpContext context) in App_Web_n3utt0vk.0.cs:0
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +341
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69

Please help.

Edit: What I've done so far

I added Security policy configuration according to this link I got

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Web.HttpException: Unable to read the security policy file for trust level 'Medium'.

error. I tried to create custom security policy file and change FileIOPermission contents other than $AppDir$. But it didn't help either. Then I create new web.config file. I copied contents of web_mediumtrust.config. But didn't solve either. At the end I removed security policy tag and all its content. And I used

<identity impersonate="true" userName="mywebsite.com\ftpUserID" password="ftpPassword"/>

to connect server with authorization. But I was unable to make connection. (I don't know why, with same data I can establish ftp connection.)

As a result nothing solved my problem and I'm eager to solve it. Here is my web.config.

<?xml version="1.0"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->

<configuration>
    <system.web>
      <compilation targetFramework="4.5" debug="true"/>
      <httpRuntime/>
      <pages controlRenderingCompatibilityVersion="4.0"/>
      <customErrors mode="Off" defaultRedirect="index.aspx"/>
      <trust level="Medium" originUrl=""/>
    </system.web>
</configuration>

I get System.Security.SecurityException with this configuration.

Edit 2: I added <location path="myAppName" allowOverride="false"> to my configuration file according to this link. Now the application works on localhost correctly. But the published web site still throws error. Here is the last version of my web.config file:

<?xml version="1.0"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->

<configuration>
  <location path="myAppName" allowOverride="false">
    <system.web>
      <compilation targetFramework="4.5" debug="true"/>
      <httpRuntime/>
      <pages controlRenderingCompatibilityVersion="4.0"/>
      <customErrors mode="Off" defaultRedirect="index.aspx"/>
      <trust level="Medium" originUrl=""/>
    </system.web>
  </location>
</configuration>

Answer

&#214;mer Kaya picture Ömer Kaya · Feb 2, 2017

Well, I've found the solution and it was very simple :( In my case I used

string filename = Path.GetFileName(new FileInfo(file.FileName).Name);

to get filename and it was unnecessary. I don't know why I did but

string filename = file.FileName

was enough to get filename of uploaded file. Rest of code is same and last status of web.config file is:

<?xml version="1.0"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->

<configuration> 
    <system.web>
      <compilation targetFramework="4.5" debug="true"/>
      <httpRuntime/>
      <pages controlRenderingCompatibilityVersion="4.0"/>
      <customErrors mode="Off" defaultRedirect="index.aspx"/>
      <trust level="Medium" originUrl=""/>
    </system.web>
</configuration>