{"record":{"id":"099785013027a624","repo":"dotnet/wpf","slug":"sr-resource-xpspackageboundaryviolation","errorCode":null,"errorMessage":"SR.Resource_XpsPackageBoundaryViolation","messagePattern":"SR\\.Resource_XpsPackageBoundaryViolation","errorType":"exception","errorClass":"FileFormatException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/FontCache/FontSource.cs","lineNumber":191,"sourceCode":"            }\n\n            if (bits == null)\n            {\n                Stream fontStream;\n\n                if (_isInternalCompositeFont)\n                {\n                    // We should read this font from our framework resources\n                    fontStream = GetCompositeFontResourceStream();\n                }\n                else\n                {\n                    // Security: When loading XPS content, block font URIs that escape\n                    // the current package to prevent SSRF. Uses stored origin to\n                    // handle deferred loading after XPS parse context has ended.\n                    if (!_fontUri.IsFile && !XpsLoadingContext.IsUriAllowedAgainstPackage(_xpsPackageOrigin, _fontUri))\n                    {\n                        throw new FileFormatException(SR.Resource_XpsPackageBoundaryViolation);\n                    }\n\n                    WebResponse response = WpfWebRequestHelper.CreateRequestAndGetResponse(_fontUri);\n                    fontStream = response.GetResponseStream();\n                    if (string.Equals(response.ContentType, ObfuscatedContentType, StringComparison.Ordinal))\n                    {\n                        // The third parameter makes sure the original stream is closed\n                        // when the deobfuscating stream is disposed.\n                        fontStream = new DeobfuscatingStream(fontStream, _fontUri, false);\n                    }\n                }\n\n                // We don't want any memory leaks\n                // TODO: Remove FinalizableUnmanagedStream once FontFileStream is migrated from C++/CLI.\n                if (fontStream is UnmanagedMemoryStream unmanagedMemoryStream)\n                    return new FinalizableUnmanagedStream(unmanagedMemoryStream);\n\n                // Convert the DeobfuscatingStream to byte[]; add it to our cache, dispose it","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/FontCache/FontSource.cs#L173-L209","documentation":"FontSource.GetUnmanagedStream enforces an XPS package-boundary security check: when loading XPS content, font URIs must resolve inside the current XPS package. A non-file URI that XpsLoadingContext.IsUriAllowedAgainstPackage rejects is blocked with FileFormatException(SR.Resource_XpsPackageBoundaryViolation) to prevent SSRF — a font reference inside a document must not point at an external resource.","triggerScenarios":"Opening an XPS document whose font part URI escapes the containing package — e.g. a pack URI referencing another package (http://, or pack URI for a different package) instead of a resource within the same XPS file, evaluated during deferred font loading.","commonSituations":"Malicious or hand-edited XPS documents referencing remote fonts; documents produced by tools writing absolute URIs instead of package-relative ones; a package origin/context mismatch where the stored XPS package origin no longer matches the font URI at load time.","solutions":["Fix the XPS document so all font part URIs are relative and resolve within the same package.","Re-generate the document with a compliant XPS producer that never emits external font references.","If the URI is trusted, load the font from a local file/stream instead of relying on the XPS package path.","Catch FileFormatException and surface a clear 'untrusted document resource' error to the user."],"exampleFix":"// before (in .xps FixedPage markup)\n<FontUri Source=\"http://evil.example.com/mal.ttf\" />\n// after\n<FontUri Source=\"/Resources/Fonts/1-0.ttf\" />","handlingStrategy":"validation","validationCode":"if (!fontUri.IsFile && !XpsLoadingContext.IsUriAllowedAgainstPackage(xpsPackageOrigin, fontUri))\n    throw new FileFormatException(\"Font URI escapes the XPS package.\");","typeGuard":null,"tryCatchPattern":"try { stream = fontSource.GetUnmanagedStream(); }\ncatch (FileFormatException ex) when (ex.Message.Contains(\"PackageBoundary\") || ex.Data.Count >= 0) { /* reject document */ }","preventionTips":["Use package-relative font URIs in XPS documents.","Never reference http(s) or cross-package fonts inside XPS.","Scan untrusted XPS documents for external resource URIs before loading.","Catch FileFormatException and reject the document."],"tags":["wpf","xps","security","ssrf","fileformatexception"],"backgroundTag":"path-traversal-blocked","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}