MergeDocument and protected PDFs strange behavior

Skip Navigation LinksHome  /  Support  /  Forums  /  DynamicPDF CoreSuite for .NET (v12)  /  MergeDocument and protected PDFs strange behavior

DynamicPDF CoreSuite for .NET (v12) Forum

I am noticing some strange/dangerous behavior related to instantiating a MergeDocument object with a source PDF that has password protection enabled.

When looking at the Document Properties page Security tab in Adobe Acrobat for my source PDF, it shows a security method of Password Security.  In the Details section of the security it shows that there is no Document Open Password, but Permissions Password is set to Yes.  For what it's worth, the PDF I am testing with is a completed fillable form generated from DocuSign.

The following items are listed as Not Allowed in the details:
Changing the Document
Commenting
Form Field Fill-in or Signing
Document Assembly
Page Extraction

When I attempt to instantiate a MergeDocument using the file path, it generates an exception saying "Required owner password for this feature."
When I do a simple File.ReadAllBytes with the file path and attempt to create a MergeDocument using the byte array that I just received from the ReadAllBytes call, I am able to successfully get back a MergeDocument.  Once I have this MergeDocument, I am able to essentially violate the security of my protected document by extracting pages, appending pages, adding form elements, etc. 

This does not seem like correct behavior in the MergeDocument constructor that takes in a byte array.  Please advise.
Posted by a ceTe Software moderator
Hi,

We tested this on our end and were unable to recreate the behavior. A PDF set with owner/Permission password is not allowed to merge using MergeDocument object without providing a correct owner password in the PdfDocument constructor.

Please send the following information to support@dynamicpdf.com so we can look into it further.

1. Code sample which uses static data to recreate the behavior.
2. Sample input PDFs used for merging.
3. Exact version and build number of DynamicPDF DLL file used in your application. You can find this information by right clicking on the DLL file>>Properties>>Details tab>>Product version. Take a screenshot of the Details tab and send it over to us.

Thanks,
ceTe Software Support Team
I have emailed support, but I cannot include the source PDF because it contains PII.  I sent an image of the document properties tab so that the document security can be recreated on your end.  Code for testing below.

    public class Program
    {
        static void Main(string[] args)
        {
            MergeProtectedPdfTest();
        }

        public static void MergeProtectedPdfTest()
        {
            var outputPathForFilePathConstructor = @"C:\testing\outputmergedocFilePathConstructor.pdf";
            var outputPathForByteArrayConstructor = @"C:\testing\outputmergedocByteArrayConstructor.pdf";

            var protectedFile1Path = @"C:\testing\protectedFile1.pdf";
            var protectedFile2Path = @"C:\testing\protectedFile2.pdf";

            MergeProtectedPdfPathConstructor(protectedFile1Path, protectedFile2Path, outputPathForFilePathConstructor);
            MergeProtectedByteArrayConstructor(protectedFile1Path, protectedFile2Path, outputPathForByteArrayConstructor);
                        
                        // PRODUCES OUTPUT:
                        //
                        // Expected failure: Required owner password for this feature.
                        // (UNEXPECTED) Successfully saved file: C:\testing\outputmergedocByteArrayConstructor.pdf
        }

        /// <summary>
        /// This method fails upon trying to open a PDF via file path that has a permission password
        /// </summary>
        public static void MergeProtectedPdfPathConstructor(string protectedFile1Path, string protectedFile2Path, string appendOutputPath)
        {
            try
            {
                var protectedFile1MergeDoc = new MergeDocument(protectedFile1Path); // exception here (EXPECTED)
                var protectedFile2MergeDoc = new MergeDocument(protectedFile2Path);

                protectedFile1MergeDoc.Append(protectedFile2MergeDoc.Draw());

                protectedFile1MergeDoc.Draw(appendOutputPath);

                Console.WriteLine($"(UNEXPECTED) Successfully saved file: {appendOutputPath}");
            }
            catch (Exception e)
            {
                Console.WriteLine($"Expected failure: {e.Message}");
            }
        }

        /// <summary>
        /// This method succeeds upon trying to open a PDF via byte array that has a permission password
        /// </summary>
        public static void MergeProtectedByteArrayConstructor(string protectedFile1Path, string protectedFile2Path, string appendOutputPath)
        {
            try
            {
                var protectedFile1Bytes = File.ReadAllBytes(protectedFile1Path);
                var protectedFile2Bytes = File.ReadAllBytes(protectedFile2Path);
                
                var protectedFile1MergeDoc = new MergeDocument(protectedFile1Bytes); // should fail here but does not
                var protectedFile2MergeDoc = new MergeDocument(protectedFile2Bytes);

                protectedFile1MergeDoc.Append(protectedFile2MergeDoc.Draw());

                protectedFile1MergeDoc.Draw(appendOutputPath);

                Console.WriteLine($"(UNEXPECTED) Successfully saved file: {appendOutputPath}");
            }
            catch (Exception e)
            {
                Console.WriteLine($"Expected failure: {e.Message}");
            }
        }
        }
Posted by a ceTe Software moderator - Commonly asked question
Hi,

We have an update from our development team and this issue is fixed in latest release, DynamicPDF Core Suite for .NET (v12.05). You can download latest from NuGet (Package ID:ceTe.DynamicPDF.CoreSuite.NET) or from our website here.

Thanks,
ceTe Software Support Team

All times are US Eastern Standard time. The time now is 6:36 PM.