A document can reference resources that are stored outside of it, for example:
an <img src="https://..."> in an HTML page or in the body of an e-mail message;
a linked (not embedded) picture in a Word document;
a remote style sheet;
an external workbook link.
Starting with version 26.10, GroupDocs.Annotationdoes not load such resources by default. Opening, previewing or saving a document makes no network or file-share request for the resources the document references. A skipped image is rendered as an empty (transparent) placeholder, and the link itself is kept, so a saved document still references the original resource.
Resources stored inside the document are always loaded: cid: parts of an e-mail message, data: URIs and embedded pictures.
The behaviour is controlled by three members of the LoadOptions class:
Called for every external resource before it is loaded. It can allow the resource, skip it, or supply its content.
The options apply to every operation: Get, Add, Save, GeneratePreview and GetDocumentInfo, for Word processing, HTML, e-mail (EML, MSG, MHT), presentation and spreadsheet documents.
Note
Images of an ImageAnnotation are not covered by these options: ImagePath is a resource that your code specifies, not one that the document references. See Network access and data privacy for details.
Skip external resources (default)
No code is needed: external resources are skipped unless you allow them. The following example generates a preview of a Word document with linked pictures without loading them:
using(Annotatorannotator=newAnnotator("remote-resources.docx")){PreviewOptionspreviewOptions=newPreviewOptions(pageNumber=>File.Create($"result_{pageNumber}.png"));previewOptions.PreviewFormat=PreviewFormats.PNG;annotator.Document.GeneratePreview(previewOptions);// linked pictures are rendered as empty placeholders}
Allow trusted locations only
Add the trusted locations to WhitelistedResources. SkipExternalResources stays true, so everything else is still skipped. An entry matches as follows:
Host name, for example "example.com": matches that host and its subdomains.
Absolute URI prefix, for example "https://cdn.example.com/images/": the scheme, host and port must match exactly, and the path matches only on a segment boundary, so /images admits /images/x.png but not /images-private/x.png.
LoadOptionsloadOptions=newLoadOptions{WhitelistedResources=newList<string>{"cdn.example.com","https://intranet.example.com/images/"}};using(Annotatorannotator=newAnnotator("input.html",loadOptions)){annotator.Save("result.html");// only resources from the two trusted locations are loaded}
Uri - the resource address as written in the document;
Skipped - pre-set from SkipExternalResources and WhitelistedResources; set it to true to skip the resource or to false to load it;
Data - set it to supply the resource content yourself; nothing is requested then.
The following example serves a local copy of a picture instead of downloading it, and skips everything else:
classLocalCopyResourceHandler:ExternalResourceHandler{publicoverridevoidOnLoading(ExternalResourceLoadingArgsargs){if(args.Uri=="https://example.com/images/banner.png")args.Data=File.ReadAllBytes("banner.png");// served locally, nothing is requestedelseargs.Skipped=true;}}LoadOptionsloadOptions=newLoadOptions{ExternalResourceHandler=newLocalCopyResourceHandler()};using(Annotatorannotator=newAnnotator("remote-resources.docx",loadOptions)){annotator.Document.GeneratePreview(newPreviewOptions(pageNumber=>File.Create($"result_{pageNumber}.png")));}
Note
Prefer an allow-list over a deny-list. Blocking an address such as http://169.254.169.254/ by pattern is fragile: DNS names, redirects, IPv6 literals and decimal-encoded IP addresses all defeat naive filtering.
Load all external resources
Set SkipExternalResources to false to restore the behaviour of versions before 26.10. Do this only for documents you trust: a document from an untrusted source can make your server request internal addresses (server-side request forgery), and a UNC path can expose the Windows credentials of the process.