Skip to content

Access restrictions are enforced inconsistently: Modify open is blocked without the owner password, but Import page copying from the same document is not #379

Description

@cbra-nbb

Environment

PDFsharp 6.2.0, .NET 10, Windows 11

Summary

PDFsharp refuses to open an owner-password-protected document in PdfDocumentOpenMode.Modify without that password. It applies no equivalent check to PdfDocumentOpenMode.Import, so the same document's full content can be copied into a new unencrypted document with no password and no diagnostic. Changing one enum value bypasses the check, and the Encryption docs recommend exactly that substitution as the workaround.

Filed as a bug rather than a feature request because PDFsharp already enforces part of the permission model. The inconsistency is the defect, not the absence of enforcement.

Expected

Given that Modify is blocked, either the Import path applies a comparable check (consulting PermitExtractContent and PermitAssembleDocument when HasOwnerPermissions is false), or the Modify restriction is documented as a technical constraint rather than an access control, and the docs stop offering Import as the way around it.

Actual

Modify throws, blocking in-place modification of the document. Import succeeds and yields the complete content of the protected document, unencrypted, without exceptions, warnings, or log entries.

Both paths protect the same thing, since copying every page into a new file achieves a result equivalent to modifying the original. Guarding one and not the other leaves the guard without practical effect.

Reproduction

using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;

const string path = "test-with-aes-256.pdf";

// (1) Blocked, as documented.
try
{
    using var doc = PdfReader.Open(path, string.Empty, PdfDocumentOpenMode.Modify);
    Console.WriteLine("Modify: opened");
}
catch (Exception ex)
{
    Console.WriteLine($"Modify: refused, {ex.GetType().Name}");
}

// (2) Not blocked. Same file, same absent password, one enum value changed.
using var input = PdfReader.Open(path, string.Empty, PdfDocumentOpenMode.Import);

Console.WriteLine(input.SecuritySettings.HasOwnerPermissions);     // False
Console.WriteLine(input.SecuritySettings.PermitExtractContent);    // False
Console.WriteLine(input.SecuritySettings.PermitAssembleDocument);  // False

using var output = new PdfDocument();
foreach (var page in input.Pages)
    output.AddPage(page);

output.Save("output.pdf");   // unencrypted, every restriction dropped

No password is needed at any point. The user password is empty, which is the normal configuration for a document restricted by its author rather than kept confidential.

Suggested resolution

Add opt-in validation that turns the same condition into an exception, for callers that want the operation to fail.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions