Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cloudflare blocks sign PDF #280

Open
MichalY-WizSoft opened this issue Jan 7, 2025 · 20 comments
Open

Cloudflare blocks sign PDF #280

MichalY-WizSoft opened this issue Jan 7, 2025 · 20 comments

Comments

@MichalY-WizSoft
Copy link

MichalY-WizSoft commented Jan 7, 2025

  • Generate PDF using JSPDF
  • Merge PDFs using PDF-MERGER
  • Add signature placeholder using pdflibAddPlaceholder
  • Sign the PDF
  • Try to upload to system -> Cloudflare blocks with WAF alerts
  • When switching to plainAddPlaceholder, the upload works but the signature is not visible in Adobe Reader
  • what the difrent and how to do not block and visible in Adobe Reader ?

Attachments

  • [signed_pdflib.pdf] - PDF signed with pdflibAddPlaceholder
  • [signed_plain.pdf] - PDF signed with plainAddPlaceholder
  • [cloudflare_block.png] - Screenshot of Cloudflare WAF block

signed_plain.pdf
signed_pdflib.pdf
cloudflare_block

const signPdf = async (pdfBuffer, signer) => {
    try {
        const pdfWithPlaceholder = await plainAddPlaceholder({
            pdfBuffer,
            reason: 'Digital Invoice Signature',
            contactInfo: 'Wizsoft',
            name: 'Wizsoft Digital Signature',
            location: 'Israel',
            signingTime: new Date().toISOString(),
            signatureLength: 8192,
            subFilter: 'adbe.pkcs7.detached',
            appName: 'Wizsoft Digital Signature System',
            widgetRect: [0, 0, 595, 842]
        });    
        return signpdf.sign(pdfWithPlaceholder, signer);
    } catch (err) {
        throw {message:`signature faild, error : ${err}`};
    }
}

const signPdfLib = async (pdfBuffer,  signer) =>{
    try {
        let pdfDoc = await PDFDocument.load(pdfBuffer);
        await pdflibAddPlaceholder({
            pdfDoc: pdfDoc,
            reason: 'Digital Invoice Signature',
            contactInfo: '',
            name: 'Digital Signature',
            location: 'Israel',
            signingTime: new Date().toISOString(),
            signatureLength: 8192,
            subFilter: 'adbe.pkcs7.detached',
        });
        pdfWithPlaceholder = await Buffer.from(await pdfDoc.save({useObjectStreams: false }), 'arraybuffer');
        return signpdf.sign(pdfWithPlaceholder, signer)                    
    } catch (err) {
        throw {message:`signature faild, error : ${err}`};
    }
}
@dhensby
Copy link
Collaborator

dhensby commented Jan 7, 2025

Have you spoken to cloudflare?

@MichalY-WizSoft
Copy link
Author

I’m trying to contact them as well.

Previously, I used to work with :
const { plainAddPlaceholder } = require('node-signpdf/dist/helpers');
However, I had to switch because I needed to upload a PDF version that wasn’t supported, and this library is now deprecated.

What has changed between the libraries?
Is there an alternative way to create a VALID Adobe signature that is also visible in Adobe Reader, while still using plainAddPlaceholder in a way that Cloudflare does not block?

@dhensby
Copy link
Collaborator

dhensby commented Jan 7, 2025

We don't know specifically what cloudflare is blocking or what they don't like. Is it specifically to do with the content of the PDF? With the signature? With that particular instance of a signature?

I'm not intimately familiar with the exact differences, but I don't see why they should produce vastly different signatures that would make cloudflare think there's embedded PHP, command injections, etc in them.

Have you looked at the PDF files in a text editor to see what is different?

@MichalY-WizSoft
Copy link
Author

I noticed that in pdflibAddPlaceholder, a long string with various characters is embedded in the signature.

How does this information help me?

image

@dhensby
Copy link
Collaborator

dhensby commented Jan 7, 2025

That stream doesn't look well formed to me, it should be binary data but it's made up of ASCII, which is unusual.

I suspect there's some encoding problem somewhere which is corrupting something. I don't know what exactly, you'll have to debug what is going on.

You aren't following the example for pdf-lib, so maybe that's a problem too?

const signPdfLib = async (pdfBuffer,  signer) =>{
    try {
        const pdfDoc = await PDFDocument.load(pdfBuffer);
       pdflibAddPlaceholder({
            pdfDoc: pdfDoc,
            reason: 'Digital Invoice Signature',
            contactInfo: '',
            name: 'Digital Signature',
            location: 'Israel',
            signingTime: new Date().toISOString(),
            signatureLength: 8192,
            subFilter: 'adbe.pkcs7.detached',
        });
        pdfWithPlaceholder = await pdfDoc.save();
        return signpdf.sign(pdfWithPlaceholder, signer)                    
    } catch (err) {
        throw {message:`signature faild, error : ${err}`};
    }
}

@MichalY-WizSoft
Copy link
Author

If I follow the example, I encounter an error:
"PDF expected as Buffer"

This happens because pdfDoc.save returns a Uint8Array, while signpdf.sign expects a Buffer.

Am I missing something in the process?

@dhensby
Copy link
Collaborator

dhensby commented Jan 8, 2025

Then do this

const signPdfLib = async (pdfBuffer,  signer) =>{
    try {
        const pdfDoc = await PDFDocument.load(pdfBuffer);
       pdflibAddPlaceholder({
            pdfDoc: pdfDoc,
            reason: 'Digital Invoice Signature',
            contactInfo: '',
            name: 'Digital Signature',
            location: 'Israel',
            signingTime: new Date().toISOString(),
            signatureLength: 8192,
            subFilter: 'adbe.pkcs7.detached',
        });
        pdfWithPlaceholder = await pdfDoc.save();
-        return signpdf.sign(pdfWithPlaceholder, signer)
+        return signpdf.sign(Buffer.from(pdfWithPlaceholder), signer)
    } catch (err) {
        throw {message:`signature faild, error : ${err}`};
    }
}

@MichalY-WizSoft
Copy link
Author

MichalY-WizSoft commented Jan 8, 2025

Thank you for the quick response - I really appreciate it!

I’ve encountered an issue: if I don’t use pdfDoc.save({ useObjectStreams: false }), I get the following error:
"No ByteRangeStrings found within PDF buffer."

@dhensby
Copy link
Collaborator

dhensby commented Jan 8, 2025

ok, and if you add that in?

@MichalY-WizSoft
Copy link
Author

Yes,

The document was signed, but it’s still being blocked by Cloudflare.
I suspected it (useObjectStreams: false) might be the cause.

@MichalY-WizSoft
Copy link
Author

Is there a way to add a placeholder using plainAddPlaceholder so that the signature will be visible in Adobe Reader?

@dhensby
Copy link
Collaborator

dhensby commented Jan 8, 2025

Yep - it seems there's a compatibility issue with lib-pdf and this lib at the moment, then. Perhaps something changed under the hood with pdf-lib in a version and we've not kept up.

@MichalY-WizSoft
Copy link
Author

MichalY-WizSoft commented Jan 8, 2025

If I use this function.
the process completes successfully and Cloudflare does not block it. However,
I do not receive the validation in Acrobat.
I’ve attached an image of what I expect to see.
Do you know why this is happening and how to fix it?
Thank you in advance for your help!

const signPdfLib = async (pdfBuffer, signer) => {
    try {
        const pdfWithPlaceholder = await plainAddPlaceholder({
            pdfBuffer: pdfBuffer,
            reason: 'Digital Invoice Signature',
            contactInfo: 'Wizsoft',
            name: 'Wizsoft Digital Signature',
            location: 'Israel',
            signingTime: new Date().toISOString(),
            signatureLength: 8192,
            subFilter: 'adbe.pkcs7.detached',
            appName: 'Wizsoft Digital Signature System',
            widgetRect: [0, 0, 595, 842]
        });

        return signpdf.sign(pdfWithPlaceholder, signer);
    } catch (err) {
        throw {message:`signature faild, error : ${err}`};
    }
}

image

@dhensby
Copy link
Collaborator

dhensby commented Jan 8, 2025

I don't know why it is not showing, presumably because not all the signatures are valid? What does the signature pane say?

@MichalY-WizSoft
Copy link
Author

The window doesn’t open—this is exactly the problem. It’s as if the document isn’t signed.
Attached is an example document.

example.pdf

@vbuch
Copy link
Owner

vbuch commented Feb 3, 2025

@MichalY-WizSoft can you share the source file that you are trying to sign, not the one with the added signature?

@MichalY-WizSoft
Copy link
Author

Thank you for your response.
Attached is a file comparing the situation before and after signing:

Before signing – Not blocked by Cloudflare
After signing – Blocked

before.pdf
after.pdf

I would appreciate your assistance in understanding the reason for this.

@vbuch
Copy link
Owner

vbuch commented Feb 11, 2025

Hi @MichalY-WizSoft , I took a look at the files above. Here are my observations:
0. My Acrobat shows a signature panel in "after". There is a valid signature in it.

  1. The signature placeholder is not applied through incremental updates. This means that you did not apply it with plainAddPlaceholder (I was expecting that based on the discussion above)
  2. If "before" is the source file can you also give here the file with the added placeholder?
  3. "before" is PDF-1.6 while "after" is PDF-1.7
  4. Just from looking at the files in a text editor I don't see anything wrong with "after".

@MichalY-WizSoft
Copy link
Author

Thank you for your response @vbuch

  1. Indeed, the signature is legal.
  2. Yes, I started it with pdflibAddPlaceholder.
  3. The after file is a file with a Placeholder and a signature, do you want just a Placeholder without a signature?
  4. The PDF version is probably changing because I read the DATA with PDFDocument.load and then save
  5. The document comes out properly signed - the only problem with it is that it is blocked by Cloudflare.

Since it was blocked, I tried with plainAddPlaceholder

When switching to plainAddPlaceholder, the upload works but the signature is not visible in Adobe Reader

Would you like me to attach a PDF with a signature not visible with plainAddPlaceholder ?

@MichalY-WizSoft
Copy link
Author

@vbuch @dhensby

Can you help or give guidance on how to create a valid signature on PDF 1.6

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants