Whatever message this page gives is out now! Go check it out!

Security

Last update:
May 18, 2026
Document ingestion turns untrusted paths and URLs into text inside your application. That surface is exposed to XML external entities (XXE), server-side request forgery (SSRF) when fetching URLs, path traversal on disk, ZIP bombs, regular expression denial of service (ReDoS) on URL allow/deny patterns, and resource exhaustion from oversized files or unbounded parallelism.
The sections below describe each threat, what ColdFusion's document service protects against, and how to configure limits correctly.
Threat
Attack surface
Primary defence
Path traversal
Filesystem paths
Controlled document root; sanitised Content-Disposition filenames.
XXE
XML and feed parsers
External entity resolution disabled in parsers.
SSRF
URL loading
HTTP(S) only; RFC1918/loopback/metadata IPs blocked; safe redirect handling.
ReDoS
includePatterns / excludePatterns
Safe regex matcher; dangerous patterns rejected or timed out.
ZIP bomb
ZIP archive parsing
maxEntries and maxDepth caps; per-thread depth tracking.
Resource exhaustion
File size, thread count
maxFileSize, maxContentSize, maxThreads; non-positive values rejected.

Path traversal protection

Path traversal (../, ..\) in configured paths can escape intended directories and read sensitive files. Tests append traversal segments under a controlled document root and expect no system file content in results. For URL loads, Content-Disposition filenames are sanitised (path stripped, .. neutralised) so metadata does not carry traversable paths.

What the tests verify

  • Traversal paths appended to the application document directory must not return /etc/passwd or SAM content in docs[1].text.
  • Both Unix (/../../../etc/passwd) and Windows (/..\..\..\..\windows\system32\config\sam) traversal sequences are tested.
  • URL loads: Content-Disposition filenames in HTTP responses are sanitised — path components stripped, .. segments neutralised — before being written into document metadata.
// Appended to application document dir — must not return /etc/passwd or SAM content
traversalPaths = [
  "/../../../etc/passwd",
  "/..\\..\\..\\..\\windows\\system32\\config\\sam"
];
for (tPath in traversalPaths) {
  docs = docService.load({ path: application.getDocumentsDir() & tPath });
  // Assert no leaked system content in docs[1].text
}
Other: The test accepts either safe parsing or a controlled failure — it does not accept file disclosure. Ensure all document source paths are validated against a configured document root before being passed to load().

XXE prevention (XML/feed parsers)

XML External Entity (XXE) attacks embed entity references that pull in local files or remote content during parsing. The suite expects XML and feed parsers to not resolve external entities in a way that leaks secrets (for example /etc/passwd). Legitimate XML without XXE must still parse.

Safe XML load (positive expectation)

Loading a valid XML file with parserType: "xml" and parserConfigs must return parsed content:
docs = docService.load({
  path: expandPath("./Documents/valid.xml"),
  parserType: "xml",
  parserConfigs: {
    xml: {
      includeAttributes: true,
      maxDepth: 5
    }
  }
});

Malicious XXE file (negative expectation)

Loading a file that references an external entity must not place root:, /bin/bash, or similar content into docs[1].text, and must not leak them through error messages. The test accepts either safe parsing or a controlled failure — not file disclosure.
Other: XXE protection must be active for all XML-based parsers including RSS, Atom, and other feed formats — not just files with a .xml extension. Never enable external entity resolution on parsers that process untrusted input.

SSRF protection (URL loading)

Server-side request forgery (SSRF) happens when the server fetches a URL the attacker chooses — often to hit localhost, internal IPs, or cloud metadata endpoints (169.254.169.254) and steal credentials.

What ColdFusion blocks

  • Only HTTP(S) schemes are permitted. Other schemes (file://, ftp://, etc.) are rejected.
  • RFC1918-style private addresses are blocked (10.x.x.x, 172.16–31.x.x, 192.168.x.x).
  • Loopback addresses are blocked (127.0.0.1, ::1, localhost).
  • Cloud metadata endpoints are blocked (169.254.169.254 and equivalents).
  • Redirects are handled safely — no blind following into unsafe chains.
  • Legitimate public HTTPS URLs must still load.
Safe URL load (positive expectation — legitimate public HTTPS URL):
docService = documentService();
docs = docService.load({
  path: "https://www.example.com/robots.txt"
});
Other: Test SSRF protection explicitly in your environment. Cloud-hosted deployments may have access to instance metadata APIs that differ from RFC1918 addresses. Confirm that your ColdFusion version blocks the specific metadata endpoints used by your cloud provider.

ReDoS prevention (include/exclude patterns)

Regular expression denial of service (ReDoS) uses patterns with catastrophic backtracking (for example nested quantifiers like (a+)+) so that matching a URL string hangs the worker. The URL loader is expected to run patterns through a safe matcher that rejects dangerous patterns and handles malformed regex without crashing. Safe patterns must still match when appropriate.

Safe pattern (positive expectation)

A well-formed pattern such as .*robots\.txt must match the target URL and allow the load to complete:
docs = docService.load({
  path: "https://www.example.com/robots.txt",
  includePatterns: [".*robots\.txt"]
});

Dangerous pattern (negative expectation)

A pattern with catastrophic backtracking such as (a+)+ must complete quickly. The URL must not load full content as if the pattern were allowed:
docs = docService.load({
  path: "https://www.example.com/robots.txt",
  includePatterns: ["(a+)+"]
});

Exclude patterns

Exclude patterns are subject to the same safe-matcher requirement. A potentially backtracking exclude pattern must not hang the worker:
docs = docService.load({
  path: "https://www.example.com/robots.txt",
  excludePatterns: ["([a-z]+)+$"]
});
Pattern type
Key
Expectation
Safe include
includePatterns
Matches target URL; load completes normally.
Dangerous include
includePatterns
Completes quickly; URL must not load as if allowed.
Dangerous exclude
excludePatterns
Completes quickly; does not hang the worker.
Note: Both includePatterns and excludePatterns apply to URL loading. They are not applied to filesystem paths. Use glob-style pattern on the path option for filesystem filtering.

ZIP bomb protection (maxEntries, maxDepth)

ZIP archives can contain huge numbers of entries or deeply nested zip-within-zip structures to exhaust CPU and memory. parserConfigs.zip supports limits such as maxEntries and maxDepth. Exceeding limits should yield errors, empty results, or failure documents — not unbounded expansion. Concurrent parsing should use per-thread depth tracking.

Cap entry count

Setting maxEntries: 1 limits the parser to a single ZIP entry. Archives with more entries must not expand beyond the cap:
docs = docService.load({
  path: zipPath,
  parserConfigs: {
    zip: { maxEntries: 1 }
  }
});

Cap nesting depth

Setting maxDepth: 1 prevents the parser from recursing into zip-within-zip structures beyond one level:
docs = docService.load({
  path: outerZipPath,
  parserConfigs: {
    zip: { maxDepth: 1 }
  }
});
Option
Scope
Behaviour when exceeded
maxEntries
Number of ZIP entries
Parser stops processing at the entry limit. Excess entries are not expanded.
maxDepth
Zip-within-zip nesting depth
Parser does not recurse beyond the specified depth. Nested archives at deeper levels are not opened.
Other: ZIP bomb protection applies per-thread when parallel loading is active. Each thread maintains its own depth counter. Always set both maxEntries and maxDepth when processing ZIP files from untrusted sources.

Content size and resource limits (maxFileSize, maxThreads)

Without caps, a single XML document or URL download can allocate excessive memory. Tests use parserConfigs.xml.maxContentSize to reject oversized XML, maxFileSize on load() for both file and URL sources, and verify a default maximum (for example 100 MB) so "unlimited by omission" does not occur.

Content size limits

XML content cap (maxContentSize):
docs = docService.load({
  path: xmlFile,
  parserType: "xml",
  parserConfigs: {
    xml: { maxContentSize: 2048 }
  }
});
Tiny cap on URL response (maxFileSize):
docs = docService.load({
  path: "https://www.example.com/robots.txt",
  maxFileSize: 10
});

Resource limits (parallel, maxThreads, maxFileSize)

Parallel directory loading can spawn many threads. Tests document maxThreads capped (for example at 64), validation that non-positive maxThreads or maxFileSize is rejected, and that defaults are real limits (setting maxFileSize: 1 on a normal file must fail or return a failure document, proving the default is not "unlimited").
Parallel load:
parallelDocs = docService.load({
  path: tempDir,
  parallel: true
});

// Explicit thread count — very large values may be capped
cappedDocs = docService.load({
  path: tempDir,
  parallel: true,
  maxThreads: 1000
});
Option
Applies to
Notes
maxFileSize
File and URL loads
Upper bound on file or response size in bytes. Non-positive values are rejected. Setting maxFileSize: 1 on a normal file must fail or return a failure document.
parserConfigs.xml.maxContentSize
XML parser
Upper bound on extracted XML content size. Oversized documents are rejected before the content is written into memory.
parallel
Directory loads
When true, files are loaded using multiple threads. Use with maxThreads to control concurrency.
maxThreads
Directory loads
Maximum number of threads for parallel loading. Very large values may be capped (e.g. at 64). Non-positive values are rejected.
Warning: Non-positive values for maxThreads or maxFileSize are rejected at configuration time. Always provide positive integers. A default maximum exists for maxFileSize (e.g. 100 MB) — omitting the option does not mean unlimited.
Note: Content size limits and thread caps apply independently. A small maxFileSize does not limit thread count, and a low maxThreads does not limit individual file size. Configure both when loading from untrusted sources at scale.

Share this page

Was this page helpful?
We're glad. Tell us how this page helped.
We're sorry. Can you tell us what didn't work for you?
Thank you for your feedback. Your response will help improve this page.

On this page