26 June 2023

lighttpd | Behavior of «setenv» directives

I faced with unclear (for me) behavior of «setenv» directives of «lighttpd» webserver and decide perform several experiments and show the results.

Environment and conditions:
  • Ubuntu 22.04.2 LTS
  • lighttpd 1.4.63-1ubuntu3.1
  • Two modifications of default «/etc/lighttpd/lighttpd.conf»:
    • Changed listened port to 3000.
    • Enabled module «mod_setenv».
  • All other changes performs in «/etc/lighttpd/conf-enabled/» folder.
  • Defined two URLs\paths («http://10.0.0.90:3000/» and «http://10.0.0.90:3000/admin/») to show how merging works

Experiments

Example # 1
Description Two config files: «test.conf» and «test2.conf».
All configs use the same «setenv.ADD-response-header» directive.
Configs
/etc/lighttpd/conf-enabled/test.conf $HTTP["url"] =~ "^/" {
        setenv.add-response-header = (
                "X-Test" => "FIRST FILE",
                "X-Frame-Options" => "FIRST FILE",
                "X-XSS-Protection" => "FIRST FILE"
        )
}
/etc/lighttpd/conf-enabled/test2.conf $HTTP["url"] =~ "^/admin" {
        setenv.add-response-header = (
                "X-Test" => "SECOND FILE"
        )
}
Results
http://10.0.0.90:3000/ X-Frame-Options: FIRST FILE
X-Test: FIRST FILE
X-XSS-Protection: FIRST FILE
http://10.0.0.90:3000/admin/ X-Test: SECOND FILE
Conclusion «setenv.add-response-header» directive from the second file replace all headers by single one.

&

Example # 2
Description Two config files: «test.conf» and «test2.conf».
First config uses the «setenv.ADD-response-header» directive.
Second config uses the «setenv.SET-response-header» directive.
Configs
/etc/lighttpd/conf-enabled/test.conf $HTTP["url"] =~ "^/" {
        setenv.add-response-header = (
                "X-Test" => "FIRST FILE",
                "X-Frame-Options" => "FIRST FILE",
                "X-XSS-Protection" => "FIRST FILE"
        )
}
/etc/lighttpd/conf-enabled/test2.conf $HTTP["url"] =~ "^/admin" {
        setenv.set-response-header = (
                "X-Test" => "SECOND FILE"
        )
}
Results
http://10.0.0.90:3000/ X-Frame-Options: FIRST FILE
X-Test: FIRST FILE
X-XSS-Protection: FIRST FILE
http://10.0.0.90:3000/admin/ X-Frame-Options: FIRST FILE
X-Test: SECOND FILE
X-XSS-Protection: FIRST FILE
Conclusion Configs are merged.
«setenv.SET-response-header» directive replace only the value of the specific «X-Test» header.

&

Example # 3
Description «test2.conf» file renamed to «abc.conf» to change the order.
Two config files: «test.conf» and «test2.conf».
All configs use the same «setenv.ADD-response-header» directive.
Configs
/etc/lighttpd/conf-enabled/test.conf $HTTP["url"] =~ "^/" {
        setenv.add-response-header = (
                "X-Test" => "FIRST FILE",
                "X-Frame-Options" => "FIRST FILE",
                "X-XSS-Protection" => "FIRST FILE"
        )
}
/etc/lighttpd/conf-enabled/abc.conf $HTTP["url"] =~ "^/admin" {
        setenv.add-response-header = (
                "X-Test" => "SECOND FILE"
        )
}
Results
http://10.0.0.90:3000/ X-Frame-Options: FIRST FILE
X-Test: FIRST FILE
X-XSS-Protection: FIRST FILE
http://10.0.0.90:3000/admin/ X-Frame-Options: FIRST FILE
X-Test: FIRST FILE
X-XSS-Protection: FIRST FILE
Conclusion First config file (test.conf) replaced the second (abc.conf) because of the order.
«lighttpd does not merge lists from multiple matching conditions. For each specific configuration directive, the last condition that matches a client request and contains that specific directive is the configuration used for that specific directive for that client request»
https://redmine.lighttpd.net/projects/lighttpd/wiki/Mod_setenv

&

Example # 4
Description Two config files: «test.conf» and «abc.conf».
«abc.conf» config use «setenv.SET-response-header» directive to add new header (which was not previously defined).
Configs
/etc/lighttpd/conf-enabled/test.conf $HTTP["url"] =~ "^/" {
        setenv.add-response-header = (
                "X-Test" => "FIRST FILE",
                "X-Frame-Options" => "FIRST FILE",
                "X-XSS-Protection" => "FIRST FILE"
        )
}
/etc/lighttpd/conf-enabled/abc.conf $HTTP["url"] =~ "^/admin" {
        setenv.set-response-header = (
                "X-Test-Set-Response" => "SECOND FILE"
        )
}
Results
http://10.0.0.90:3000/ X-Frame-Options: FIRST FILE
X-Test: FIRST FILE
X-XSS-Protection: FIRST FILE
http://10.0.0.90:3000/admin/ X-Frame-Options: FIRST FILE
X-Test: FIRST FILE
X-Test-Set-Response: SECOND FILE
X-XSS-Protection: FIRST FILE
Conclusion «abc.conf» applied first and «test.conf» applied second.
«setenv.SET-response-header» directive add a new «X-Test-Set-Response» header.

Hope this helps someone.

No comments:

Post a Comment