Software / code / prosody
Comparison
plugins/mod_http.lua @ 13837:0b63c2c3b563
Merge 13.0->trunk
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Wed, 09 Apr 2025 20:28:28 +0200 |
| parent | 13835:a4b58ea5bf7b |
comparison
equal
deleted
inserted
replaced
| 13831:bf4cd327966f | 13837:0b63c2c3b563 |
|---|---|
| 329 | 329 |
| 330 local trusted_proxies = module:get_option_set("trusted_proxies", { "127.0.0.1", "::1" })._items; | 330 local trusted_proxies = module:get_option_set("trusted_proxies", { "127.0.0.1", "::1" })._items; |
| 331 | 331 |
| 332 --- deal with [ipv6]:port / ip:port format | 332 --- deal with [ipv6]:port / ip:port format |
| 333 local function normal_ip(ip) | 333 local function normal_ip(ip) |
| 334 return ip:match("^%[([%x:]*)%]") or ip:match("^([%d.]+)") or ip; | 334 return ip:match("^%[([%x:]*)%]") or ip:match("^%d+%.%d+%.%d+%.%d+") or ip; |
| 335 end | 335 end |
| 336 | 336 |
| 337 local function is_trusted_proxy(ip) | 337 local function is_trusted_proxy(ip) |
| 338 ip = normal_ip(ip); | 338 ip = normal_ip(ip); |
| 339 if trusted_proxies[ip] then | 339 if trusted_proxies[ip] then |
| 340 return true; | 340 return true; |
| 341 end | 341 end |
| 342 local parsed_ip = new_ip(ip) | 342 local parsed_ip, err = new_ip(ip); |
| 343 if not parsed_ip then return nil, err; end | |
| 343 for trusted_proxy in trusted_proxies do | 344 for trusted_proxy in trusted_proxies do |
| 344 if match_ip(parsed_ip, parse_cidr(trusted_proxy)) then | 345 if match_ip(parsed_ip, parse_cidr(trusted_proxy)) then |
| 345 return true; | 346 return true; |
| 346 end | 347 end |
| 347 end | 348 end |
| 355 local forwarded = http_util.parse_forwarded(request.headers.forwarded); | 356 local forwarded = http_util.parse_forwarded(request.headers.forwarded); |
| 356 if forwarded then | 357 if forwarded then |
| 357 request.forwarded = forwarded; | 358 request.forwarded = forwarded; |
| 358 for i = #forwarded, 1, -1 do | 359 for i = #forwarded, 1, -1 do |
| 359 local proxy = forwarded[i] | 360 local proxy = forwarded[i] |
| 360 if is_trusted_proxy(ip) then | 361 local trusted, err = is_trusted_proxy(ip); |
| 362 if trusted then | |
| 361 ip = normal_ip(proxy["for"]); | 363 ip = normal_ip(proxy["for"]); |
| 362 secure = secure and proxy.proto == "https"; | 364 secure = secure and proxy.proto == "https"; |
| 363 else | 365 else |
| 366 if err then | |
| 367 request.log("warn", "Could not parse forwarded connection details: %s"); | |
| 368 end | |
| 364 break | 369 break |
| 365 end | 370 end |
| 366 end | 371 end |
| 367 end | 372 end |
| 368 | 373 |
| 385 -- Case b) The original request IP is in trusted proxies. In that case, the if branch in the for loop will skip the last IP, causing it to be ignored. The second-to-last IP will be taken instead. | 390 -- Case b) The original request IP is in trusted proxies. In that case, the if branch in the for loop will skip the last IP, causing it to be ignored. The second-to-last IP will be taken instead. |
| 386 -- Case c) If the second-to-last IP is also a trusted proxy, it will also be ignored, iteratively, up to the last IP which isn’t in trusted proxies. | 391 -- Case c) If the second-to-last IP is also a trusted proxy, it will also be ignored, iteratively, up to the last IP which isn’t in trusted proxies. |
| 387 -- Case d) If all IPs are in trusted proxies, something went obviously wrong and the logic never overwrites `ip`, leaving it at the original request IP. | 392 -- Case d) If all IPs are in trusted proxies, something went obviously wrong and the logic never overwrites `ip`, leaving it at the original request IP. |
| 388 forwarded_for = forwarded_for..", "..ip; | 393 forwarded_for = forwarded_for..", "..ip; |
| 389 for forwarded_ip in forwarded_for:gmatch("[^%s,]+") do | 394 for forwarded_ip in forwarded_for:gmatch("[^%s,]+") do |
| 390 if not is_trusted_proxy(forwarded_ip) then | 395 local trusted, err = is_trusted_proxy(forwarded_ip); |
| 396 if err then | |
| 397 request.log("warn", "Could not parse forwarded connection details: %s"); | |
| 398 elseif not trusted then | |
| 391 ip = forwarded_ip; | 399 ip = forwarded_ip; |
| 392 end | 400 end |
| 393 end | 401 end |
| 394 end | 402 end |
| 395 | 403 |