(At least) 4 ways to die opening a PDFFri 26 June 2009 by fred
There are several way to trigger events when a PDF is viewed: pushing a button, resizing the document, closing it, reaching a page, when mouse pass on a zone, when an annotation is displayed/hidden, ... but the most interesting from an offensive point of view is when the document is open.
Here come the marvelous /OpenAction. The name speaks for itself.
Anyway, back to /OpenAction. It is really easy to use:
Adding an /OpenAction is straightforward with origami:
pdf = PDF.read( ARGV ) pdf.onDocumentOpen( action )
2. Special combo: select the 1st page to be seen
You can set in a PDF what page has to be seen at first when the document is opened. But you can also set an action when a page is displayed. 1+1=you win.
When you select this option is PDF readers, there is a trick. In fact, this is done once more on /OpenAction: in order to jump to any page, the OpenAction calls a GoTo action. It is then combined with what is called an Additional Action /AA. This kind of action is associated with many objects in PDF, pages, but also annotations for instance. They have special flags (depending on the kind of the object) to trigger the event, like the one will we use when a page is displayed.
So, in the end, the PDF looks like:
Here is the corresponding origami code:
pdf = PDF.read( ARGV ) page = pdf.pages[ rand(pdf.pages.size) ] page.onOpen( action ) goto = Action::GoTo.new( :D => [ page, :Fit] ) pdf.onDocumentOpen( goto )
3. Using annotations when they become visible
You can add some annotations to the PDF document, hide them or not and so on. As explained with the /AA, you can also bind an action to an annotation, especially when it becomes visible.
So, guess what happens when you put an annotation on the 1st page? Yes, it is visible. So if there is an additional action bound to this annotation, it is automatically triggered. Bingo!
And once more the origami source code:
pdf = PDF.read( ARGV ) annot = Annotation::Screen.new annot.Rect = Rectangle[:llx => 350, :lly => 700, :urx => 415, :ury => 640] annot.onPageVisible( action ) pdf.pages[ 0 ].add_annot(annot)
4. Just /Names it
Comparing these methods
When examining how malicious a PDF can be, one can focus on action. There are 2 main objects referring to actions in PDF: /OpenAction and /AA. So, let's compare our 4 methods regarding how they need these 2 commands:
When we state PDF is naturally polymorphic, you have here the semantic proof :)