mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-29 18:36:30 +02:00
config: escape % signs in local reply format string (#5470)
config: escape % signs in local reply format string (#5460) Since v0.26, Pomerium configures Envoy to use a custom HTML error page format string for most errors served by Envoy itself. This format string uses %COMMAND% directives to include details about the error. The HTML error page template also includes any branding options set via the corresponding Enterprise settings. We need to ensure that any % signs in the branding options strings are escaped to %% so that Envoy will not interpret them as the start of a %COMMAND% directive, which could lead to Envoy rejecting the format string as invalid. Co-authored-by: Kenneth Jenkins <51246568+kenjenkins@users.noreply.github.com>
This commit is contained in:
parent
5e45fa4b0d
commit
ac40ef445d
2 changed files with 76 additions and 6 deletions
|
@ -55,13 +55,19 @@ func (b *Builder) buildLocalReplyConfig(
|
||||||
headers = toEnvoyHeaders(options.GetSetResponseHeaders())
|
headers = toEnvoyHeaders(options.GetSetResponseHeaders())
|
||||||
}
|
}
|
||||||
|
|
||||||
data := map[string]any{
|
data := make(map[string]any)
|
||||||
"status": "%RESPONSE_CODE%",
|
|
||||||
"statusText": "%RESPONSE_CODE_DETAILS%",
|
|
||||||
"requestId": "%STREAM_ID%",
|
|
||||||
"responseFlags": "%RESPONSE_FLAGS%",
|
|
||||||
}
|
|
||||||
httputil.AddBrandingOptionsToMap(data, options.BrandingOptions)
|
httputil.AddBrandingOptionsToMap(data, options.BrandingOptions)
|
||||||
|
for k, v := range data {
|
||||||
|
// Escape any % signs in the branding options data, as Envoy will
|
||||||
|
// interpret the page output as a substitution format string.
|
||||||
|
if s, ok := v.(string); ok {
|
||||||
|
data[k] = strings.ReplaceAll(s, "%", "%%")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data["status"] = "%RESPONSE_CODE%"
|
||||||
|
data["statusText"] = "%RESPONSE_CODE_DETAILS%"
|
||||||
|
data["requestId"] = "%STREAM_ID%"
|
||||||
|
data["responseFlags"] = "%RESPONSE_FLAGS%"
|
||||||
|
|
||||||
bs, err := ui.RenderPage("Error", "Error", data)
|
bs, err := ui.RenderPage("Error", "Error", data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
64
config/envoyconfig/http_connection_manager_test.go
Normal file
64
config/envoyconfig/http_connection_manager_test.go
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
package envoyconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
|
||||||
|
"github.com/pomerium/pomerium/config"
|
||||||
|
configpb "github.com/pomerium/pomerium/pkg/grpc/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_buildLocalReplyConfig(t *testing.T) {
|
||||||
|
b := Builder{}
|
||||||
|
opts := config.NewDefaultOptions()
|
||||||
|
opts.BrandingOptions = &configpb.Settings{
|
||||||
|
LogoUrl: proto.String("http://example.com/my%20branding%20logo.png"),
|
||||||
|
ErrorMessageFirstParagraph: proto.String("It's 100% broken."),
|
||||||
|
}
|
||||||
|
lrc, err := b.buildLocalReplyConfig(opts)
|
||||||
|
require.NoError(t, err)
|
||||||
|
tmpl := string(lrc.Mappers[0].GetBodyFormatOverride().GetTextFormatSource().GetInlineBytes())
|
||||||
|
assert.Equal(t, `<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link id="favicon" rel="shortcut icon" href="/.pomerium/favicon.ico?v=2" />
|
||||||
|
<link
|
||||||
|
class="pomerium_favicon"
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="180x180"
|
||||||
|
href="/.pomerium/apple-touch-icon.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
class="pomerium_favicon"
|
||||||
|
rel="icon"
|
||||||
|
sizes="32x32"
|
||||||
|
href="/.pomerium/favicon-32x32.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
class="pomerium_favicon"
|
||||||
|
rel="icon"
|
||||||
|
sizes="16x16"
|
||||||
|
href="/.pomerium/favicon-16x16.png"
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||||||
|
/>
|
||||||
|
<title>Error</title>
|
||||||
|
<link rel="stylesheet" href="/.pomerium/index.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script>
|
||||||
|
window.POMERIUM_DATA = {"errorMessageFirstParagraph":"It's 100%% broken.","logoUrl":"http://example.com/my%%20branding%%20logo.png","page":"Error","requestId":"%STREAM_ID%","responseFlags":"%RESPONSE_FLAGS%","status":"%RESPONSE_CODE%","statusText":"%RESPONSE_CODE_DETAILS%"};
|
||||||
|
</script>
|
||||||
|
<script src="/.pomerium/index.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`, tmpl)
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue