Click or drag to resize
Pdf Library for .NET

Security Recommendations for SelectPdf Html To Pdf Converter

Converting HTML to PDF means rendering a web page: the library fetches it, runs its CSS and, unless you say otherwise, its JavaScript. When the HTML or the URL comes from somebody you trust - your own templates, your own pages - there is nothing here you need to do. When it comes from a user you do not know, the conversion runs untrusted content on your server, and the recommendations below apply.

Two of them are switches on the converter. The rest are decisions about where the conversion runs and what it is allowed to reach, which no library setting can make for you.

Control the input

Check what you are about to convert, and prefer a narrow rule to a broad one: accept the handful of URLs, hosts or HTML constructs you meant to support, rather than trying to list everything that could be harmful. Sanitizing hostile input by looking for bad patterns is difficult to get right, and attackers spend their time finding the way around it.

Restrict what the conversion can reach

This is the point most worth your attention. When you convert a URL a user gave you, the page is fetched by your server, from your server's position on the network. A URL that the user could never open themselves - an address on your private network, a service listening only on localhost, an internal admin page, a cloud provider's instance metadata endpoint - is reachable from there, and the rendered result comes back to the user in the PDF.

The same applies to the resources the page pulls in. A page you accepted can reference an image, a stylesheet or a script at any address it likes, and the engine will fetch those from your server too.

  • Put the conversion where it cannot reach anything private. Run it on a host, container or network segment whose outbound access is limited to what a conversion legitimately needs, and block the private and loopback address ranges and the metadata endpoint at that boundary. This is the control that holds, because it does not depend on inspecting the URL.

  • Check the URL before you pass it in, but do not rely on it alone. Accept only the schemes and hosts you intend to support. Be aware that a host which passes your check can redirect to one that would not: the engine follows redirects itself, so a check made before the call cannot see where the fetch ends up.

  • Send the conversion out through a proxy you control if all its traffic should leave by one route - see ProxyOptions and Proxy Options.

Turn off what the conversion does not need

Local file access. If the pages you convert do not load anything from the server's own disk, deny it. A page that cannot open local files cannot use the conversion to read them back to whoever asked for the PDF.

Set it per conversion with DenyLocalFileAccess, which is the right form when only some of your conversions handle untrusted input:

C#
VB
converter.Options.DenyLocalFileAccess = true;

Or set it once for the whole process with ForceDenyLocalFileAccess. This one is not a default that a conversion can override - it denies local file access to every conversion in the process, including your own trusted ones, so a template that loads a logo from disk stops working too:

C#
VB
SelectPdf.GlobalProperties.ForceDenyLocalFileAccess = true;

JavaScript. If the pages you convert do not need it, turn it off with JavaScriptEnabled:

C#
VB
converter.Options.JavaScriptEnabled = false;

Weigh this one against the output you want. Plenty of modern pages build part of their content in script, and with JavaScript off those pages convert incomplete or empty rather than failing outright - so check the result before you settle on it.

Put a bound on the work

A page that never finishes loading holds a conversion open. Cap it with MaxPageLoadTime, in seconds, so one request cannot occupy a converter indefinitely:

C#
VB
converter.Options.MaxPageLoadTime = 60;

Set it alongside whatever limit your application already puts on how many conversions can run at once, and on how large a document a single request may produce. See Conversion Delay and Timeout.

Restrict access to the service itself

If the application that performs conversions is only ever called from known places, say so at the network boundary and limit the addresses allowed to reach it. Convert-anything-for-anyone is a service worth putting behind authentication and a rate limit, whatever else you do.

See Also