Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

html/template: base64 html images in image tag are unsafe #20536

Closed
azr opened this issue May 31, 2017 · 11 comments
Closed

html/template: base64 html images in image tag are unsafe #20536

azr opened this issue May 31, 2017 · 11 comments

Comments

@azr
Copy link
Contributor

azr commented May 31, 2017

Hello there

Is there a way to print that image ? Is normal that it is unsafe ?

What did you do?

https://play.golang.org/p/dOQHc3Y-n8

package main

import "os"
import "html/template"

func main() {
	img := `data:image/gif;base64,R0lGODlhGAAYALMPACAgLLW1w5WLp3lvjEdDWa+nwWRed87M4Fxdae/w/9LT4T8/S5eYpXl5h////////yH5BAEAAA8ALAAAAAAYABgAAASH8MlJq700qBPYwuCTOI7CACHGKAUCoOnFBA0cW0wS2DeVnz2ciRdsKGiAT1CSM9WWD2OJ0WgoewySjnqNIUYOXdXa+yYUiipD0A0hFImzml1WhNONdRv0JuEbdDd9JWOBMQt2hGN7GAsrR2pkN44MlQgIBAiMFwsDngMGBAQLmxeXVaSkUEsRADs= `

	var ImageTemplate string = `<img src="{{.}}">
{{.}}`

	template.Must(template.New("name").Parse(ImageTemplate)).Execute(os.Stdout, img)

}

What did you expect to see?

A bottle icon !

<img src="data:image/gif;base64,R0lGODlhGAAYALMPACAgLLW1w5WLp3lvjEdDWa+nwWRed87M4Fxdae/w/9LT4T8/S5eYpXl5h////////yH5BAEAAA8ALAAAAAAYABgAAASH8MlJq700qBPYwuCTOI7CACHGKAUCoOnFBA0cW0wS2DeVnz2ciRdsKGiAT1CSM9WWD2OJ0WgoewySjnqNIUYOXdXa+yYUiipD0A0hFImzml1WhNONdRv0JuEbdDd9JWOBMQt2hGN7GAsrR2pkN44MlQgIBAiMFwsDngMGBAQLmxeXVaSkUEsRADs= ">
data:image/gif;base64,R0lGODlhGAAYALMPACAgLLW1w5WLp3lvjEdDWa+nwWRed87M4Fxdae/w/9LT4T8/S5eYpXl5h////////yH5BAEAAA8ALAAAAAAYABgAAASH8MlJq700qBPYwuCTOI7CACHGKAUCoOnFBA0cW0wS2DeVnz2ciRdsKGiAT1CSM9WWD2OJ0WgoewySjnqNIUYOXdXa+yYUiipD0A0hFImzml1WhNONdRv0JuEbdDd9JWOBMQt2hGN7GAsrR2pkN44MlQgIBAiMFwsDngMGBAQLmxeXVaSkUEsRADs= 

What did you see instead?

<img src="#ZgotmplZ">
data:image/gif;base64,R0lGODlhGAAYALMPACAgLLW1w5WLp3lvjEdDWa+nwWRed87M4Fxdae/w/9LT4T8/S5eYpXl5h////////yH5BAEAAA8ALAAAAAAYABgAAASH8MlJq700qBPYwuCTOI7CACHGKAUCoOnFBA0cW0wS2DeVnz2ciRdsKGiAT1CSM9WWD2OJ0WgoewySjnqNIUYOXdXa+yYUiipD0A0hFImzml1WhNONdRv0JuEbdDd9JWOBMQt2hGN7GAsrR2pkN44MlQgIBAiMFwsDngMGBAQLmxeXVaSkUEsRADs= 

Thoughts

I also tried with template.URLQueryEscaper, navigator doesnt get string as an image and template.HTMLEscapeString gets me the #ZgotmplZ

System details

go version go1.8.3 darwin/amd64
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/azr/go"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.8.3/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.8.3/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/sq/zw92_59n6q9fvh0bw99jkfnw0000gn/T/go-build365313874=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
GOROOT/bin/go version: go version go1.8.3 darwin/amd64
GOROOT/bin/go tool compile -V: compile version go1.8.3 X:framepointer
uname -v: Darwin Kernel Version 16.5.0: Fri Mar  3 16:52:33 PST 2017; root:xnu-3789.51.2~3/RELEASE_X86_64
ProductName:	Mac OS X
ProductVersion:	10.12.4
BuildVersion:	16E195
lldb --version: lldb-370.0.42
  Swift-3.1
gdb --version: GNU gdb (GDB) 7.12.1
@azr
Copy link
Contributor Author

azr commented May 31, 2017

Also when I use <img covfefe="{{.}}"> the correct content is displayed, so I can have a js parser that does some little magic

@ianlancetaylor
Copy link
Contributor

This is working as intended. It's not the base64 that is unsafe, it is the "data:" URL. If img were a user-supplied string, the data: URL could be anything. It works with covfefe because covfefe does not expect a URL.

Closing. Please comment if you disagree.

@azr
Copy link
Contributor Author

azr commented May 31, 2017

Howdy, okay, I just read this: https://html5sec.org/ , got it: if we do <embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></embed> then ppl can arbitrarily execute code.

But shouldn't it be that data:text/html is dangerous and not data:image/* ?

Edit: may be also data:image/svg is dangerous

@azr
Copy link
Contributor Author

azr commented Jun 4, 2017

What do you think @ianlancetaylor ?

@azr
Copy link
Contributor Author

azr commented Jun 21, 2017

Bump @ianlancetaylor . It seems I'm reaching your spams.
I'll make another issue to re-start the discussion soon then.

@ianlancetaylor
Copy link
Contributor

Sorry, reopening. Offhand I don't know the answer to your question. Is there a real problem here, or is this just theoretical?

CC @stjj89

@stjj89
Copy link
Contributor

stjj89 commented Jun 21, 2017

But shouldn't it be that data:text/html is dangerous and not data:image/* ?

Edit: may be also data:image/svg is dangerous

Right, certain media MIME types (e.g. data:image/* and data:video/*) are probably safe. However, html/template's URL filter is conservative by design, and accepts only the http, https, and mailto schemes.

You can get around the URL filter by passing your URL to html/template as a template.URL rather than a plain string. This tells html/template that your URL is known to be safe, and therefore does not need to be filtered. See example at https://play.golang.org/p/cSORJiFSdI.

@azr
Copy link
Contributor Author

azr commented Jun 21, 2017

Ah okay thanks @stjj89 , so I guess making data:image/* and data:video/* 'safe' will never happen ?
The source is not that trusted but if I double check input all should be safe enough, thanks again people for the answers.

@ianlancetaylor
Copy link
Contributor

Closing since it seems there is nothing to do.

@azr
Copy link
Contributor Author

azr commented Jun 22, 2017

"A good issue is a closed issue"
- ianlancetaylor

😆

@stjj89
Copy link
Contributor

stjj89 commented Jun 22, 2017

Ah okay thanks @stjj89 , so I guess making data:image/* and data:video/* 'safe' will never happen ?
The source is not that trusted but if I double check input all should be safe enough, thanks again people for the answers.

I think it generally pays to remain conservative about our assumptions, but we could consider this in the future if enough users are running into this issue.

@golang golang locked and limited conversation to collaborators Jun 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants