fix XSS on opengraph tags
This commit is contained in:
@@ -65,4 +65,4 @@ See our subscription plans on Patreon
|
|||||||
|
|
||||||
After ordering you will receive an e-mail with a link to activate your
|
After ordering you will receive an e-mail with a link to activate your
|
||||||
subscription. The subscription will be linked to the pixeldrain account you're
|
subscription. The subscription will be linked to the pixeldrain account you're
|
||||||
currently loggin into.
|
currently logged into.
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
{{template `modal.css`}}
|
{{template `modal.css`}}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
{{.OGData}}
|
{{ template "opengraph" .OGData }}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -81,19 +81,17 @@
|
|||||||
|
|
||||||
{{ if and .Other.FileAdsEnabled .Other.UserAdsEnabled }}
|
{{ if and .Other.FileAdsEnabled .Other.UserAdsEnabled }}
|
||||||
<hr/>
|
<hr/>
|
||||||
<div style="text-align: center; line-height: 1.4em">
|
Tired of ads?<br/>
|
||||||
<!-- scrolling="no" is not allowed by the W3C, but overflow: hidden doesn't work in chrome, so I have no choice -->
|
Files expiring too soon?<br/>
|
||||||
<iframe
|
<a class="button button_highlight" href="/click/7wy9gg2J?target=%2Fsubscribe">
|
||||||
data-aa="73974"
|
<svg style="float: left; width: 2em; height: 2em; fill: currentColor;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||||
src="//ad.a-ads.com/73974?size=120x600&background_color={{.Style.Layer1Color.RGB}}&text_color={{.Style.TextColor.RGB}}&title_color={{.Style.HighlightColor.RGB}}&title_hover_color={{.Style.HighlightColor.RGB}}&link_color={{.Style.HighlightColor.RGB}}&link_hover_color={{.Style.HighlightColor.RGB}}"
|
<g fill-rule="evenodd">
|
||||||
style="width:120px; height:600px; border:none; padding:0; overflow:hidden;"
|
<path d="M64.1102,0.1004 C44.259,0.1004 28.1086,16.2486 28.1086,36.0986 C28.1086,55.8884 44.259,71.989 64.1102,71.989 C83.9,71.989 100,55.8884 100,36.0986 C100,16.2486 83.9,0.1004 64.1102,0.1004"/>
|
||||||
scrolling="no">
|
<polygon points=".012 95.988 17.59 95.988 17.59 .1 .012 .1"/>
|
||||||
</iframe>
|
</g>
|
||||||
<br/>
|
</svg>
|
||||||
<a class="button" href="https://a-ads.com/campaigns/new?selected_ad_unit_id=73974&selected_source_type=ad_unit&partner=73974">
|
Become a Patron!
|
||||||
Put your own advertisement here
|
</a>
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
<!-- This frame will load the download URL when a download button is pressed -->
|
<!-- This frame will load the download URL when a download button is pressed -->
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
{{template `viewer.css`}}
|
{{template `viewer.css`}}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
{{.OGData}}
|
{{ template "opengraph" .OGData }}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@@ -19,7 +19,7 @@
|
|||||||
<link rel="shortcut icon" sizes="196x196" href="/res/img/pixeldrain_196.png" />
|
<link rel="shortcut icon" sizes="196x196" href="/res/img/pixeldrain_196.png" />
|
||||||
<meta name="theme-color" content="#75AD38"/>
|
<meta name="theme-color" content="#75AD38"/>
|
||||||
|
|
||||||
{{.OGData}}
|
{{ template "opengraph" .OGData }}
|
||||||
<script>
|
<script>
|
||||||
const initialNode = {{.Other}};
|
const initialNode = {{.Other}};
|
||||||
window.api_endpoint = '{{.APIEndpoint}}';
|
window.api_endpoint = '{{.APIEndpoint}}';
|
||||||
|
13
res/template/fragments/opengraph.html
Normal file
13
res/template/fragments/opengraph.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{{ define "opengraph" }}
|
||||||
|
|
||||||
|
{{ range $kv := .OGRules }}
|
||||||
|
<meta property="{{ $kv.Key }}" content="{{ $kv.Value }}" />
|
||||||
|
{{ end }}
|
||||||
|
{{ range $kv := .TwitterRules }}
|
||||||
|
<meta name="{{ $kv.Key }}" content="{{ $kv.Value }}" />
|
||||||
|
{{ end }}
|
||||||
|
{{ range $kv := .LinkRules }}
|
||||||
|
<link rel="{{ $kv.Key }}" href="{{ $kv.Value }}" />
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ end }}
|
@@ -44,12 +44,12 @@ func adType() int {
|
|||||||
// Intn returns a number up to n, but never n itself. So to get a random 0
|
// Intn returns a number up to n, but never n itself. So to get a random 0
|
||||||
// or 1 we need to give it n=2. We can use this function to make other
|
// or 1 we need to give it n=2. We can use this function to make other
|
||||||
// splits like 1/3 1/4, etc
|
// splits like 1/3 1/4, etc
|
||||||
switch i := rand.Intn(8); i {
|
switch i := rand.Intn(10); i {
|
||||||
case 0, 1, 2, 3:
|
case 0, 1:
|
||||||
return amarulaSolutions
|
return amarulaSolutions
|
||||||
case 4, 5:
|
case 2, 3, 4:
|
||||||
return adMaven
|
return adMaven
|
||||||
case 6, 7:
|
case 5, 6, 7, 8, 9:
|
||||||
return propellerAds
|
return propellerAds
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf(
|
panic(fmt.Errorf(
|
||||||
@@ -282,7 +282,6 @@ func (wc *WebController) serveSkynetViewer(w http.ResponseWriter, r *http.Reques
|
|||||||
name = params["filename"]
|
name = params["filename"]
|
||||||
}
|
}
|
||||||
|
|
||||||
templateData.OGData = ""
|
|
||||||
templateData.Title = fmt.Sprintf("name ~ Skynet")
|
templateData.Title = fmt.Sprintf("name ~ Skynet")
|
||||||
templateData.Other = viewerData{
|
templateData.Other = viewerData{
|
||||||
Type: "skylink",
|
Type: "skylink",
|
||||||
|
@@ -1,99 +1,87 @@
|
|||||||
package webcontroller
|
package webcontroller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"html/template"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"fornaxian.tech/pixeldrain_server/api/restapi/apitype"
|
"fornaxian.tech/pixeldrain_server/api/restapi/apitype"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ogRule struct {
|
type ogData struct {
|
||||||
Prop string
|
OGRules []ogProp
|
||||||
Content string
|
TwitterRules []ogProp
|
||||||
|
LinkRules []ogProp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o ogRule) HTML() template.HTML {
|
type ogProp struct {
|
||||||
return template.HTML(`<meta property="` + o.Prop + `" content="` + o.Content + `"/>` + "\n")
|
Key string
|
||||||
|
Value string
|
||||||
}
|
}
|
||||||
|
|
||||||
type twitterRule struct {
|
func (og *ogData) addOG(k, v string) { og.OGRules = append(og.OGRules, ogProp{k, v}) }
|
||||||
Name string
|
func (og *ogData) addTwitter(k, v string) { og.TwitterRules = append(og.TwitterRules, ogProp{k, v}) }
|
||||||
Content string
|
func (og *ogData) addLink(k, v string) { og.LinkRules = append(og.LinkRules, ogProp{k, v}) }
|
||||||
}
|
|
||||||
|
|
||||||
func (o twitterRule) HTML() template.HTML {
|
func metadataFromFile(f apitype.FileInfo) (og ogData) {
|
||||||
return template.HTML(`<meta name="` + o.Name + `" content="` + o.Content + `"/>` + "\n")
|
og.addOG("og:title", f.Name)
|
||||||
}
|
og.addOG("og:site_name", "pixeldrain")
|
||||||
|
og.addOG("og:description", "View '"+f.Name+"' on pixeldrain")
|
||||||
type linkRule struct {
|
og.addOG("description", "View '"+f.Name+"' on pixeldrain")
|
||||||
Rel string
|
og.addOG("og:url", "/u/"+f.ID)
|
||||||
HREF string
|
og.addTwitter("twitter:title", f.Name)
|
||||||
}
|
og.addTwitter("twitter:site", "@Fornax96")
|
||||||
|
og.addTwitter("twitter:domain", "pixeldrain.com")
|
||||||
func (o linkRule) HTML() template.HTML {
|
|
||||||
return template.HTML(`<link rel="` + o.Rel + `" href="` + o.HREF + `"/>` + "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func metadataFromFile(f apitype.FileInfo) (meta template.HTML) {
|
|
||||||
meta += ogRule{"og:title", f.Name}.HTML()
|
|
||||||
meta += ogRule{"og:site_name", "pixeldrain"}.HTML()
|
|
||||||
meta += ogRule{"og:description", "View '" + f.Name + "' on pixeldrain"}.HTML()
|
|
||||||
meta += ogRule{"description", "View '" + f.Name + "' on pixeldrain"}.HTML()
|
|
||||||
meta += ogRule{"og:url", "/u/" + f.ID}.HTML()
|
|
||||||
meta += twitterRule{"twitter:title", f.Name}.HTML()
|
|
||||||
meta += twitterRule{"twitter:site", "@Fornax96"}.HTML()
|
|
||||||
meta += twitterRule{"twitter:domain", "pixeldrain.com"}.HTML()
|
|
||||||
|
|
||||||
if strings.HasPrefix(f.MimeType, "image") {
|
if strings.HasPrefix(f.MimeType, "image") {
|
||||||
meta += ogRule{"og:type", "article"}.HTML()
|
og.addOG("og:type", "article")
|
||||||
meta += ogRule{"og:image", "/api/file/" + f.ID}.HTML()
|
og.addOG("og:image", "/api/file/"+f.ID)
|
||||||
meta += ogRule{"og:image:url", "/api/file/" + f.ID}.HTML()
|
og.addOG("og:image:url", "/api/file/"+f.ID)
|
||||||
meta += ogRule{"og:image:secure_url", "/api/file/" + f.ID}.HTML()
|
og.addOG("og:image:secure_url", "/api/file/"+f.ID)
|
||||||
meta += ogRule{"og:image:type", f.MimeType}.HTML()
|
og.addOG("og:image:type", f.MimeType)
|
||||||
|
|
||||||
meta += twitterRule{"twitter:card", "summary_large_image"}.HTML()
|
og.addTwitter("twitter:card", "summary_large_image")
|
||||||
meta += twitterRule{"twitter:image", "/api/file/" + f.ID}.HTML()
|
og.addTwitter("twitter:image", "/api/file/"+f.ID)
|
||||||
meta += linkRule{"image_src", "/api/file/" + f.ID}.HTML()
|
og.addLink("image_src", "/api/file/"+f.ID)
|
||||||
} else if strings.HasPrefix(f.MimeType, "video") {
|
} else if strings.HasPrefix(f.MimeType, "video") {
|
||||||
meta += ogRule{"og:type", "video.other"}.HTML()
|
og.addOG("og:type", "video.other")
|
||||||
meta += ogRule{"og:image", "/api/file/" + f.ID + "/thumbnail"}.HTML()
|
og.addOG("og:image", "/api/file/"+f.ID+"/thumbnail")
|
||||||
meta += ogRule{"og:video", "/api/file/" + f.ID}.HTML()
|
og.addOG("og:video", "/api/file/"+f.ID)
|
||||||
meta += ogRule{"og:video:secure_url", "/api/file/" + f.ID}.HTML()
|
og.addOG("og:video:url", "/api/file/"+f.ID)
|
||||||
meta += ogRule{"og:video:type", f.MimeType}.HTML()
|
og.addOG("og:video:secure_url", "/api/file/"+f.ID)
|
||||||
|
og.addOG("og:video:type", f.MimeType)
|
||||||
|
|
||||||
meta += twitterRule{"twitter:card", "player"}.HTML()
|
og.addTwitter("twitter:card", "player")
|
||||||
meta += twitterRule{"twitter:image", "/api/file/" + f.ID + "/thumbnail"}.HTML()
|
og.addTwitter("twitter:image", "/api/file/"+f.ID+"/thumbnail")
|
||||||
meta += twitterRule{"twitter:player", "/api/file/" + f.ID}.HTML()
|
og.addTwitter("twitter:player", "/api/file/"+f.ID)
|
||||||
meta += twitterRule{"twitter:player:stream", "/api/file/" + f.ID}.HTML()
|
og.addTwitter("twitter:player:stream", "/api/file/"+f.ID)
|
||||||
meta += twitterRule{"twitter:player:stream:content_type", f.MimeType}.HTML()
|
og.addTwitter("twitter:player:stream:content_type", f.MimeType)
|
||||||
meta += linkRule{"image_src", "/api/file/" + f.ID + "/thumbnail"}.HTML()
|
og.addLink("image_src", "/api/file/"+f.ID+"/thumbnail")
|
||||||
} else if strings.HasPrefix(f.MimeType, "audio") {
|
} else if strings.HasPrefix(f.MimeType, "audio") {
|
||||||
meta += ogRule{"og:type", "music.song"}.HTML()
|
og.addOG("og:type", "music.song")
|
||||||
meta += ogRule{"og:audio", "/api/file/" + f.ID}.HTML()
|
og.addOG("og:audio", "/api/file/"+f.ID)
|
||||||
meta += ogRule{"og:audio:secure_url", "/api/file/" + f.ID}.HTML()
|
og.addOG("og:audio:secure_url", "/api/file/"+f.ID)
|
||||||
meta += ogRule{"og:audio:type", f.MimeType}.HTML()
|
og.addOG("og:audio:type", f.MimeType)
|
||||||
meta += linkRule{"image_src", "/api/file/" + f.ID + "/thumbnail"}.HTML()
|
og.addLink("image_src", "/api/file/"+f.ID+"/thumbnail")
|
||||||
} else {
|
} else {
|
||||||
meta += ogRule{"og:type", "website"}.HTML()
|
og.addOG("og:type", "website")
|
||||||
meta += linkRule{"image_src", "/api/file/" + f.ID + "/thumbnail"}.HTML()
|
og.addLink("image_src", "/api/file/"+f.ID+"/thumbnail")
|
||||||
}
|
}
|
||||||
return meta
|
return og
|
||||||
}
|
}
|
||||||
func metadataFromList(l apitype.ListInfo) (meta template.HTML) {
|
func metadataFromList(l apitype.ListInfo) (og ogData) {
|
||||||
meta += ogRule{"og:type", "website"}.HTML()
|
og.addOG("og:type", "website")
|
||||||
meta += ogRule{"og:title", l.Title}.HTML()
|
og.addOG("og:title", l.Title)
|
||||||
meta += ogRule{"og:site_name", "pixeldrain"}.HTML()
|
og.addOG("og:site_name", "pixeldrain")
|
||||||
meta += ogRule{"og:description", "View '" + l.Title + "' on pixeldrain"}.HTML()
|
og.addOG("og:description", "View '"+l.Title+"' on pixeldrain")
|
||||||
meta += ogRule{"description", "View '" + l.Title + "' on pixeldrain"}.HTML()
|
og.addOG("description", "View '"+l.Title+"' on pixeldrain")
|
||||||
meta += ogRule{"og:url", "/l/" + l.ID}.HTML()
|
og.addOG("og:url", "/l/"+l.ID)
|
||||||
meta += twitterRule{"twitter:title", l.Title}.HTML()
|
og.addTwitter("twitter:title", l.Title)
|
||||||
meta += twitterRule{"twitter:site", "@Fornax96"}.HTML()
|
og.addTwitter("twitter:site", "@Fornax96")
|
||||||
meta += twitterRule{"twitter:domain", "pixeldrain.com"}.HTML()
|
og.addTwitter("twitter:domain", "pixeldrain.com")
|
||||||
if l.FileCount > 0 {
|
if l.FileCount > 0 {
|
||||||
meta += ogRule{"og:image", "/api/file/" + l.Files[0].ID + "/thumbnail"}.HTML()
|
og.addOG("og:image", "/api/file/"+l.Files[0].ID+"/thumbnail")
|
||||||
meta += ogRule{"og:image:url", "/api/file/" + l.Files[0].ID + "/thumbnail"}.HTML()
|
og.addOG("og:image:url", "/api/file/"+l.Files[0].ID+"/thumbnail")
|
||||||
meta += twitterRule{"twitter:image", "/api/file/" + l.Files[0].ID + "/thumbnail"}.HTML()
|
og.addTwitter("twitter:image", "/api/file/"+l.Files[0].ID+"/thumbnail")
|
||||||
meta += linkRule{"image_src", "/api/file/" + l.Files[0].ID + "/thumbnail"}.HTML()
|
og.addLink("image_src", "/api/file/"+l.Files[0].ID+"/thumbnail")
|
||||||
}
|
}
|
||||||
return meta
|
return og
|
||||||
}
|
}
|
||||||
|
@@ -34,7 +34,7 @@ type TemplateData struct {
|
|||||||
|
|
||||||
// Only used on file viewer page
|
// Only used on file viewer page
|
||||||
Title string
|
Title string
|
||||||
OGData template.HTML
|
OGData ogData
|
||||||
|
|
||||||
Other interface{}
|
Other interface{}
|
||||||
URLQuery url.Values
|
URLQuery url.Values
|
||||||
|
Reference in New Issue
Block a user