projectdiscovery/nuclei · error
path %v is outside nuclei-template directory and -allow-loca
Error message
path %v is outside nuclei-template directory and -allow-local-file-access is not enabled
What it means
Thrown by krbforge's normalizeOutputFile when the ticket OutputFile resolves to a path outside the nuclei templates directory while -allow-local-file-access is not enabled. Nuclei sandboxes file writes from JavaScript templates: relative paths are joined onto the template directory, absolute paths must already lie inside it. This guard prevents a template from persisting a forged-ticket ccache to arbitrary locations on the host.
Source
Thrown at pkg/js/libs/krbforge/krbforge.go:236
return normalized, nil
}
normalized := outputFile
if !filepath.IsAbs(normalized) {
normalized = filepath.Join(config.DefaultConfig.GetTemplateDir(), normalized)
}
normalized, err := filepath.Abs(normalized)
if err != nil {
return "", fmt.Errorf("normalize output file %q: %w", outputFile, err)
}
if filepathutil.IsPathWithinDirectory(normalized, config.DefaultConfig.GetTemplateDir()) {
return normalized, nil
}
return "", fmt.Errorf("path %v is outside nuclei-template directory and -allow-local-file-access is not enabled", outputFile)
}
func exportTicketRequest(vm *goja.Runtime, value goja.Value) (TicketRequest, error) {
var req TicketRequest
if err := vm.ExportTo(value, &req); err != nil {
return req, fmt.Errorf("invalid TicketRequest: %w", err)
}
return req, nil
}
func exportOutputFile(value goja.Value) (string, error) {
if goja.IsUndefined(value) || goja.IsNull(value) {
return "", nil
}
outputFile, ok := value.Export().(string)
if !ok {
return "", fmt.Errorf("outputFile must be a string")
}View on GitHub (pinned to 265b3a3dec)
Solutions
- Omit the outputFile argument (or pass '-' / leave output_file empty) so no file is written and the ticket is returned in-memory as ticket_hex/session_key_hex
- Pass a bare relative filename (e.g. 'silver.ccache') so it normalizes inside the nuclei templates directory
- If writing outside the sandbox is intentional, run nuclei with -allow-local-file-access (note: with LFA on, relative paths are placed in os.TempDir(), not CWD)
- Have the template copy the returned hex to the desired sink instead of writing a ccache file
Example fix
// before const t = krb.CreateSilverTicket(req, '/tmp/silver.ccache'); // throws: outside sandbox // after (no file written) const t = krb.CreateSilverTicket(req); log(t.ticket_hex); // after (sandboxed file) const t = krb.CreateSilverTicket(req, 'silver.ccache');
Defensive patterns
Strategy: validation
Validate before calling
// decide up front where the ccache may go
const lfaEnabled = templateallowsLocalFileAccess; // from scan config
let outFile;
if (!lfaEnabled) {
outFile = 'ticket.ccache'; // bare name -> inside nuclei templates dir
} else if (lfaEnabled === true) {
outFile = '/tmp/ticket.ccache'; // allowed with -allow-local-file-access
}
// or skip file output entirely: pass no second argument / no output_file Try / catch
try {
const t = krb.CreateSilverTicket(req, outFile);
} catch (e) {
if (String(e).includes('outside nuclei-template directory')) {
// sandbox denial: fall back to in-memory ticket only
return krb.CreateSilverTicket(req);
}
throw e;
} Prevention
- Default to no OutputFile: the ticket_hex/session_key_hex return values usually suffice
- Never hardcode absolute paths like /tmp/... in templates meant to run under default flags
- Document in the template metadata that -allow-local-file-access is required if a ccache write is intentional
When it happens
Trigger: Calling krb.CreateSilverTicket(req, '/tmp/silver.ccache') or krb.CreateGoldenTicket({..., output_file: '/etc/evil'}) without -allow-local-file-access; also a relative path that escapes the sandbox via '../..' segments, since normalization joins it onto GetTemplateDir() and the IsPathWithinDirectory check then fails.
Common situations: Template authors copying the doc example verbatim (it uses '/tmp/silver.ccache'); running nuclei with default flags where the sandbox is enforced; LFA enabled on one machine but not in CI, so the same template fails only there.
Related errors
- normalize output file %q: %w
- invalid TicketRequest: %w
- outputFile must be a string
- kerberos client is not initialized
- spn is required for silver ticket
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/25478640a984512c.
Report an issue: GitHub.