shadow1ng/fscan · error

%s %s: %w (webscan_exec_env_error, poc name)

Error message

%s %s: %w (webscan_exec_env_error, poc name)

What it means

executePoc builds the CEL expression environment for a POC by extending the cached base environment with the POC's variable declarations (ExtendEnvWithVars). If environment construction fails, it wraps the failure as 'webscan_exec_env_error <pocName>: <cause>'. The poc name is embedded so you know which POC's expression environment could not be built.

Source

Thrown at webscan/lib/poc_executor.go:147

		value := ""
		if len(item.Value) > 0 {
			value = item.Value[0]
		}
		decls = append(decls, MakeVarDecl(item.Key, value))
	}

	return decls
}

// executePoc 执行单个POC检测
func executePoc(oReq *http.Request, p *Poc, pocCtx *POCContext) (bool, string, error) {
	// 收集POC变量声明
	varDecls := collectVarDeclarations(p)

	// 从基础环境扩展(复用缓存的基础环境,仅添加变量声明)
	env, err := ExtendEnvWithVars(varDecls)
	if err != nil {
		return false, "", fmt.Errorf("%s %s: %w", i18n.GetText("webscan_exec_env_error"), p.Name, err)
	}

	// 解析请求
	req, err := ParseRequest(oReq)
	if err != nil {
		return false, "", fmt.Errorf("%s %s: %w", i18n.GetText("webscan_request_parse_error"), p.Name, err)
	}

	// 初始化变量映射
	variableMap := make(map[string]interface{})
	defer func() { variableMap = nil }()
	variableMap["request"] = req

	// 处理设置项
	for _, item := range p.Set {
		key, expression := item.Key, item.Value
		if expression == "newReverse()" {
			if !pocCtx.DNSLog {

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Look at the wrapped cause after the poc name to see which variable declaration failed
  2. Rename variables in the POC expression to avoid collisions with built-in env vars (e.g. 'request', 'response')
  3. Fix or remove the offending variable declaration in the POC
  4. Rebuild/reset the cached base environment if it was created by an older library version

Example fix

// before: POC var collides with built-in
vars:
  request: "1"
// after
vars:
  reqVersion: "1"
Defensive patterns

Strategy: try-catch

Validate before calling

names := map[string]bool{}
for _, d := range poc.VarDeclarations {
    if reserved[d.Name] { return fmt.Errorf("var %q collides with built-in env var", d.Name) }
    names[d.Name] = true
}

Type guard

func hasSafeVars(p *lib.Poc) bool {
    reserved := map[string]bool{"request": true, "response": true}
    for _, d := range p.VarDeclarations {
        if reserved[d.Name] { return false }
    }
    return true
}

Try / catch

matched, detail, err := executor.Execute(target, poc)
if err != nil {
    if strings.Contains(err.Error(), "webscan_exec_env_error") {
        log.Warnf("POC env build failed, skipping: %v", err)
        return false, "", nil
    }
    return false, "", err
}

Prevention

When it happens

Trigger: Calling executePoc (via the executor's anonymous caller) with a POC whose collectVarDeclarations output causes ExtendEnvWithVars to fail — typically a variable declaration that cannot be added to the CEL environment (duplicate name, invalid identifier, or unsupported declaration type).

Common situations: A POC declaring variables with names that collide with built-in environment variables; malformed or exotic variable declarations in the POC expression; a corrupted or incompatible cached base environment after library/state changes; POC ported from another engine with unsupported syntax.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/50c14061693b816d. Report an issue: GitHub.