Skip to content
This repository was archived by the owner on May 25, 2023. It is now read-only.

Commit f74d2a8

Browse files
committed
Added REDIRECT_ALLOW_TARGET option (defaults to HTTP referer).
1 parent 3ddcbe6 commit f74d2a8

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

server/gae-go/app/main.go

+28-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* jQuery File Upload Plugin GAE Go Example 4.0.0
2+
* jQuery File Upload Plugin GAE Go Example 4.1.0
33
* https://github.com/blueimp/jQuery-File-Upload
44
*
55
* Copyright 2011, Sebastian Tschan
@@ -44,6 +44,9 @@ const (
4444
THUMB_MAX_WIDTH = 80
4545
THUMB_MAX_HEIGHT = 80
4646
EXPIRATION_TIME = 300 // seconds
47+
// If empty, only allow redirects to the referer protocol+host.
48+
// Set to a regexp string for custom pattern matching:
49+
REDIRECT_ALLOW_TARGET = ""
4750
)
4851

4952
var (
@@ -220,6 +223,29 @@ func handleUploads(r *http.Request) (fileInfos []*FileInfo) {
220223
return
221224
}
222225

226+
func validateRedirect(r *http.Request, redirect string) bool {
227+
if redirect != "" {
228+
var redirectAllowTarget *regexp.Regexp
229+
if REDIRECT_ALLOW_TARGET != "" {
230+
redirectAllowTarget = regexp.MustCompile(REDIRECT_ALLOW_TARGET)
231+
} else {
232+
referer := r.Referer()
233+
if referer == "" {
234+
return false
235+
}
236+
refererUrl, err := url.Parse(referer)
237+
if err != nil {
238+
return false
239+
}
240+
redirectAllowTarget = regexp.MustCompile("^" + regexp.QuoteMeta(
241+
refererUrl.Scheme + "://" + refererUrl.Host + "/",
242+
))
243+
}
244+
return redirectAllowTarget.MatchString(redirect)
245+
}
246+
return false
247+
}
248+
223249
func get(w http.ResponseWriter, r *http.Request) {
224250
if r.URL.Path == "/" {
225251
http.Redirect(w, r, WEBSITE, http.StatusFound)
@@ -254,7 +280,7 @@ func post(w http.ResponseWriter, r *http.Request) {
254280
result["files"] = handleUploads(r)
255281
b, err := json.Marshal(result)
256282
check(err)
257-
if redirect := r.FormValue("redirect"); redirect != "" {
283+
if redirect := r.FormValue("redirect"); validateRedirect(r, redirect) {
258284
if strings.Contains(redirect, "%s") {
259285
redirect = fmt.Sprintf(
260286
redirect,

server/gae-python/main.py

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
22
#
3-
# jQuery File Upload Plugin GAE Python Example 3.0.0
3+
# jQuery File Upload Plugin GAE Python Example 3.1.0
44
# https://github.com/blueimp/jQuery-File-Upload
55
#
66
# Copyright 2011, Sebastian Tschan
@@ -28,6 +28,9 @@
2828
THUMB_MAX_HEIGHT = 80
2929
THUMB_SUFFIX = '.'+str(THUMB_MAX_WIDTH)+'x'+str(THUMB_MAX_HEIGHT)+'.png'
3030
EXPIRATION_TIME = 300 # seconds
31+
# If set to None, only allow redirects to the referer protocol+host.
32+
# Set to a regexp for custom pattern matching against the redirect value:
33+
REDIRECT_ALLOW_TARGET = None
3134

3235
class CORSHandler(webapp2.RequestHandler):
3336
def cors(self):
@@ -60,6 +63,20 @@ def validate(self, file):
6063
return True
6164
return False
6265

66+
def validate_redirect(self, redirect):
67+
if redirect:
68+
if REDIRECT_ALLOW_TARGET:
69+
return REDIRECT_ALLOW_TARGET.match(redirect)
70+
referer = self.request.headers['referer']
71+
if referer:
72+
from urlparse import urlparse
73+
parts = urlparse(referer)
74+
redirect_allow_target = '^' + re.escape(
75+
parts.scheme + '://' + parts.netloc + '/'
76+
)
77+
return re.match(redirect_allow_target, redirect)
78+
return False
79+
6380
def get_file_size(self, file):
6481
file.seek(0, 2) # Seek to the end of the file
6582
size = file.tell() # Get the position of EOF
@@ -131,7 +148,7 @@ def post(self):
131148
result = {'files': self.handle_upload()}
132149
s = self.json_stringify(result)
133150
redirect = self.request.get('redirect')
134-
if redirect:
151+
if self.validate_redirect(redirect):
135152
return self.redirect(str(
136153
redirect.replace('%s', urllib.quote(s, ''), 1)
137154
))

0 commit comments

Comments
 (0)