hugo

Fork of github.com/gohugoio/hugo with reverse pagination support

git clone git://git.shimmy1996.com/hugo.git

securitypolicies_test.go (5580B)

    1 // Copyright 2019 The Hugo Authors. All rights reserved.
    2 //
    3 // Licensed under the Apache License, Version 2.0 (the "License");
    4 // you may not use this file except in compliance with the License.
    5 // You may obtain a copy of the License at
    6 // http://www.apache.org/licenses/LICENSE-2.0
    7 //
    8 // Unless required by applicable law or agreed to in writing, software
    9 // distributed under the License is distributed on an "AS IS" BASIS,
   10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   11 // See the License for the specific language governing permissions and
   12 // limitations under the License.
   13 
   14 package hugolib
   15 
   16 import (
   17 	"fmt"
   18 	"net/http"
   19 	"net/http/httptest"
   20 	"runtime"
   21 	"testing"
   22 
   23 	qt "github.com/frankban/quicktest"
   24 	"github.com/gohugoio/hugo/markup/asciidocext"
   25 	"github.com/gohugoio/hugo/markup/pandoc"
   26 	"github.com/gohugoio/hugo/markup/rst"
   27 	"github.com/gohugoio/hugo/resources/resource_transformers/tocss/dartsass"
   28 )
   29 
   30 func TestSecurityPolicies(t *testing.T) {
   31 	c := qt.New(t)
   32 
   33 	testVariant := func(c *qt.C, withBuilder func(b *sitesBuilder), expectErr string) {
   34 		c.Helper()
   35 		b := newTestSitesBuilder(c)
   36 		withBuilder(b)
   37 
   38 		if expectErr != "" {
   39 			err := b.BuildE(BuildCfg{})
   40 			b.Assert(err, qt.IsNotNil)
   41 			b.Assert(err, qt.ErrorMatches, expectErr)
   42 		} else {
   43 			b.Build(BuildCfg{})
   44 		}
   45 
   46 	}
   47 
   48 	httpTestVariant := func(c *qt.C, templ, expectErr string, withBuilder func(b *sitesBuilder)) {
   49 		ts := httptest.NewServer(http.FileServer(http.Dir("testdata/")))
   50 		c.Cleanup(func() {
   51 			ts.Close()
   52 		})
   53 		cb := func(b *sitesBuilder) {
   54 			b.WithTemplatesAdded("index.html", fmt.Sprintf(templ, ts.URL))
   55 			if withBuilder != nil {
   56 				withBuilder(b)
   57 			}
   58 		}
   59 		testVariant(c, cb, expectErr)
   60 	}
   61 
   62 	c.Run("os.GetEnv, denied", func(c *qt.C) {
   63 		c.Parallel()
   64 		cb := func(b *sitesBuilder) {
   65 			b.WithTemplatesAdded("index.html", `{{ os.Getenv "FOOBAR" }}`)
   66 		}
   67 		testVariant(c, cb, `(?s).*"FOOBAR" is not whitelisted in policy "security\.funcs\.getenv".*`)
   68 	})
   69 
   70 	c.Run("os.GetEnv, OK", func(c *qt.C) {
   71 		c.Parallel()
   72 		cb := func(b *sitesBuilder) {
   73 			b.WithTemplatesAdded("index.html", `{{ os.Getenv "HUGO_FOO" }}`)
   74 		}
   75 		testVariant(c, cb, "")
   76 	})
   77 
   78 	c.Run("Asciidoc, denied", func(c *qt.C) {
   79 		c.Parallel()
   80 		if !asciidocext.Supports() {
   81 			c.Skip()
   82 		}
   83 
   84 		cb := func(b *sitesBuilder) {
   85 			b.WithContent("page.ad", "foo")
   86 		}
   87 
   88 		testVariant(c, cb, `(?s).*"asciidoctor" is not whitelisted in policy "security\.exec\.allow".*`)
   89 	})
   90 
   91 	c.Run("RST, denied", func(c *qt.C) {
   92 		c.Parallel()
   93 		if !rst.Supports() {
   94 			c.Skip()
   95 		}
   96 
   97 		cb := func(b *sitesBuilder) {
   98 			b.WithContent("page.rst", "foo")
   99 		}
  100 
  101 		if runtime.GOOS == "windows" {
  102 			testVariant(c, cb, `(?s).*python(\.exe)?" is not whitelisted in policy "security\.exec\.allow".*`)
  103 		} else {
  104 			testVariant(c, cb, `(?s).*"rst2html(\.py)?" is not whitelisted in policy "security\.exec\.allow".*`)
  105 
  106 		}
  107 
  108 	})
  109 
  110 	c.Run("Pandoc, denied", func(c *qt.C) {
  111 		c.Parallel()
  112 		if !pandoc.Supports() {
  113 			c.Skip()
  114 		}
  115 
  116 		cb := func(b *sitesBuilder) {
  117 			b.WithContent("page.pdc", "foo")
  118 		}
  119 
  120 		testVariant(c, cb, `"(?s).*pandoc" is not whitelisted in policy "security\.exec\.allow".*`)
  121 	})
  122 
  123 	c.Run("Dart SASS, OK", func(c *qt.C) {
  124 		c.Parallel()
  125 		if !dartsass.Supports() {
  126 			c.Skip()
  127 		}
  128 		cb := func(b *sitesBuilder) {
  129 			b.WithTemplatesAdded("index.html", `{{ $scss := "body { color: #333; }" | resources.FromString "foo.scss"  | resources.ToCSS (dict "transpiler" "dartsass") }}`)
  130 		}
  131 		testVariant(c, cb, "")
  132 	})
  133 
  134 	c.Run("Dart SASS, denied", func(c *qt.C) {
  135 		c.Parallel()
  136 		if !dartsass.Supports() {
  137 			c.Skip()
  138 		}
  139 		cb := func(b *sitesBuilder) {
  140 			b.WithConfigFile("toml", `
  141 			[security]
  142 			[security.exec]
  143 			allow="none"	
  144 		
  145 			`)
  146 			b.WithTemplatesAdded("index.html", `{{ $scss := "body { color: #333; }" | resources.FromString "foo.scss"  | resources.ToCSS (dict "transpiler" "dartsass") }}`)
  147 		}
  148 		testVariant(c, cb, `(?s).*"dart-sass-embedded" is not whitelisted in policy "security\.exec\.allow".*`)
  149 	})
  150 
  151 	c.Run("resources.GetRemote, OK", func(c *qt.C) {
  152 		c.Parallel()
  153 		httpTestVariant(c, `{{ $json := resources.GetRemote "%[1]s/fruits.json" }}{{ $json.Content }}`, "", nil)
  154 	})
  155 
  156 	c.Run("resources.GetRemote, denied method", func(c *qt.C) {
  157 		c.Parallel()
  158 		httpTestVariant(c, `{{ $json := resources.GetRemote "%[1]s/fruits.json" (dict "method" "DELETE" ) }}{{ $json.Content }}`, `(?s).*"DELETE" is not whitelisted in policy "security\.http\.method".*`, nil)
  159 	})
  160 
  161 	c.Run("resources.GetRemote, denied URL", func(c *qt.C) {
  162 		c.Parallel()
  163 		httpTestVariant(c, `{{ $json := resources.GetRemote "%[1]s/fruits.json" }}{{ $json.Content }}`, `(?s).*is not whitelisted in policy "security\.http\.urls".*`,
  164 			func(b *sitesBuilder) {
  165 				b.WithConfigFile("toml", `
  166 [security]		
  167 [security.http]
  168 urls="none"
  169 `)
  170 			})
  171 	})
  172 
  173 	c.Run("getJSON, OK", func(c *qt.C) {
  174 		c.Parallel()
  175 		httpTestVariant(c, `{{ $json := getJSON "%[1]s/fruits.json" }}{{ $json.Content }}`, "", nil)
  176 	})
  177 
  178 	c.Run("getJSON, denied URL", func(c *qt.C) {
  179 		c.Parallel()
  180 		httpTestVariant(c, `{{ $json := getJSON "%[1]s/fruits.json" }}{{ $json.Content }}`, `(?s).*is not whitelisted in policy "security\.http\.urls".*`,
  181 			func(b *sitesBuilder) {
  182 				b.WithConfigFile("toml", `
  183 [security]		
  184 [security.http]
  185 urls="none"		
  186 `)
  187 			})
  188 	})
  189 
  190 	c.Run("getCSV, denied URL", func(c *qt.C) {
  191 		c.Parallel()
  192 		httpTestVariant(c, `{{ $d := getCSV ";" "%[1]s/cities.csv" }}{{ $d.Content }}`, `(?s).*is not whitelisted in policy "security\.http\.urls".*`,
  193 			func(b *sitesBuilder) {
  194 				b.WithConfigFile("toml", `
  195 [security]		
  196 [security.http]
  197 urls="none"		
  198 `)
  199 			})
  200 	})
  201 
  202 }