mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-07 20:30:36 -05:00
Fixes #7698.
markup: Allow installed arbitrary Asciidoc extension via path validation.
This commit is contained in:
parent
c8f45d1d86
commit
01dd7c16af
4 changed files with 44 additions and 22 deletions
|
@ -100,6 +100,8 @@ Below are all the AsciiDoc related settings in Hugo with their default values:
|
||||||
|
|
||||||
{{< code-toggle config="markup.asciidocExt" />}}
|
{{< code-toggle config="markup.asciidocExt" />}}
|
||||||
|
|
||||||
|
Notice that for security concerns only extensions that do not have path separators (either `\`, `/` or `.`) are allowed. That means that extensions can only be invoked if they are in one's ruby's `$LOAD_PATH` (ie. most likely, the extension has been installed by the user). Any extension declared relative to the website's path will not be accepted.
|
||||||
|
|
||||||
Example of how to set extensions and attributes:
|
Example of how to set extensions and attributes:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -37,18 +37,6 @@ var (
|
||||||
FailureLevel: "fatal",
|
FailureLevel: "fatal",
|
||||||
}
|
}
|
||||||
|
|
||||||
AllowedExtensions = map[string]bool{
|
|
||||||
"asciidoctor-html5s": true,
|
|
||||||
"asciidoctor-bibtex": true,
|
|
||||||
"asciidoctor-diagram": true,
|
|
||||||
"asciidoctor-interdoc-reftext": true,
|
|
||||||
"asciidoctor-katex": true,
|
|
||||||
"asciidoctor-latex": true,
|
|
||||||
"asciidoctor-mathematical": true,
|
|
||||||
"asciidoctor-question": true,
|
|
||||||
"asciidoctor-rouge": true,
|
|
||||||
}
|
|
||||||
|
|
||||||
AllowedSafeMode = map[string]bool{
|
AllowedSafeMode = map[string]bool{
|
||||||
"unsafe": true,
|
"unsafe": true,
|
||||||
"safe": true,
|
"safe": true,
|
||||||
|
|
|
@ -19,6 +19,7 @@ package asciidocext
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/htesting"
|
"github.com/gohugoio/hugo/htesting"
|
||||||
|
|
||||||
|
@ -105,11 +106,10 @@ func (a *asciidocConverter) parseArgs(ctx converter.DocumentContext) []string {
|
||||||
args = a.appendArg(args, "-b", cfg.Backend, asciidocext_config.CliDefault.Backend, asciidocext_config.AllowedBackend)
|
args = a.appendArg(args, "-b", cfg.Backend, asciidocext_config.CliDefault.Backend, asciidocext_config.AllowedBackend)
|
||||||
|
|
||||||
for _, extension := range cfg.Extensions {
|
for _, extension := range cfg.Extensions {
|
||||||
if !asciidocext_config.AllowedExtensions[extension] {
|
if strings.LastIndexAny(extension, `\/.`) > -1 {
|
||||||
a.cfg.Logger.Errorln("Unsupported asciidoctor extension was passed in. Extension `" + extension + "` ignored.")
|
a.cfg.Logger.Errorln("Unsupported asciidoctor extension was passed in. Extension `" + extension + "` ignored. Only installed asciidoctor extensions are allowed.")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
args = append(args, "-r", extension)
|
args = append(args, "-r", extension)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ func TestAsciidoctorDisallowedArgs(t *testing.T) {
|
||||||
cfg := viper.New()
|
cfg := viper.New()
|
||||||
mconf := markup_config.Default
|
mconf := markup_config.Default
|
||||||
mconf.AsciidocExt.Backend = "disallowed-backend"
|
mconf.AsciidocExt.Backend = "disallowed-backend"
|
||||||
mconf.AsciidocExt.Extensions = []string{"disallowed-extension"}
|
mconf.AsciidocExt.Extensions = []string{"./disallowed-extension"}
|
||||||
mconf.AsciidocExt.Attributes = map[string]string{"outdir": "disallowed-attribute"}
|
mconf.AsciidocExt.Attributes = map[string]string{"outdir": "disallowed-attribute"}
|
||||||
mconf.AsciidocExt.SafeMode = "disallowed-safemode"
|
mconf.AsciidocExt.SafeMode = "disallowed-safemode"
|
||||||
mconf.AsciidocExt.FailureLevel = "disallowed-failurelevel"
|
mconf.AsciidocExt.FailureLevel = "disallowed-failurelevel"
|
||||||
|
@ -115,14 +115,11 @@ func TestAsciidoctorDisallowedArgs(t *testing.T) {
|
||||||
c.Assert(args, qt.DeepEquals, expected)
|
c.Assert(args, qt.DeepEquals, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAsciidoctorDiagramArgs(t *testing.T) {
|
func TestAsciidoctorArbitraryExtension(t *testing.T) {
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
cfg := viper.New()
|
cfg := viper.New()
|
||||||
mconf := markup_config.Default
|
mconf := markup_config.Default
|
||||||
mconf.AsciidocExt.NoHeaderOrFooter = true
|
mconf.AsciidocExt.Extensions = []string{"arbitrary-extension"}
|
||||||
mconf.AsciidocExt.Extensions = []string{"asciidoctor-html5s", "asciidoctor-diagram"}
|
|
||||||
mconf.AsciidocExt.Backend = "html5s"
|
|
||||||
mconf.AsciidocExt.Trace = false
|
|
||||||
p, err := Provider.New(
|
p, err := Provider.New(
|
||||||
converter.ProviderConfig{
|
converter.ProviderConfig{
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
|
@ -139,10 +136,45 @@ func TestAsciidoctorDiagramArgs(t *testing.T) {
|
||||||
c.Assert(ac, qt.Not(qt.IsNil))
|
c.Assert(ac, qt.Not(qt.IsNil))
|
||||||
|
|
||||||
args := ac.parseArgs(converter.DocumentContext{})
|
args := ac.parseArgs(converter.DocumentContext{})
|
||||||
expected := []string{"-b", "html5s", "-r", "asciidoctor-html5s", "-r", "asciidoctor-diagram", "--no-header-footer"}
|
expected := []string{"-r", "arbitrary-extension", "--no-header-footer"}
|
||||||
c.Assert(args, qt.DeepEquals, expected)
|
c.Assert(args, qt.DeepEquals, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAsciidoctorDisallowedExtension(t *testing.T) {
|
||||||
|
c := qt.New(t)
|
||||||
|
cfg := viper.New()
|
||||||
|
for _, disallowedExtension := range []string{
|
||||||
|
`foo-bar//`,
|
||||||
|
`foo-bar\\ `,
|
||||||
|
`../../foo-bar`,
|
||||||
|
`/foo-bar`,
|
||||||
|
`C:\foo-bar`,
|
||||||
|
`foo-bar.rb`,
|
||||||
|
`foo.bar`,
|
||||||
|
} {
|
||||||
|
mconf := markup_config.Default
|
||||||
|
mconf.AsciidocExt.Extensions = []string{disallowedExtension}
|
||||||
|
p, err := Provider.New(
|
||||||
|
converter.ProviderConfig{
|
||||||
|
Cfg: cfg,
|
||||||
|
MarkupConfig: mconf,
|
||||||
|
Logger: loggers.NewErrorLogger(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
c.Assert(err, qt.IsNil)
|
||||||
|
|
||||||
|
conv, err := p.New(converter.DocumentContext{})
|
||||||
|
c.Assert(err, qt.IsNil)
|
||||||
|
|
||||||
|
ac := conv.(*asciidocConverter)
|
||||||
|
c.Assert(ac, qt.Not(qt.IsNil))
|
||||||
|
|
||||||
|
args := ac.parseArgs(converter.DocumentContext{})
|
||||||
|
expected := []string{"--no-header-footer"}
|
||||||
|
c.Assert(args, qt.DeepEquals, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAsciidoctorWorkingFolderCurrent(t *testing.T) {
|
func TestAsciidoctorWorkingFolderCurrent(t *testing.T) {
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
cfg := viper.New()
|
cfg := viper.New()
|
||||||
|
|
Loading…
Reference in a new issue