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

  1. 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
  2. Pass a bare relative filename (e.g. 'silver.ccache') so it normalizes inside the nuclei templates directory
  3. 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)
  4. 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

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


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/25478640a984512c. Report an issue: GitHub.