Skip to content

removeProtection() silently corrupts the document instead of throwing for an unauthenticated PDF instance #82

Description

@alfikiafan

Environments

LibPDF version: 0.4.0
Node version: v24.11.1

Minimal reproduction

import { PDF } from "@libpdf/core";

// `encryptedBytes` is a PDF encrypted with a known user password
const pdf = await PDF.load(encryptedBytes, {
  credentials: { password: "WRONG_PASSWORD" },
});

console.log(pdf.isAuthenticated); // false

pdf.removeProtection(); // does not throw
const bytes = await pdf.save();
// The saved file no longer has an /Encrypt dictionary, but its content
// streams are still ciphertext — the resulting PDF is unreadable garbage.

Expected behavior

Per the method's own doc comment (@throws {PermissionDeniedError}), calling removeProtection() on a PDF instance that isn't authenticated (isAuthenticated === false) should throw.

Actual behavior

No error is thrown. The /Encrypt dictionary is removed from the trailer (so the file looks unencrypted), but the page content streams are never actually decrypted, since the correct key was never derived. The result is a PDF that "succeeds" but is silently corrupt — the same symptom occurs whenever credentials are simply missing, not just wrong.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions