Repository navigation
Commit fc41009
authored
Merge commit from fork
* fix: trust forwarded scheme headers only from trusted proxies
Context.Scheme() used X-Forwarded-Proto, X-Forwarded-Protocol,
X-Forwarded-Ssl and X-Url-Scheme from any client, so a direct client
could send X-Forwarded-Proto: https over plain HTTP and bypass
middleware.HTTPSRedirect() (GHSA-2ffq-g2xg-c22p).
The headers are now used only when the request comes directly from a
loopback, link-local or private network address or a unix socket.
Echo#SchemeExtractor (and Config.SchemeExtractor) selects the strategy:
ExtractSchemeFromHeaders (default, accepts TrustOption),
ExtractSchemeDirect, or LegacySchemeExtractor for the old behavior.
The Secure middleware now uses Context.Scheme() for HSTS, and the Proxy
middleware always sets X-Forwarded-Proto from Context.Scheme() instead
of forwarding a client-supplied value.
* fix(proxy): always set X-Real-IP from Context.RealIP()
The Proxy middleware forwarded a client-supplied X-Real-IP header to the
upstream when Echo#IPExtractor was not set, so any client could spoof
the IP address seen by upstream services (GHSA-99jh-6h7p-pp36).
Since v5.1.0, Context.RealIP() returns the address of the direct peer
unless Echo#IPExtractor is configured, so the header is now always set
from Context.RealIP().
* fix: validate JSONP callback and send nosniff header
Context.JSONP and Context.JSONPBlob wrote the callback into the response
unchanged, so a callback taken from a query parameter could inject
arbitrary JavaScript (GHSA-h9g5-28mm-hx3g).
The callback must now be empty, a JavaScript identifier or a
dot-separated path of identifiers (ASCII letters, digits, _ and $).
Otherwise nothing is written and a 400 Bad Request error wrapping
ErrInvalidJSONPCallback is returned. JSONP responses also get the
X-Content-Type-Options: nosniff header.
Claude-Session: https://claude.ai/code/session_01QKDYQr53zNKkR7nif2CAAq
* fix(method-override): do not override POST to safe methods
MethodOverride rewrote a POST to any method, including GET and HEAD.
When the middleware ran before CSRF, a cross-site form POST with
_method=GET skipped the CSRF check (GHSA-r7w9-592q-9vg4).
POST can no longer be overridden to GET, HEAD, OPTIONS, TRACE or
CONNECT. The documentation now also says to register the middleware
with Echo#Pre.
Claude-Session: https://claude.ai/code/session_01QKDYQr53zNKkR7nif2CAAq
* fix: percent-encode control characters in redirect paths
The trailing slash middlewares and the static directory redirect only
collapsed a leading double slash. Browsers remove tab and newline
characters from URLs, so a path such as /%09/evil.example/ produced
Location: /\t/evil.example/, which a browser follows to evil.example
(GHSA-v753-g4cw-jm48).
sanitizeURI now percent-encodes C0 control characters and DEL before
the double slash check, so the browser requests the same path.
Claude-Session: https://claude.ai/code/session_01QKDYQr53zNKkR7nif2CAAq
* fix(static): resolve files from the routed path and reject dot segments
The Static middleware resolved files from the decoded URL.Path while the
router matched the escaped URL.RawPath, so /admin%2Fsecret.txt or
/%61dmin/secret.txt reached a file under a guarded /admin/* route
(GHSA-375p-5qhx-8wq4). It now uses the same form of the path as the
router and unescapes it only when EnablePathUnescaping is set.
Both the Static middleware and StaticDirectoryHandler (Echo.Static,
Echo.StaticFS) resolved file names with path.Clean(), while the router
matched the path as sent. A path with a ".", ".." or empty segment,
such as /assets/../admin/secret.txt, could therefore reach a file under
a route the router never matched (GHSA-3pmx-cf9f-34xr). Such paths are
no longer served. The documented opt-in behavior of encoded dots with
path unescaping enabled is unchanged.
Claude-Session: https://claude.ai/code/session_01QKDYQr53zNKkR7nif2CAAq
* docs: changelog for security release and Static middleware guard note
Claude-Session: https://claude.ai/code/session_01QKDYQr53zNKkR7nif2CAAq
* fix: harden security fixes after review
- Scheme: when X-Forwarded-Proto is present, use only it (its last
value, added by the nearest proxy) instead of falling back to other
headers, and return the scheme in lowercase so HTTPSRedirect and HSTS
work with "HTTPS".
- Proxy: remove X-Forwarded-Ssl, X-Forwarded-Protocol and X-Url-Scheme
before forwarding; X-Forwarded-Proto carries the scheme.
- Static: check for dot segments again after path unescaping, keep the
HTML5 index fallback for unclean paths, check the path only once, and
document how EnablePathUnescaping affects non-default escaping.
- Tests: guardable route-level static test, group static test, and a
control-character redirect test that does not rely on traversal.
- Docs: IPExtractor default, SchemeExtractor trust notes, changelog
behavior changes; bump Version to 5.4.0.
Claude-Session: https://claude.ai/code/session_01QKDYQr53zNKkR7nif2CAAq
* docs: set v5.4.0 release date
Claude-Session: https://claude.ai/code/session_01QKDYQr53zNKkR7nif2CAAq1 parent e804f42 commit fc41009
22 files changed
Lines changed: 1333 additions & 84 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
4 | 39 | | |
5 | 40 | | |
6 | 41 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
195 | 195 | | |
196 | 196 | | |
197 | 197 | | |
198 | | - | |
199 | | - | |
200 | | - | |
201 | | - | |
202 | | - | |
203 | | - | |
204 | | - | |
205 | | - | |
206 | | - | |
207 | | - | |
208 | | - | |
209 | | - | |
210 | | - | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
211 | 205 | | |
212 | 206 | | |
213 | 207 | | |
214 | | - | |
215 | | - | |
216 | | - | |
217 | | - | |
218 | | - | |
| 208 | + | |
| 209 | + | |
219 | 210 | | |
220 | | - | |
221 | | - | |
222 | | - | |
223 | | - | |
224 | | - | |
225 | | - | |
226 | | - | |
227 | | - | |
228 | | - | |
229 | | - | |
| 211 | + | |
230 | 212 | | |
231 | 213 | | |
232 | 214 | | |
| |||
524 | 506 | | |
525 | 507 | | |
526 | 508 | | |
527 | | - | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
528 | 543 | | |
| 544 | + | |
529 | 545 | | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
530 | 553 | | |
531 | 554 | | |
532 | 555 | | |
| |||
581 | 604 | | |
582 | 605 | | |
583 | 606 | | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
584 | 614 | | |
585 | 615 | | |
586 | 616 | | |
587 | 617 | | |
588 | 618 | | |
589 | | - | |
| 619 | + | |
590 | 620 | | |
591 | | - | |
592 | | - | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
593 | 624 | | |
594 | 625 | | |
595 | 626 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
260 | 260 | | |
261 | 261 | | |
262 | 262 | | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
263 | 321 | | |
264 | 322 | | |
265 | 323 | | |
| |||
1091 | 1149 | | |
1092 | 1150 | | |
1093 | 1151 | | |
1094 | | - | |
1095 | | - | |
1096 | | - | |
1097 | | - | |
| 1152 | + | |
| 1153 | + | |
| 1154 | + | |
| 1155 | + | |
| 1156 | + | |
1098 | 1157 | | |
1099 | 1158 | | |
1100 | 1159 | | |
| |||
1138 | 1197 | | |
1139 | 1198 | | |
1140 | 1199 | | |
1141 | | - | |
| 1200 | + | |
1142 | 1201 | | |
1143 | 1202 | | |
1144 | 1203 | | |
| |||
1157 | 1216 | | |
1158 | 1217 | | |
1159 | 1218 | | |
1160 | | - | |
| 1219 | + | |
1161 | 1220 | | |
1162 | 1221 | | |
1163 | 1222 | | |
1164 | 1223 | | |
1165 | 1224 | | |
1166 | | - | |
| 1225 | + | |
| 1226 | + | |
| 1227 | + | |
| 1228 | + | |
| 1229 | + | |
| 1230 | + | |
| 1231 | + | |
| 1232 | + | |
| 1233 | + | |
| 1234 | + | |
| 1235 | + | |
| 1236 | + | |
| 1237 | + | |
| 1238 | + | |
| 1239 | + | |
| 1240 | + | |
| 1241 | + | |
| 1242 | + | |
| 1243 | + | |
| 1244 | + | |
| 1245 | + | |
| 1246 | + | |
| 1247 | + | |
1167 | 1248 | | |
1168 | 1249 | | |
1169 | 1250 | | |
| |||
1244 | 1325 | | |
1245 | 1326 | | |
1246 | 1327 | | |
| 1328 | + | |
| 1329 | + | |
| 1330 | + | |
| 1331 | + | |
| 1332 | + | |
| 1333 | + | |
| 1334 | + | |
| 1335 | + | |
| 1336 | + | |
| 1337 | + | |
| 1338 | + | |
| 1339 | + | |
| 1340 | + | |
| 1341 | + | |
| 1342 | + | |
| 1343 | + | |
| 1344 | + | |
| 1345 | + | |
| 1346 | + | |
| 1347 | + | |
| 1348 | + | |
| 1349 | + | |
| 1350 | + | |
| 1351 | + | |
| 1352 | + | |
| 1353 | + | |
| 1354 | + | |
| 1355 | + | |
| 1356 | + | |
| 1357 | + | |
| 1358 | + | |
| 1359 | + | |
| 1360 | + | |
| 1361 | + | |
| 1362 | + | |
| 1363 | + | |
| 1364 | + | |
| 1365 | + | |
| 1366 | + | |
| 1367 | + | |
| 1368 | + | |
| 1369 | + | |
| 1370 | + | |
| 1371 | + | |
| 1372 | + | |
| 1373 | + | |
| 1374 | + | |
| 1375 | + | |
| 1376 | + | |
| 1377 | + | |
| 1378 | + | |
| 1379 | + | |
| 1380 | + | |
| 1381 | + | |
| 1382 | + | |
1247 | 1383 | | |
1248 | 1384 | | |
1249 | 1385 | | |
1250 | 1386 | | |
1251 | 1387 | | |
| 1388 | + | |
| 1389 | + | |
| 1390 | + | |
| 1391 | + | |
1252 | 1392 | | |
1253 | 1393 | | |
1254 | 1394 | | |
| |||
0 commit comments