Thursday, February 21, 2013

Converting untrusted PDFs into trusted ones: The Qubes Way

Arguably one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 biggest challenges for desktop security is how to handle those overly complex PDFs, DOCs, and similar files, that are so often exchanged by people, or downloaded from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Web, and that often provide a way for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker to compromise cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user's desktop system.

Today I would like to discuss a recent innovation we created for Qubes OS that allows to securely convert those pesky PDFs (as well as essentially any graphics files) into trusted PDFs. Here by a “trusted PDF” I mean a file that should be harmless to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user's system, so, a non-malicious PDF.


A few years ago, we have already introduced a mechanism in Qubes OS called Disposable VMs, that can be used to safely open any file, including PDFs, DOCs, etc. The file is being opened in a... well a dedicated disposable VM that is created within seconds (typically below 5 seconds) and all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file processing and rendering happens inside this VM. Once cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 document is closed, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 disposable VM is automatically destroyed, and any changes to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file (e.g. if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 was an editable DOC file) are automatically propagated back into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original file. This mechanism is very powerful, and I often use it for my daily work. However, it surely is a bit cumbersome – who wants to wait 5 seconds for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PDF to open, especially if I have a dozen of invoices to look through! So, today I present an alternative approach...
 
Approaches to converting PDFs

The problem of converting a potentially untrusted PDF into a harmless one is certainly not a new one. Some tools have already be created for this task.

The typical approach is to parse cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original PDF, look for “potentially dangerous things” cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re, and remove cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m. As simple as that! This is, of course, a typical AntiVirus approach to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 problem. And, typically as it is for most AV approaches, it's completely useless against any more skilled and determined attacker (and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ones we fear cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most, don't we?).

A somehow better approach is to parse cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original PDF, disassemble it into pieces, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n reassemble cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m into a new PDF only using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “trusted” pieces – this, I think, could be called a whitelisting approach.

Anyway, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fundamental problem with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 approaches mentioned above, is that all of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m require parsing of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original PDF file. And parsing is where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “big bang” usually happens. Parsing is where our, normally pretty decent, code, comes in close, intimate contact with some unknown complex input data, which often leads to a successful abuse or exploitation.

Parsing PDFs safely

So, how to perform parsing safely? Of course, that's simple! Let's run cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 parser in an isolated container – in case of Qubes we already have an ideal such container: it's cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Disposable VMs.

But, before we get too excited, let's think more about it – say we run cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 parser safely isolated in a Disposable VM, meaning it couldn't harm any of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rest of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system, except for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Disposable VM itself, which we however won't worry much about, because it is disposable... But cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n what?

We want our PDF back in our original VM, to actually use it, right? But we cannot just copy cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Disposable VM, because if it got compromised, as a result of parsing of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 malicious PDF, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n we would like get... a compromised converted PDF. So, this approach gives us nothing!

(Even though our “solution” incorporates all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 obligatory buzzwords: “Disposable VMs” (“Micro Disposable VMs”?), “VMs isolated using hardware Intel vPRO technology” and, of course, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “hypervisor”! Sometime just cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mere fact we use “hardware virtualization” buys us nothing... People seem to forget about this sometimes.)

So, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 trick to make this approach meaningful is to introduce what I will call a “Simple Representation” of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 input file. More on this, straightforward concept, below. The idea is that our parser (that runs in a Disposable VM) will be expected to return cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Simple Representation of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original PDF. Of course, it might very well go wild (as a result of exploitation by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PDF it parses), and don't obey our expectations, and instead return something totally different and potentially malicious. But that doesn't matter! The whole point of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Simple Representation is that it should be, well... simple to parse it safely and discard in case what we're getting doesn't look like cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Simple Representation.

Ok, so what's cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 simplest possible representation of an arbitrary PDF file? Yes, it's cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 RGB format, which is essentially just a raw array of RGB values for each pixel. In fact, I'm not sure cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re could be anything simpler in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Known Universe to represent a PDF file...

Now this is all becoming simple: we would expect our parser to send us just two things: cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 dimensions (W x H) of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bitmap representation of each of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 page of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PDF in question, and each of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PDF page itself converted into a raw RGB format. If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 parser didn't obey, we would still interpret whatever stream of bytes we get as a RGB bitmap – in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 worst case cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PDF we create would look like un-tuned analog TV screen.

The diagram below summaries this idea:



Implementing this all on Qubes

Now I would like to show how easy it is to implement such PDF converter service using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Qubes advanced infrastructure that we call qrexec, and which is part of Qubes core for quite some time now.

First, let's choose cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PDF and image conversion tools. The choice of PDF converter is not security critical, because it will run in an isolated Disposable VM. Here I decided to use pdftocairo converter, which is part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 poppler-utils package on Fedora. We will also use ImageMagick's “convert” command to convert cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PNG files (produced by pdftocairo, one for each PDF page) to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 raw RGB format. Incidentally ImageMagick supports RGB format natively. As mentioned above, in addition to sending cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 raw RGB file, we would also need to send cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 width and height of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pixmap – those can easily be obtained using ImageMagick's “identify” command. Again, all those programs discussed so far are not security critical – cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y might get exploited during cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 processing of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 untrusted input PDF file, and we don't worry about that at all.

On cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 receiving side, however, we need to use a foolproof parser for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 RGB format. Again, this is what we gain in this whole process – instead of requiring a foolproof-and-also-being-able-to-produce-non-malicious-PDFs parser, we only require a foolproof RGB parses, and that's quite a gain! The ImageMagick's convert comes to mind again here, and one might want to use it like this:

convert page.rgb page.pdf

Unfortunately this would be wrong, because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 convert program would still try to detect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “real” format of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 page.rgb file, and, if it looked more like, say, JPEG or PDF, it would parse it accordingly, compromising all our careful plan! What we really need is to tell our convert program to always treat cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 input as raw RGB file, instead of trying to be (too) smart and trying to guess cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 format by itself. This can be achieved by adding cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “rgb:” prefix in front of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 input argument, which provides explicit input format specification:

convert -size ${IMG_WIDTH}x${IMG_HEIGHT} -depth ${IMG_DEPTH} rgb:$RGB_FILE pdf:$PDF_FILE

Now also needed to add size and depth explicitly, because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 raw RGB format doesn't convey such information (well, it has no header of any sort at all!). Of course we need to obtain cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 width and height from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 parser, but we can validate such input racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r easily. In addition we make sure that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 received RGB file has exactly cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 size as indicated by width and height. With those precautions in place, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re would have to be really a gapping hole in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ImageMagic's RGB parsing code for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker to exploit this. Perhaps instead of using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ImageMagick's convert I should have written a small script in python that would parse cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 received RGB file (and save it into a... RGB file, for later processing by ImageMagick), but I sincerely think this would be an overkill here. 
 
Finally we can write cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following two simple bash scripts, one for client: qpdf-convert-client, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r one, qpdf-convert-server, for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server (which runs in a Disposable VM).

Additionally we also need to create a policy file in Dom0 in /etc/qubes_rpc/policy/ to allow to use this service. The policy file content for this service should look like this:

$anyvm $dispvm allow

... which is pretty self explanatory. When I do development I also add anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r line to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 policy file like this:

$anyvm devel-vm ask

... to allow me to run cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server inside my 'devel-vm' VM, instead of running it in Disposable VM every time, which would be very inconvenient for development, as it would require me to update cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Disposable VM template each time I wanted to test a new version of qpdf-convert-server.

The policy file should be placed in Dom0 in /etc/qubes_rpc/policy/qubes.PdfConvert file – here cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 name of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file must be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 name of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 service, as invoked via qrexec_client_vm command, discussed below.

And, one last thing, in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 destination VM we must also create a file that will map cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 service name (so, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 qubes.PdfConvert in our example) to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 actual binary that should be called in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 VM when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 service is invoked. So, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file should be named: /etc/qubes_rpc/qubes.PdfConvert (again, this is now in a VM, not in Dom0, also note cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lack of policy/ subdir), and it is anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r one-liner with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following content:

/usr/lib/qubes/qpdf-convert-server

The full source code of qpdf-converter can be seen and downloaded from this git repo.

We're ready now to test our qubes.PdfConvert service: in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 requesting VM, i.e. cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 one from which we want to initiate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 conversion process we do:

[user@work Downloads]$ /usr/lib/qubes/qrexec_client_vm '$dispvm' qubes.PdfConvert /usr/lib/qubes/qpdf-convert-client ITLquote.pdf
-> Sending file to remote VM...
-> Waiting for converted samples...
-> Receving page 2 out of 2...
-> Merging pages into a single PDF document...
-> Converted PDF saved as: ITLquote.trusted.pdf
-> Original file saved as .ITLquote.pdf

Again, for development process I would replace '$dispvm' with something like 'devel-vm'.

The qrexec_client_vm command, used above, is not actually intended to be used by user directly (that's why it's installed in /usr/lib/qubes instead of /usr/bin/), and so when one creates a Qubes qrexec service, it's customary to create also a small wrapper around qrexec, like this one, that makes using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 service simple.

The presented converter saves cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original file as .${original_pdf} making it a hidden file to help cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user avoid accidental opening. The new, converted file gets .trusted.pdf suffix appended to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 base name of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original file. I discuss more issues regarding cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 human factor and avoiding accidental opening in one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next paragraphs below. The converter can also be used to convert essentially any image file, such as JPEG, PNG, etc, into a PDF, using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same method.

As you can see creating client-server services in Qubes is very simple – in fact it took me just one afternoon to get cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 inital working version of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 converter (with subsequent "polishing" over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next 2 days).

The qrexec infrastructure takes care about all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 under-cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365-hood tasks, such as starting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 necessary VMs, e.g. creating Disposable VM to handle cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 service request,establishing communication channels between VMs (which are ultimately implemented on top of Xen's shared memory), redirecting client and server's stdin and stdout to each ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r, so that writing services is very simple, even in shell, and, of course, obeying policies defined centrally in Dom0.

Most “inter-VM” features in Qubes, such as secure file copy between domains, opening files in Disposable VMs, time synchronization, appmenus synchronization, etc, are all implemented on top of qrexec. A notable exception is clipboard exchange, which is implemented as part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 GUI protocol, but still uses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same common qrexec code for policy processing (e.g. I use this policy to block clipboard and file exchanges between my work and personal domains).

Limitations, ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r Simple Representations

The obvious disadvantage of converting a PDF to an RGB representation is that one looses text search, as well as copy and edit capabilities (e.g. in case of PDF forms). So, converting Intel's IA32 Software Developer's Manual this way would certainly not be a good idea... But, hey, such large PDFs can always be opened in a Disposable VM – cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y would be fully functional cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n, only that you would need to wait a few seconds for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PDF window to pop up. Or, better yet, why not keep all such PDFs in a dedicated domain? E.g. I have a VM called “work-pub” where I keep tons of various, publicly available PDFs, such as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mentioned Intel's SDM, as well as various chipset docs, conferences papers and slides, and generally lots of stuff. The key point is that all in this VM is public material (and also all is related to my work), so that I don't really care if any of those PDFs compromises my work-pub domain. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 worst case, I will revert cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 VM from backup and download any missing PDFs again from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 web. They are public after all. 
 
But cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PDF conversion described above comes extremely useful in case of all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 various invoices, Purchase Orders, NDAs, contracts, and god-knows-what-else PDF documents, which I'm forced to deal with in my “work” domain (where my email client runs). Most of those are one pagers, or maximum a few pages long documents, so cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fact that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y got converted to a bitmap provides me with very little discomfort. At cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same time I gain incredible freedom in opening all those documents natively in my work VM, without fearing that one of those invoices will comrpomise my work domain (which would be a racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r sad thing for me, although cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 really sensitive stuff is still in some ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r domains ;)

An interesting question is, however, can we come up with anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r form of Simple Representation that would allow e.g. to preserve cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 text searching ability of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 converted PDFs (and DOCs, PPTs)? Probably... yes. The choice of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Simple Representation should be thought of as of a trade-off between security and document's features preservation. I'm not an expert on PDF and DOC formats (and I'm not sure I want to be) but it seems plausible that one could disassemble PDF into simple pieces, select cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 really simple ones, send those pieces as a Simple Representation back to client, and have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m reassembled back into a almost-fully-functional PDF. Here, again, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 point is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PDF parsing is done in isolated Disposable VM, while cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reassembly in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 trusted VM. Anyway, let me leave it as a exercise for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reader :)
 
Preventing user mistakes

Being able to right-click on a PDF file and have it converted into a trusted PDF is one thing. Having this mechanism adopted by users and actually making cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir daily computing safer, is anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r story.
Users will likely have hundreds of PDF spread over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir home directories, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 real challenge is how to make sure that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user never accidentally opens cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 unconverted, untrusted PDF. We can think of several approaches to this problem:
  • We modify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Thunderbird, Firefox, etc, e.g. by providing specific plugins, to always perform PDF conversion on each file that we got via email or downloaded from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Web. Additionally we convert all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 already present PDFs in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user's home directory (file system?). And, additionally, we modify Qubes file copy operation to also always do automatic PDF conversion whenever one transfers files from ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r domains (if Qubes qrexec policy allows for such transfer in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first place, of course).

This approach would not be optimal, because some PDFs, as we discussed above, might not be well suited for conversion-through-bitmap process – cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y might be large PDFs where text search is crucial, some conference papers for review, where text copy is crucial, or some editable forms. That's why it seems better to take a slightly different approach:
  • We modify mime handlers for PDF files (as well as any ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r files that our converter supports) and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n upon every opening of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file (e.g. via mouse click in a file manager) our program gets to run and its job is to determine whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file should be opened natively, converted to a trusted PDF, or perhaps opened in a Disposable VM. Of course, upon “first” opening we should probably ask cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 decision, if this cannot be determined automatically. E.g. if we can reliably determine cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file is already converted, we can safely open it without prompting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user, but if it's not, we should ask – perhaps cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user would like to open it in a Disposable VM instead of converting, or perhaps cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file should be considered trusted anyway, because it was created by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user herself.

This second approach seems like a way to go, and we will likely implement it sooner or later (probably sooner, but after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 upcoming R2 Beta2). It should also be noted, that typically user would need such mechanism only in some domains – e.g. I really feel cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 need for such protection in my “work” domain, but not in any ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r. But that, of course, depends on how one partitions cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir digital life into security domains.

One important detail worth mentioning here, is that we should unconditionally disable “Thumbnail View” in whatever file manager we use (which itself is really a stupid feature – can people not read filenames anymore or something?).

Qubes: from containers isolation down to apps protection

The mechanism introduced today, in addition to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Disposable VMs mechanism introduced earlier, represents a trend in Qubes development of “stepping down” into AppVMs in order to also make cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 VMs cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365mselves somehow more secure (in addition to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 isolation between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 VMs).

Originally Qubes aimed at containers isolation only. This included protecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system TCB where techniques such as deprivileged networking stacks (and optionally also deprivileged USB stacks) have been deployed, as well as custom GUI virtualization, and generally somehow “hardened” Xen configuration. This also included protecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 VMs from each ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r, where techniques such as secure clipboard, secure file copy and generally secure qrexec infrastructure have been introduced, as well as trusted GUI subsystem with explicit domain decorations.

But now, Qubes is stepping down into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AppVMs in order to make cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 VMs cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365mselves also less prone to compromise. We surely will be working on more such mechanisms in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 future. We still are only at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 beginning of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 quest to create a Reasonably Secure Desktop OS!

PS. The presenetd converter will be part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Qubes R2 Beta 2, that is expected to be released... in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 comming days. Experienced users of Qubes R1 and R2 Beta 1 can install cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 converter immediately by building cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rpms from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 git repo.


PS. WTF is happening with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Blogger web interface? Seriously, I don't remember being so frustrated using any software in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 recent years that I am right now, when editing this post (as well as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last several ones). It sometimes honours cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 line breaks, sometimes do not, sometimes inserts a couple of new lines, sometime removes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, sometime mysterious spaces appear at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end of lines, sometime those cannot be removed... It doesn't allow to paste pre-formatted code-listing (at least I couldn't figure out how to make it honour tabs). And yes, I'm using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 "Compose mode", because when I try to switch to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 HTML mode, not only I'm overwhelmed with tons of HTML markups, nobody knows what for, but also when I switch back to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Compose mode, my article tends to get even more fucked up! Really, a shame. I wish I could go away to some ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r blogging service, but I'm afraid that converting all my posts would be even a bigger PITA... Sigh.

23 comments:

nicolas said...

Your raw RGB format is actually extremely close to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Windows BMP 24 so you could have used that. The header only really contains width and height.

You could keep a pre-loaded disposable VM in memory to make disp vm startup faster. I do not know at what point of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 loading portion cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y need to be "specialized"

Joanna Rutkowska said...

@nicolas: it's not "mine", it's ImageMagick's.

Also @nicolas: how many Disposable VMs should you keep in a queue to look through a dozen of invoices in a folder?

dragosr said...

The best way to parse PDFs safely is still probably to parse cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m safely with safe code. Applying a band-aid on a turd still leaves you with a turd. interesting ideas though. right now I use a sacrificial machine for pdfs - kind of a real world physical equivalent of your VMs, and a little less bocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r at a little more hardware expense.

nicolas said...

I am just suggesting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same approach used to speed up ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r things (pre-loading tabs, linked pages, hard drive blocks,...). I assume that it could be tweaked based on available (meaning not used, or wasted...) memory. There is always a draw back.

Joanna Rutkowska said...

@dragosr: I don't quite understand what criteria you used to state that "safe code is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 best way to parse PDFs safely"? The absolute safety of so called "safe languages" is a myth -- ever wondered why Singularity never taken off?

Also @dragosr: Using a "sacrificial machine" for PDF processing, whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r it is real or virtual, is only good if you deal with unclassified, public PDFs only. But if you need to open a confidential contract, or NDA-protected documentation, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n using a sacrificial machine would be irresponsible at best, and might even get you into legal problems if those confidential PDFs leak out of your "sacrificial machine", because every decent NDA would explicitly require you to treat cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 confidential material given to you with great care. And, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n, on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r hand, it's also unreasonable to assume that every non-public PDF is non-malicious.

Theodoros said...

Joanna nice post!!!!

Have you ever thought on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following solution ?
http://www.sans.org/reading_room/whitepapers/intrusion/animal-farm-protection-client-side-attacks-rendering-content-python-squid_33614

Its used python and squid to render cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pdfs.

Joanna Rutkowska said...

@Theodoros:

1) Your solution is a centralized one -- not only it creates privacy concerns and cannot be used for end-to-end encrypted documents, but also is much less secure, as if your "safe" parser got compromised than it will be able to steal all subsequent documents (and leak cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m out to China) as well as infect clients by serving cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m malicious PDFs.

2) Your approach to process PDF is what I described in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 article as a black list solution, with all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 usual problems such solutions have.

In ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r words I fail to see how this solution could be better than just using a somehow "hardened" PDF viewer. Actually cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 latter would be better because we avoid cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 centralized single point of failure, i.e. your proxy.

Joanna Rutkowska said...

... of course we can also run such proxy in a Disposable VM, no problem, if somebody likes blacklisting approaches. Here cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 benefit would be that we don't have a centralized single point of failure that can later turn against us.

Jake said...

i think this, and qubes in general, is an interesting approach to overall security. however, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 complexity of it all seems racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r high.

cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re have been lots of exploits for adobe products published but comparatively fewer for open source pdf viewers, e.g. xpdf. how do you justify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 increase in complexity versus cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 likelihood of various attack vectors, e.g. owned windows machine with an adobe pdf exploit?

Joanna Rutkowska said...

@Jake: if you consider RGB parsing to be "complex", cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n I wonder what do you possible consider to be "simple"? ;)

Jake said...

nice way of not answering my question. ;)

Dwight_Chroot said...

Wow, I understand your approach, despite copy-paste shell scripting "ability;" I'm going to try out Qubes, I need at least one software environment that works.
Probably cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most useful thing I can contribute is this: You need Free(as in GNU) hardware for this to end well, O level ownership from microcircuitry to microcode on up, ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rwise fake security(opacity) will trump real security. And a clean electricity/EMF environment or it may well "Blogger" on you due to institutional resistance to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 "dangerous" notion you have a right to do things on your computer unmolested;)

Alon said...

Hi Joanna,
Nice post and an interesting approach. Some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original motivation for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PDF format was saving space. The PDF is (to my knowledge) a vector format, which saves lots of space on big documents. Since you convert it back to RGB-based, it's uncompressed and I assume it'll take a lot of space, like BMP files mentioned by anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r comment. The next reasonable step in your approach would be IMHO to switch to better representation of graphical data, e.g. use JPG or ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rs instead of "pure" RGB representation. I guess you've probably considered it by now.

BTW I personally think that in terms of functionality and scalability, as you remarked with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Intel example, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 solution must be white list, i.e. disassembling and building it back.
The PDF is overall a good format, it just uses a little bit too much functionality. You're solution basically destroys cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 format completely :)

Anonymous said...

Alon: A jpg parser is significantly more complex than a raw RGB one. In fact one could say that raw RGB data needs no parsing, just read into memory and display.
If space is a concern cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n a simple run-length-encoding scheme which is trivial to implement safely would improve cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 situation.


Jake: It is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 premise that is important here, not a specific implementation. XPDF lacks a lot of features that modern PDF viewers offer and even so, I do not think that one can say with certainty that it is "safe code" since nothing has been formally proven. Even if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are no publicly disclosed XPDF vulnerabilities, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fact remains that it could still be vulnerable.

I think that people should focus more on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ideas and premises behind Joanna's posts (which are all solid and offer tangible security benefits, something that is extremely rare in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 defensive domain) than trying to come up with more user-friendly (yet inherently flawed) alternatives to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 specific scenarios that she brings up.

Compartmentalization works because it allows one to think about risk and exposure and *factor* cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m into his everyday decisions. It may not be as simple as click-and-forget but it is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 best solution we have today and Qubes does an excellent job of balancing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 scales.

Joanna Rutkowska said...

Actually cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 image compression code can be of arbitrary complexity, as one would normally be doing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 compression in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 trusted VM on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 already verified RGB format. So, unless we fear attacks that could exploit a compressor by feeding it with "strange" bytes to compress (in contrast to feeding a decompressor with strange input file), a racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r unthinkable situation for any real-world compressor IMO, we should be fine with any compressor.

Anonymous said...

Security by correctness seems more relevant here. The parser can be small enough to allow cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 demonstration of its correctness. I mean a formal demonstration like one would do with a macá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365matical cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365orem (taking into account cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 way numbers are represented, memory limitations, etc). (You can show that whatever data (not necessarily pdfs but any random data) is fed to your program, it will always behave as expected.)

All this parser need to do is locate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 safe areas (white listing) and transmit it to a second program which will turn it into a correct (striped) pdf file (or something different).

All this assume we can trust system calls for disk access. If we can't, it means that storing, copying or reading it (eg. with an hexadecimal reader) will compromise cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system.

Joanna Rutkowska said...

@anonymous-who-thinks-one-can-formally-prove-a-pdf-parser: your comment made me laugh.

Anyway, if you think this is all that simple, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n where is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code? Everybody is good at talking, but few can actually write something, huh?

Anonymous said...

I am actually working on it (and ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r things more or less related) on my free time. I am still documenting myself on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pdf format.

Code comes last. You need a good design first. Things can be made simple on purpose. If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 white list is pretty restrictive and hardcoded in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 parser, I am confident it is doable.

One does not have to do it in one go. One can first demonstrate that a function does what it is meant to do considering its ins and outs. Once done one can just assume cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function works correctly and considere cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bigger picture without going back on it.

Most of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 proof is done by exhaustion considering a general case and a lot of special cases (boundaries, overflow, etc).

Automatising it is hard but doing it by hand is relatively easy (with common program structure : no self modifying code, etc). It is just time consuming but with a program small enough it is manageable.

A parser that copy what it recognize and ignore cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rest can be fairly small.

anonymous-who-thinks-one-can-formally-prove-a-pdf-parser (and made you laugh)

Unknown said...

Let me say I admire your work Joanna and I am not a PDF expert eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r.
Racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r than go cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 "Raster" (RGB Bitmap) route I would go cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 "Vector" one and better yet using a Declarative e.g.

XML-based format supporting both Raster and Vector data with robust parsers but without embedded Procedural Code

like PDF and PS ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r than within well defined tags like "script" that can be readily stripped.
This problem with embedded "code" exists for all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se big major file formats including MS and Open Office files

and such things as CAD files and will be a constant bugbear for security (and not limited to, but also including

your Qubes). XML based file formats are a saving grace given cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 simpliity and ubiquity of tested parsers along

with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data/code divide mentioned.
Consider a series of transformations between formats with each one using a different parser that also to strip out

all code and macros (and so cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re will be no dynamism or animated imagery in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 regenerated PDFs for example). If

you do enough transformations with enough code stripping cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n nothing is going to get through as an attacker would

have to target multiple vulnerabilites accross multiple libraries in order to do so and such a chain can be

arbitrary or random both in terms of components used and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 length of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 chain e.g.:

PDF => ... => .... => PDF

You are currently using Bitmaps but SVG would be a much better option:

PDF => SVG => PDF

There is open source available including multiple Apache PDF engines along with SVG2PDF and PDF2SVG

projects available.

Feel free to contact me offline to discuss furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r since I really wanted to follow Gandalf's advice and: "Keep it

secret; Keep it safe..." before I actually started writing this...

Unknown said...

GSview PStoEdit:
http://pages.cs.wisc.edu/~ghost/gsview/pstoedit.htm
Converter to Vector Formats:
http://www.pstoedit.net/pstoedit/
Including SVG:
http://www.helga-glunz.homepage.t-online.de/plugins/

Assuming you can get cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source.
I can't help with needing to spawn a Disposable VM to securely do cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 conversion... BUT you should need to: (A) you can have a list of one more DVMs pre-running ready to go (B) you could reuse such PDF->SVG conversion DVMs after some number of jobs or for a session sending cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m back to sleep to await cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next conversion job... Unfortunately you might have to compromise security for your sanity here but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SVG (XML) output of a behind cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 scenes PDF Converter should not propagate infections...

J.M. Porup said...

Joanna

cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 links to git.qubes-os.org all return 404. Would like to take a look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 wrapper scripts.

thanks
j

Joanna Rutkowska said...

@J.M. Porup: cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 repo has been renamed since that time, hence cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 links are giving 404s. The repo is now here:

http://git.qubes-os.org/?p=joanna/antievilmaid.git;a=summary

You should be able to find all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 referenced files in this new repo.

Joanna Rutkowska said...

Sorry, wrong URL, this is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 correct repo, of course:

http://git.qubes-os.org/?p=joanna/qubes-app-linux-pdf-converter.git;a=summary