Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Merge pull request from GHSA-vg46-2rrj-3647
#11716 Fix NameVirtualHost HTML injection and deprecate t.w.r.ErrorPage in favor of t.w.pages
- Loading branch information
Showing
16 changed files
with
416 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| twisted.web.vhost.NameVirtualHost no longer echoes HTML received in the Host header without escaping it (CVE-2022-39348, GHSA-vg46-2rrj-3647). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| The twisted.web.pages.errorPage, notFound, and forbidden each return an IResource that displays an HTML error pages safely rendered using twisted.web.template. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| The twisted.web.resource.ErrorPage, NoResource, and ForbiddenResource classes have been deprecated in favor of new implementations twisted.web.pages module because they permit HTML injection. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| # -*- test-case-name: twisted.web.test.test_pages -*- | ||
| # Copyright (c) Twisted Matrix Laboratories. | ||
| # See LICENSE for details. | ||
|
|
||
| """ | ||
| Utility implementations of L{IResource}. | ||
| """ | ||
|
|
||
| __all__ = ( | ||
| "errorPage", | ||
| "notFound", | ||
| "forbidden", | ||
| ) | ||
|
|
||
| from typing import cast | ||
|
|
||
| from twisted.web import http | ||
| from twisted.web.iweb import IRenderable, IRequest | ||
| from twisted.web.resource import IResource, Resource | ||
| from twisted.web.template import renderElement, tags | ||
|
|
||
|
|
||
| class _ErrorPage(Resource): | ||
| """ | ||
| L{_ErrorPage} is a resource that responds to all requests with a particular | ||
| (parameterized) HTTP status code and an HTML body containing some | ||
| descriptive text. This is useful for rendering simple error pages. | ||
| @see: L{twisted.web.pages.errorPage} | ||
| @ivar _code: An integer HTTP status code which will be used for the | ||
| response. | ||
| @ivar _brief: A short string which will be included in the response body as | ||
| the page title. | ||
| @ivar _detail: A longer string which will be included in the response body. | ||
| """ | ||
|
|
||
| def __init__(self, code: int, brief: str, detail: str) -> None: | ||
| super().__init__() | ||
| self._code: int = code | ||
| self._brief: str = brief | ||
| self._detail: str = detail | ||
|
|
||
| def render(self, request: IRequest) -> object: | ||
| """ | ||
| Respond to all requests with the given HTTP status code and an HTML | ||
| document containing the explanatory strings. | ||
| """ | ||
| request.setResponseCode(self._code) | ||
| request.setHeader(b"content-type", b"text/html; charset=utf-8") | ||
| return renderElement( | ||
| request, | ||
| # cast because the type annotations here seem off; Tag isn't an | ||
| # IRenderable but also probably should be? See | ||
| # https://github.com/twisted/twisted/issues/4982 | ||
| cast( | ||
| IRenderable, | ||
| tags.html( | ||
| tags.head(tags.title(f"{self._code} - {self._brief}")), | ||
| tags.body(tags.h1(self._brief), tags.p(self._detail)), | ||
| ), | ||
| ), | ||
| ) | ||
|
|
||
| def getChild(self, path: bytes, request: IRequest) -> Resource: | ||
| """ | ||
| Handle all requests for which L{_ErrorPage} lacks a child by returning | ||
| this error page. | ||
| @param path: A path segment. | ||
| @param request: HTTP request | ||
| """ | ||
| return self | ||
|
|
||
|
|
||
| def errorPage(code: int, brief: str, detail: str) -> IResource: | ||
| """ | ||
| Build a resource that responds to all requests with a particular HTTP | ||
| status code and an HTML body containing some descriptive text. This is | ||
| useful for rendering simple error pages. | ||
| The resource dynamically handles all paths below it. Use | ||
| L{IResource.putChild()} override specific path. | ||
| @param code: An integer HTTP status code which will be used for the | ||
| response. | ||
| @param brief: A short string which will be included in the response | ||
| body as the page title. | ||
| @param detail: A longer string which will be included in the | ||
| response body. | ||
| @returns: An L{IResource} | ||
| """ | ||
| return _ErrorPage(code, brief, detail) | ||
|
|
||
|
|
||
| def notFound( | ||
| brief: str = "No Such Resource", | ||
| message: str = "Sorry. No luck finding that resource.", | ||
| ) -> IResource: | ||
| """ | ||
| Generate an L{IResource} with a 404 Not Found status code. | ||
| @see: L{twisted.web.pages.errorPage} | ||
| @param brief: A short string displayed as the page title. | ||
| @param brief: A longer string displayed in the page body. | ||
| @returns: An L{IResource} | ||
| """ | ||
| return _ErrorPage(http.NOT_FOUND, brief, message) | ||
|
|
||
|
|
||
| def forbidden( | ||
| brief: str = "Forbidden Resource", message: str = "Sorry, resource is forbidden." | ||
| ) -> IResource: | ||
| """ | ||
| Generate an L{IResource} with a 403 Forbidden status code. | ||
| @see: L{twisted.web.pages.errorPage} | ||
| @param brief: A short string displayed as the page title. | ||
| @param brief: A longer string displayed in the page body. | ||
| @returns: An L{IResource} | ||
| """ | ||
| return _ErrorPage(http.FORBIDDEN, brief, message) |
Oops, something went wrong.