Validate Input from Flow Builder
Validate Input Before Processing
DataWeave transformations process any input structure. Without validation, runtime errors can leak schema details, or invalid input can corrupt downstream data.
Do: Check the shape and presence of every input field before use.
Don't: Assume Flow has already validated the input.
Example
Vulnerable
1payload.items map ((i) -> { id: i.id, qty: i.qty })Secure
1if (!(payload.items is Array)) fail("invalid-items")
2else payload.items map ((i) -> { id: i.id, qty: i.qty })Validate Type Coercion
The as operator performs type coercion. Out-of-range or malformed inputs can fail with a leaky error message or pass through with precision loss.
Do: Match the input against a regex or range check before you coerce it.
Don't: Use as Number or as String on user input without validation.
Example
Vulnerable
1{ amount: payload.amount as Number }Secure
1if ((payload.amount as String) matches /^[0-9]{1,9}$/)
2 { amount: payload.amount as Number }
3else fail("invalid-amount")Validate Types in Filter Conditions
Filters on mixed or unchecked types can trigger coercion errors or unintended logic paths. Non-numeric or malformed input can crash the transform or the transform can silently misinterpret it.
Do: Validate the format of each field in a filter expression before you compare the values.
Don't: Apply numeric or boolean comparisons in a filter without first checking that the input matches the expected format.
Example
Vulnerable
1payload.users filter ($.age > 18)Secure
1payload.users filter ((u) -> ((u.age as String) matches /^[0-9]+$/) and ((u.age as Number) > 18))Don't Default Sensitive Fields
A default on a sensitive field hides a missing-required-field error and bypasses your authentication check.
Do: Fail fast when a required field is missing.
Don't: Use default "guest" or similar placeholders in security-sensitive code paths.
Example
Vulnerable
1var userId = payload.userId default "guest"
2---
3{ userId: userId }Secure
1if (isEmpty(payload.userId default "")) fail("missing-userId")
2else { userId: payload.userId }URL-Encode User Input
The connector framework scopes outbound calls to the configured Named Credential's base URI, but path interpolation can still inject traversal sequences or break URL parsing.
Do: URL-encode every user-supplied value before you concatenate it into a URL.
Don't: Build URLs with raw string concatenation.
Example
Vulnerable
1"https://api.example.com/search?q=" ++ payload.qSecure
1"https://api.example.com/search?q=" ++ dw::core::URL::encodeURIComponent(payload.q as String)Allowlist Dynamic Output Keys
A user-controlled value as a DataWeave object key can introduce unauthorized fields such as isAdmin: true into the output. Downstream systems interpret these fields as privileged data.
Do: Validate the key against an explicit allowlist before you use it.
Don't: Use (payload.keyName): ... patterns without checking the key.
Example
Vulnerable
1{ (payload.keyName): payload.value }Secure
1if ((payload.keyName as String) in ["firstName", "lastName", "email"])
2 { (payload.keyName): payload.value }
3else fail("invalid-key")Guard Against Null and Out-of-Bounds Access
DataWeave selectors return null rather than raise an error for missing fields and out-of-range array indices. Chained operations on those null values can fail with leaky error messages or quietly produce wrong output.
Do: Check for null and array bounds before chained access.
Don't: Chain selectors or index into arrays without guarding the inputs.
Example
Vulnerable (null chain)
1{ emailDomain: (payload.user.email splitBy "@")[1] }Secure (null chain)
1if ((payload.user default null) == null or (payload.user.email default null) == null)
2 fail("missing-email")
3else
4 { emailDomain: (payload.user.email splitBy "@")[1] }Vulnerable (array index)
1{ item: payload.items[payload.index as Number] }Secure (array index)
1if ((payload.index as Number) >= 0 and (payload.index as Number) < sizeOf(payload.items))
2 { item: payload.items[payload.index as Number] }
3else fail("invalid-index")Validate Output Before Returning
Even after you validate inputs, the values that you compute or pass through can fail to match the schema that downstream consumers expect. Unvalidated output can corrupt downstream data or carry injection payloads through your connector.
Do: Validate output values against expected ranges, enums, and formats before you return them.
Don't: Trust input-side validation alone. Re-check values that flow to the output.
Example
Vulnerable
1{ status: payload.status, score: payload.score }Secure
1if ((payload.status in ["OK", "FAILED"]) and ((payload.score as Number) >= 0 and (payload.score as Number) <= 100))
2 { status: payload.status, score: payload.score }
3else fail("invalid-output")