SharePoint 2010 Allows copies of Attachments to be added to List Item against security policy

I am using SharePoint 2010 and I have a List which allows document attachments to be added.  We are using custom forms for the new/Edit and View screens of the list Item.  The problem is with the View Screen, users with only read access to the list item can open document attachments (specifically in Office 2013) and save a copy of that attachment with any changes they may have made back to the list item.  We need to allow these users the ability to read the attachments, but not save changes back to the list item.

I am using the following code to make the attachment links which allow the users access to download and read the attachments on the list item.

StringBuilder AttachmentsText = new StringBuilder();
    foreach (string FileName in li.Attachments)
    {
       AttachmentsText.AppendLine("<a onclick=\"" + CreateDocumentOnClickLink(li.Web.GetFile(li.Attachments.UrlPrefix + FileName), li) + " \" href=\"" + li.Attachments.UrlPrefix + FileName + "\" target=\"_blank\">" + FileName + "</a><br />");
    }

    public string CreateDocumentOnClickLink(SPFile myfile, SPListItem li)
    {
        //string text = SPUtility.MapToControl(SPContext.Current.Web, myfile.Name, string.Empty);
        //string text2 = "0";// (myfile.Item.ParentList.DefaultItemOpen == DefaultItemOpen.Browser) ? "1" : "0";
        ////SPFieldLookupValue sPFieldLookupValue = myfile.Item["CheckedOutUserId"] as SPFieldLookupValue;
        //string scriptLiteralToEncode = string.Empty;// (sPFieldLookupValue == null) ? string.Empty : sPFieldLookupValue.LookupValue;
        //string text3 = (SPContext.Current.Web.CurrentUser != null) ? SPContext.Current.Web.CurrentUser.ID.ToString(System.Globalization.CultureInfo.InvariantCulture) : string.Empty;
        //string text4 = "0";// myfile.Item.ParentList.ForceCheckout ? "1" : "0";

        //return string.Format(System.Globalization.CultureInfo.InvariantCulture, "return DispEx(this,event,'{0}',{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}')", new object[] 
        //{
        //    "TRUE",
        //    "FALSE",
        //    "FALSE",
        //    text,
        //    text2,
        //    text,
        //    string.Empty,
        //    string.Empty,
        //    SPHttpUtility.EcmaScriptStringLiteralEncode(scriptLiteralToEncode),
        //    text3,
        //    text4,
        //    "0",//(string)myfile.Item["IsCheckedoutToLocal"],
        //    "0x0000000000000000"//"0x7fffffffffffffff"//(string)myfile.Item["PermMask"]
        //});

        //return "javscript:STSNavigate('" + li.Web.Url + "/_layouts/download.aspx?SourceUrl=" + li.Attachments.UrlPrefix + myfile.Name + "&Source=" + li.Attachments.UrlPrefix + "')";
        return  li.Web.Url + "/_layouts/download.aspx?SourceUrl=" + li.Attachments.UrlPrefix + myfile.Name + "&Source=" + li.Attachments.UrlPrefix;

    }

I have tried multiple different techniques to create the links that open the attachments in the hopes that it would keep the users from saving copies, but do far all have failed. You can see from the commented out code the different link types I have tried. It does keep them from saving changes to the existing attachment.

I have also tried using an Event Receiver to check when an attachment is added to a list item and check the security of the user that way.

public override void ItemAttachmentAdding(SPItemEventProperties properties)
    {
        try
        {
            base.ItemAttachmentAdding(properties);
            string POC = string.Empty;
            string ModifiedUser = string.Empty;

            if (AppSettings == null)
            {
                setGlobalVariables(properties);
            }

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                POC = FormatPOC(properties, properties.ListItem, properties.ListItem["ASCPOC"].ToString());
                ModifiedUser = FormatPOC(properties, properties.ListItem, properties.ListItem["Editor"].ToString());

                COICTaskerHelper.WriteLog(AppSettings, properties.ListItem.Web.Url, ModifiedUser, " Made it into the ItemAttachmentAdding Event.");


                if (properties.ListItem["IsParent"] != null && Convert.ToBoolean(properties.ListItem["IsParent"].ToString()) == true)
                {
                    if (!AJTrackerTools.IsCTBUser(AppSettings, properties, ModifiedUser)) //Not part of CTB for Parent List Item Cancel Attachment adding
                    {
                        COICTaskerHelper.WriteLog(AppSettings, properties.ListItem.Web.Url, ModifiedUser, " Canceling the Item Attachment because it is a parent tasker and user isnt in the CTB.");
                        properties.Cancel = true;
                        properties.ErrorMessage = "You do not have permissions to add an attachment to this item.";
                    }
                }
                else
                {
                    ArrayList ActionGroups = AJTrackerTools.GetActionGroups(AppSettings, properties, properties.ListItem);
                    Boolean SaveAttachment = false;

                    foreach (string ActionGroup in ActionGroups)
                    {
                        ArrayList UsersList = AJTrackerTools.GetUsersInGroup(AppSettings, properties, properties.ListItem, ActionGroup);

                        foreach (SPUser u in UsersList)
                        {
                            if (!string.IsNullOrEmpty(u.LoginName.ToString()))
                            {
                                if (u.LoginName == ModifiedUser)
                                {
                                    SaveAttachment = true;
                                }
                            }
                        }
                    }

                    if (POC == ModifiedUser)
                        SaveAttachment = true;

                    if (SaveAttachment == false)
                    {
                        COICTaskerHelper.WriteLog(AppSettings, properties.ListItem.Web.Url, ModifiedUser, " Canceling the Item Attachment because it is a child tasker and user isnt in the Action group or a POC.");
                        properties.Cancel = true;
                        properties.ErrorMessage = "You do not have permissions to add an attachment to this item.";
                    }

                }
            });
        }
        catch (Exception ex)
        {
            if (AppSettings == null)
            {
                AppSettings.Add(new AppSetting("SP_LOGGING_ENABLED", "true"));
            }
            COICTaskerHelper.WriteLog(AppSettings, properties.ListItem.Web.Url, "ERROR", " ItemAttachmentAdding error: " + ex.Message);
        }
    }

The problem with this method is when adding an attachment it seems you have to make sure the Office document has to have the same content type to kick off the event. Also when opening up that same Office 2013 attachment you can still save a copy of the attachment without the event kicking off even if you use the attachment that is using the same content type. Any help on this issue would be greatly appreciated.

Thanks,

P.S.  I have also tried a workflow, but when saving a copy of the Office 2013 attachment it still doesn't kick off the Item changed Event for the workflow to run and check the security of the user.


May 13th, 2015 5:41pm

Hi,

The issue you are trying to fix is to prevent users with only read permission from adding copies of attachments into a list item. However, as my test, users with only read permission to a list can never update or save a new copy of the attached files in an item. SharePoint definitely will check user's permission when saving a copy of an Office document. Would you please double check whether you have some customization with the read permission?

Thanks,
Reken Liu

Free Windows Admin Tool Kit Click here and download it now
May 18th, 2015 9:51am

I was able to create a Document Library and a Custom List that allowed attachments in the same site with the same permissions as the list I am having problems with and in both cases the Document Library and Custom List worked correctly allowing me to only read the attachment and not save a copy of the attachment back to the list or library.

After taking myself out of the site collection admin group and just trying to access the list items with the read only group I get an access denied error.  So I am unable to read the attachments now.  The other two lists I created work fine with the read only group. 


May 19th, 2015 6:37pm

Hi Mistlin,

I assume you haven't stopped inheriting permission on the problem list, that means, you should be able to read the list item as well as attachments under read only permission, but now encountered an access deny error. It sounds another issue which is different from the one you described before.

In my opinion, there might be difference between your read only and others. Would you please check the permission level of the read only permission, which should include "View Items". Besides, if this list includes custom event, is there any chance to re-create this list as a OOTB one?

Thanks,
Reken Liu

Free Windows Admin Tool Kit Click here and download it now
June 5th, 2015 3:41am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics