+1-888-365-2779
Try Now
More in this section

Forums / Security / How do you preventing direct linking to website files

How do you preventing direct linking to website files

12 posts, 1 answered
  1. AB
    AB avatar
    7 posts
    Registered:
    05 Aug 2009
    17 Jun 2010
    Link to this post
    How do I prevent a public web user from direct linking to a file that is identified on a secured page (you must have an account to access the page).  For example:  a hyperlink with the direct path to the file is inserted on a new page.  The new page is secured so that only people in in the employee role can access the page to get the link.  Yet if the link is copied a potential user can past it into their browser and bypass the page.  Is there a setting in IIS that will trigger a login prompt on that file or folder?
  2. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    22 Jun 2010
    Link to this post
    Hi AB,

    Thank you for using our services.

    You can create a class which inherits from our content http handler which serves content items from libraries. Please find the class below. We override the ContentHttpHandler. Then, check whether the user from a specified role has permissions to see the files in our library:
    using System;
    using System.Web;
    using System.Web.Security;
    using Telerik.Cms.Engine;
      
    //Override ContentHttpHandler
    public class CustomCmsContentHandler : ContentHttpHandler
    {
          
        public override void ProcessRequest(HttpContext context)
        {
      
            //restrict access to mylib
            string path = String.Concat(context.Request.ApplicationPath, "/libraries/mylib/");
      
            if (context.Request.RawUrl.StartsWith(path, StringComparison.OrdinalIgnoreCase))
            {
                //check whether the user is authenticated or not.
                RolePrincipal principal = context.User as RolePrincipal;
                if (principal == null
                    || !principal.Identity.IsAuthenticated
                    || !principal.IsInRole("Administrators"))
                {
                    //you can also redirect to the login page if you wish
                    throw new HttpException(403, "Access forbidden");
                    return;
                }
            }
      
            base.ProcessRequest(context);
        }
    }

    Set up:

    1. Add CustomCmsContentHandler class to App_Code folder.
    2. Then, change your web.config and replace the handler as below:

    Replace in system.webServer/handers:
    <add name="SitefinityThumbnail" path="*.tmb" verb="*" preCondition="integratedMode" type="Telerik.Cms.Engine.ContentHttpHandler, Telerik.Cms.Engine" />
    <add name="SitefinityThumbnailAdd" path="*.tmb.ashx" verb="*" preCondition="integratedMode" type="Telerik.Cms.Engine.ContentHttpHandler, Telerik.Cms.Engine" />
    <add name="SitefinityLibrary" path="*.sflb" verb="*" preCondition="integratedMode" type="Telerik.Cms.Engine.ContentHttpHandler, Telerik.Cms.Engine" />
    <add name="SitefinityLibraryAdd" path="*.sflb.ashx" verb="*" preCondition="integratedMode" type="Telerik.Cms.Engine.ContentHttpHandler, Telerik.Cms.Engine" />

    <add name="SitefinityThumbnail" path="*.tmb" verb="*" preCondition="integratedMode" type="CustomCmsContentHandler, App_Code" />
    <add name="SitefinityThumbnailAdd" path="*.tmb.ashx" verb="*" preCondition="integratedMode" type="CustomCmsContentHandler, App_Code" />
    <add name="SitefinityLibrary" path="*.sflb" verb="*" preCondition="integratedMode" type="CustomCmsContentHandler, App_Code" />
    <add name="SitefinityLibraryAdd" path="*.sflb.ashx" verb="*" preCondition="integratedMode" type="CustomCmsContentHandler, App_Code" />

    and in system.web/httpHandlers:
    <httpHandlers>
    <add verb="GET" path="*.sflb" type="Telerik.Cms.Engine.ContentHttpHandler, Telerik.Cms.Engine" />
    <add verb="GET" path="*.sflb.ashx" type="Telerik.Cms.Engine.ContentHttpHandler, Telerik.Cms.Engine" />
    <add verb="GET" path="*.tmb" type="Telerik.Cms.Engine.ContentHttpHandler, Telerik.Cms.Engine" />
    <add verb="GET" path="*.tmb.ashx" type="Telerik.Cms.Engine.ContentHttpHandler, Telerik.Cms.Engine" />
    </httpHandlers>

    with:
    <httpHandlers>
    <add verb="GET" path="*.sflb" type="CustomCmsContentHandler, App_Code" />
    <add verb="GET" path="*.sflb.ashx" type="CustomCmsContentHandler, App_Code" />
    <add verb="GET" path="*.tmb" type="CustomCmsContentHandler, App_Code" />
    <add verb="GET" path="*.tmb.ashx" type="CustomCmsContentHandler, App_Code" />
    </httpHandlers>


    Sincerely yours,
    Radoslav Georgiev
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. AB
    AB avatar
    7 posts
    Registered:
    05 Aug 2009
    25 Jun 2010
    Link to this post
    Thanks for your response.

    My version of Sitefinity Telerik.Cms.Engine does not have the HTTPContentHandler.  At this time my shops does not intend to upgrade Sitefinity and we at version 3.1.  Is there another solution?  What version is this handler availiable in?
  4. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    25 Jun 2010
    Link to this post
    Hello AB,

    You can use standard ASP.NET HttpHandler or HttpModule to prevent the access for a certain request.

    Best wishes,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  5. AB
    AB avatar
    7 posts
    Registered:
    05 Aug 2009
    12 Jul 2010
    Link to this post
    I've tried this code and it get's into an infinite loop if a .doc file is requested, and I have been authenticated.  It never processes the request.  I know my question was how do you prevent direct linking to files within your website and this is that solution.  But  I guess I meant how do you stop unauthenticated uses from accessing doc files intended only for let's say employees.  I've tried web.config authentication settings in the folders where the files reside but the website ignores these settings.  Is there a way to make this code work or get the authentication settings to work.

    One other thing.  I was able to compile the exact code provide except for this line

    base.ProcessRequest(context);   I had to remove the base.
  6. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    12 Jul 2010
    Link to this post
    Hi AB,

    When you inherit from CustomCmsContentHandler  your derivate will be called only for the CMS requests and item that are uploaded through Images and Documents module. To restrict the File system you have to create a custom standard ASP.NET HttpHandler or HttpModule.
    If you are using IHttpHandler you could set  IsReusable property to false

    sample

    public class HttpHandlerCustom : IHttpHandler
    {
        #region IHttpHandler Members
     
        public bool IsReusable
        {
            get { return false; }
        }
     
        public void ProcessRequest(HttpContext context)
        {
                string path = String.Concat(context.Request.ApplicationPath, "/Images/SecuredFolder/");
                if (context.Request.RawUrl.StartsWith(path, StringComparison.OrdinalIgnoreCase))
                {
                    RolePrincipal principal = context.User as RolePrincipal;
                    if (!principal.Identity.IsAuthenticated)
                    {
                         
                        throw new HttpException(403, "Access forbidden");
                        return;
                    }
                }
        }
     
        #endregion
     
    }


    Also the Authorization element and its settings ( Allow "*", Deny) are valid only for the File system.

    All the best,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
    Answered
  7. AB
    AB avatar
    7 posts
    Registered:
    05 Aug 2009
    13 Jul 2010
    Link to this post
    Finally, the code below is what did it for me....thanks for providing your input, I was missing the download file part....

    1) include the web config handler

    <

     

    add verb="GET" path="*.doc,*.docx,*.xls,*.xlsx,*.pdf,*.htm,*.ppt,*.wrf" type="CustomCmsContentHandler, App_Code" />

     


    2) then add this code to the app_code library
    using System;
    using System.Web;
    using System.Web.Security;
    using Telerik.Cms.Engine;
      
    //Override ContentHttpHandler 
    public class CustomCmsContentHandler : IHttpHandler
    {
      
      using System;
    using System.Web;
    using System.Web.Security;
    using Telerik.Cms.Engine;
      
    //Override ContentHttpHandler 
    public class CustomCmsContentHandler : IHttpHandler
    {
      
        public void ProcessRequest(HttpContext context)
        {
      
            ////restrict access to these directories
            string diraccessrole = null;
            string emp = String.Concat(context.Request.ApplicationPath, "/files/employee/");
            string edu = String.Concat(context.Request.ApplicationPath, "/toolkit/education");
            string hlth = String.Concat(context.Request.ApplicationPath, "/toolkit/healthcare/");
            string web = String.Concat(context.Request.ApplicationPath, "/securewebinars/");
      
            //string emp = String.Concat(context.Request.PhysicalApplicationPath, "/files/employee/");
            //string edu = String.Concat(context.Request.PhysicalApplicationPath,"/toolkit/education/");
            //string hlth = String.Concat(context.Request.PhysicalApplicationPath,"/toolkit/healthcare/");
            //string web = String.Concat(context.Request.PhysicalApplicationPath,"/securewebinars/");
      
            //assign the role needed for access to each directory
            if (context.Request.RawUrl.Contains(emp))
            {
                diraccessrole = "employees";
            }
      
            if (context.Request.RawUrl.Contains(edu))
            {
                diraccessrole = "education";
            }
      
            if (context.Request.RawUrl.Contains(hlth))
            {
                diraccessrole = "healthcare";
            }
      
            if (context.Request.RawUrl.Contains(web))
            {
                diraccessrole = "university";
            }
            //determine if the request is to a restricted file otherwise download the file
            if (diraccessrole == null)
            {
                DownloadFile(context);
            }
            else
            {
                RestrictedAccess(context, diraccessrole);
            }
        }    
           private void RestrictedAccess(HttpContext context, string diraccessrole)
           {
      
               //allow or deny access to the file based on user role
                
                   if ((context.User.Identity.IsAuthenticated)
                        && (context.User.IsInRole(diraccessrole)))
                   {
                       DownloadFile(context);
                   }
                   else
                   {
                       context.Response.Write("To access this file please go to www.xxx.com and log in.  If you do not have an account send  an email to help@xxx.com");
                   }
                 
            }
         
        protected void DownloadFile(HttpContext context)
        {
            string ct = null;
            string word = ".doc";
            string excel = ".xls";
            string power = ".ppt";
            string web = ".wrf";
            string pdf = ".pdf";
            string word2 = ".docx";
            string excel2 = ".xlsx";
      
            //determine content type unable to retrieve content type from the context.request.contenttype so hardcoded
            if (context.Request.FilePath.Contains(word))
            {
                ct = "application/msword";
            }
            if (context.Request.FilePath.Contains(excel))
            {
                ct = "application/vnd.ms-excel";
            }
            if (context.Request.FilePath.Contains(power))
            {
                ct = "application/vnd.ms-powerpoint";
            }
            if (context.Request.FilePath.Contains(web))
            {
                ct = "application/octet-stream";
            }
            if (context.Request.FilePath.Contains(pdf))
            {
                ct = "application/pdf";
            }
            if (context.Request.FilePath.Contains(word2))
            {
                ct = "application/msword";
            }
            if (context.Request.FilePath.Contains(excel2))
            {
                ct = "application/vnd.ms-excel";
            }
                  
            
            context.Response.Buffer = true;
            context.Response.Clear();
            context.Response.AddHeader("content-disposition", context.Request.Url.LocalPath.ToLower());
            context.Response.ContentType = ct;
            context.Response.WriteFile(context.Server.MapPath(context.Request.Url.LocalPath.ToLower()));
                 
        }
      
        public bool IsReusable
        {
            get
            {
                return false;
            }
             
         }
        
             
    }
      
          
        
  8. shanta
    shanta avatar
    3 posts
    Registered:
    04 Aug 2010
    04 Aug 2010
    Link to this post
    the above solution is working fine with my local host. but when i deploy this on IIS 6 it is not working, this is not going through that new controller  which is added. can any one help on this.
  9. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    05 Aug 2010
    Link to this post
    Hi shanta,

    Make sure that the handler is added to system.web/httpHandlers in your web.config. This is the section where it has to be registered for IIS 6.0

    Regards,
    Radoslav Georgiev
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  10. shanta
    shanta avatar
    3 posts
    Registered:
    04 Aug 2010
    09 Aug 2010
    Link to this post

    <

     

    httpHandlers>

     

    <

     

    add verb="GET, HEAD, POST, DEBUG" path="*.htm" type="System.Web.UI.PageHandlerFactory"/>

     

    <

     

    add verb="GET, HEAD, POST, DEBUG" path="*.html" type="System.Web.UI.PageHandlerFactory"/>

     

    <

     

    add verb="GET" path="*.doc" type="Microsoft.Web.CustomHandler.HttpHandlers.CustomContentHandler, Microsoft.Web.CustomHandler" />

     

     

    </

     

    httpHandlers>

    and the custom controller located within the Appcode folder

     

    namespace

     

    Microsoft.Web.CustomHandler.HttpHandlers

     

    {

     

    //Override ContentHttpHandler

     

     

     

     

     

    public class CustomContentHandler : IHttpHandler

     

     

     

     

    {

     

    public void ProcessRequest(HttpContext context)

     

    {

     

    //

    if

     

    (context.User.Identity.IsAuthenticated)

     

    {

    DownloadFile(context);

    }


    else
    //throw exception

    }
    }


    But when i deploy the application in IIS with a virtual directory, and browse it is not even calling this handler. is any other setting do i need to make in IIS 6 apart from adding the home directory for .doc
    C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll


    Thank You,
    Shanta

  11. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    09 Aug 2010
    Link to this post
    Hi shanta,

    Take a look at How to: Register HTTP Handlers. The solution you use is standard ASP.NET implementation and the code you have is not affected by Sitefinity itself.

    All the best,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  12. shanta
    shanta avatar
    3 posts
    Registered:
    04 Aug 2010
    10 Aug 2010
    Link to this post
    Its working now. have added below code in my login authentication

     

    FormsAuthentication.SetAuthCookie(username, false);

    this will assign 'true' value  to the following "context.User.Identity.IsAuthenticated"

     

Register for webinar
12 posts, 1 answered