Forum Discussion
Help needed: HTTP::respond does not add headers
Hi Mats,
you have to use the [eval] command to allow the TCL interpreter to expand the $headers variable before executing the [HTTP::respond] command. Otherwise the collected headers storend in $headers will be counted just as a single parameter.
Warning: Special care must be taken if you use [eval]. The problem of this technique is, that the input may contain TCL syntax (e.g. [somecommand] and $variables) which may accedentially become executed by the [eval] command (aka. its comparable with SQL-Injection for TCL). In the best case this will lead to a broken TCP connection, but in the worst case could also crash your TMM core or even lead into a full compromise of your TMM/TCL environment.
You may take a look to the snipped below to get familar with the usage of [eval] and to learn a syntax how the header values can be securely collected and then passed to eval.
when HTTP_RESPONSE {
if { ( [HTTP::header exists "x-http-statuscode"] )
and ( [HTTP::status] == 200 )
and ( [set xhttpstatuscode [lindex [HTTP::header values "x-http-statuscode"] 0]] != 200 ) } then {
Save response-headers for later use
set headers ""
set x 0
foreach aHeader [HTTP::header names] {
incr x
set input_array(name_$x) $aHeader
set input_array(value_$x) [HTTP::header value $aHeader]
append headers "\$input_array(name_$x) \$input_array(value_$x) "
Explanation: The names and values of your headers are getting temporary stored in a $input_array() variable.
This technique makes sure, that the later use of [eval] never interprets the contained values
as TCL syntax. This technique is comparable to a parameterised SQL query to counter SQL injections.
}
log local0. "Headers Saved: $headers"
eval "HTTP::respond $xhttpstatuscode -version [HTTP::version] content {[HTTP::payload]} $headers"
Explanation: [eval] uses two passes in its execution, the first pass will concentate [command]s
and $variables into eval's input string. And the second pass will execute the input string
as TCL code and concentate [command]s and $variables a second time.
Raw TCL syntax:
eval "HTTP::respond $xhttpstatuscode -version [HTTP::version] content {[HTTP::payload]} $headers"
First pass substitution result:
eval "HTTP::respond 404 -version 1.1 content [HTTP::payload] $input_array(name_1) $input_array(value_1) $input_array(name_2) $input_array(value_2)"
Second pass code execution:
HTTP::respond 404 -version 1.1 content {...} {MyHeader1} {MyHeaderValue1} {EvilHeader} {Evil\[InsertTCLCodeHere\]HeaderValue}
}
}
Additional Note: The [HTTP::payload] command will not output the response payload unless [HTTP::collect] is called and the HTTP_RESPONSE_DATA event is raised.
*Update: Modified my previous post to include the parameterised eval syntax.
Cheers, Kai
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com