mirror of
https://github.com/mickael-kerjean/filestash.git
synced 2024-04-21 12:32:08 +00:00
improve (security): add support for the X-Requested-With header
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
export function http_get(url, type = 'json'){
|
||||
return new Promise((done, err) => {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url, true);
|
||||
xhr.withCredentials = true;
|
||||
xhr.setRequestHeader('X-Requested-With', 'XmlHttpRequest');
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState === XMLHttpRequest.DONE) {
|
||||
if(xhr.status === 200){
|
||||
@@ -24,7 +26,6 @@ export function http_get(url, type = 'json'){
|
||||
}
|
||||
}
|
||||
}
|
||||
xhr.open('GET', url, true);
|
||||
xhr.send(null);
|
||||
});
|
||||
}
|
||||
@@ -34,6 +35,7 @@ export function http_post(url, data, type = 'json'){
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", url, true);
|
||||
xhr.withCredentials = true;
|
||||
xhr.setRequestHeader('X-Requested-With', 'XmlHttpRequest');
|
||||
if(type === 'json'){
|
||||
data = JSON.stringify(data);
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
@@ -68,6 +70,7 @@ export function http_delete(url){
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("DELETE", url, true);
|
||||
xhr.withCredentials = true;
|
||||
xhr.setRequestHeader('X-Requested-With', 'XmlHttpRequest');
|
||||
xhr.onload = function () {
|
||||
if (xhr.readyState === XMLHttpRequest.DONE) {
|
||||
if(xhr.status === 200){
|
||||
@@ -95,6 +98,7 @@ export function http_options(url){
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("OPTIONS", url, true);
|
||||
xhr.withCredentials = true;
|
||||
xhr.setRequestHeader('X-Requested-With', 'XmlHttpRequest');
|
||||
xhr.onload = function(){
|
||||
if(xhr.readyState === XMLHttpRequest.DONE){
|
||||
if(xhr.status !== 200){
|
||||
|
||||
+13
-12
@@ -41,35 +41,36 @@ func Init(a *App) {
|
||||
|
||||
// API for Session
|
||||
session := r.PathPrefix("/api/session").Subrouter()
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, SessionStart }
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, SessionStart }
|
||||
session.HandleFunc("", NewMiddlewareChain(SessionGet, middlewares, *a)).Methods("GET")
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, BodyParser }
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, BodyParser }
|
||||
session.HandleFunc("", NewMiddlewareChain(SessionAuthenticate, middlewares, *a)).Methods("POST")
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, SessionTry }
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, SessionTry }
|
||||
session.HandleFunc("", NewMiddlewareChain(SessionLogout, middlewares, *a)).Methods("DELETE")
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders }
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax }
|
||||
session.HandleFunc("/auth/{service}", NewMiddlewareChain(SessionOAuthBackend, middlewares, *a)).Methods("GET")
|
||||
|
||||
// API for admin
|
||||
middlewares = []Middleware{ ApiHeaders }
|
||||
middlewares = []Middleware{ ApiHeaders, SecureAjax }
|
||||
admin := r.PathPrefix("/admin/api").Subrouter()
|
||||
admin.HandleFunc("/session", NewMiddlewareChain(AdminSessionGet, middlewares, *a)).Methods("GET")
|
||||
admin.HandleFunc("/session", NewMiddlewareChain(AdminSessionAuthenticate, middlewares, *a)).Methods("POST")
|
||||
middlewares = []Middleware{ ApiHeaders, AdminOnly }
|
||||
middlewares = []Middleware{ ApiHeaders, AdminOnly, SecureAjax }
|
||||
admin.HandleFunc("/plugin", NewMiddlewareChain(FetchPluginsHandler, middlewares, *a)).Methods("GET")
|
||||
admin.HandleFunc("/log", NewMiddlewareChain(FetchLogHandler, middlewares, *a)).Methods("GET")
|
||||
admin.HandleFunc("/config", NewMiddlewareChain(PrivateConfigHandler, middlewares, *a)).Methods("GET")
|
||||
admin.HandleFunc("/config", NewMiddlewareChain(PrivateConfigUpdateHandler, middlewares, *a)).Methods("POST")
|
||||
middlewares = []Middleware{ IndexHeaders }
|
||||
middlewares = []Middleware{ IndexHeaders, SecureAjax }
|
||||
r.PathPrefix("/admin").Handler(http.HandlerFunc(NewMiddlewareChain(IndexHandler(FILE_INDEX), middlewares, *a))).Methods("GET")
|
||||
|
||||
// API for File management
|
||||
files := r.PathPrefix("/api/files").Subrouter()
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, SessionStart, LoggedInOnly }
|
||||
files.HandleFunc("/ls", NewMiddlewareChain(FileLs, middlewares, *a)).Methods("GET")
|
||||
files.HandleFunc("/cat", NewMiddlewareChain(FileCat, middlewares, *a)).Methods("GET", "HEAD")
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, SessionStart, LoggedInOnly }
|
||||
files.HandleFunc("/cat", NewMiddlewareChain(FileAccess, middlewares, *a)).Methods("OPTIONS")
|
||||
files.HandleFunc("/cat", NewMiddlewareChain(FileSave, middlewares, *a)).Methods("POST")
|
||||
files.HandleFunc("/ls", NewMiddlewareChain(FileLs, middlewares, *a)).Methods("GET")
|
||||
files.HandleFunc("/mv", NewMiddlewareChain(FileMv, middlewares, *a)).Methods("GET")
|
||||
files.HandleFunc("/rm", NewMiddlewareChain(FileRm, middlewares, *a)).Methods("GET")
|
||||
files.HandleFunc("/mkdir", NewMiddlewareChain(FileMkdir, middlewares, *a)).Methods("GET")
|
||||
@@ -81,13 +82,13 @@ func Init(a *App) {
|
||||
|
||||
// API for Shared link
|
||||
share := r.PathPrefix("/api/share").Subrouter()
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, SessionStart, LoggedInOnly }
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, SessionStart, LoggedInOnly }
|
||||
share.HandleFunc("", NewMiddlewareChain(ShareList, middlewares, *a)).Methods("GET")
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, BodyParser }
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, BodyParser }
|
||||
share.HandleFunc("/{share}/proof", NewMiddlewareChain(ShareVerifyProof, middlewares, *a)).Methods("POST")
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, CanManageShare }
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, CanManageShare }
|
||||
share.HandleFunc("/{share}", NewMiddlewareChain(ShareDelete, middlewares, *a)).Methods("DELETE")
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, BodyParser, CanManageShare }
|
||||
middlewares = []Middleware{ ApiHeaders, SecureHeaders, SecureAjax, BodyParser, CanManageShare }
|
||||
share.HandleFunc("/{share}", NewMiddlewareChain(ShareUpsert, middlewares, *a)).Methods("POST")
|
||||
|
||||
// Webdav server / Shared Link
|
||||
|
||||
@@ -16,6 +16,17 @@ func ApiHeaders(fn func(App, http.ResponseWriter, *http.Request)) func(ctx App,
|
||||
}
|
||||
}
|
||||
|
||||
func SecureAjax(fn func(App, http.ResponseWriter, *http.Request)) func(ctx App, res http.ResponseWriter, req *http.Request) {
|
||||
return func(ctx App, res http.ResponseWriter, req *http.Request) {
|
||||
if req.Header.Get("X-Requested-With") != "XmlHttpRequest" {
|
||||
Log.Warning("Intrusion detection: %s - %s", req.RemoteAddr, req.URL.String())
|
||||
SendErrorResult(res, ErrNotAllowed)
|
||||
return
|
||||
}
|
||||
fn(ctx, res, req)
|
||||
}
|
||||
}
|
||||
|
||||
func StaticHeaders(fn func(App, http.ResponseWriter, *http.Request)) func(ctx App, res http.ResponseWriter, req *http.Request) {
|
||||
return func(ctx App, res http.ResponseWriter, req *http.Request) {
|
||||
header := res.Header()
|
||||
@@ -49,7 +60,6 @@ func SecureHeaders(fn func(App, http.ResponseWriter, *http.Request)) func(ctx Ap
|
||||
if Config.Get("general.force_ssl").Bool() {
|
||||
header.Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
|
||||
}
|
||||
|
||||
header.Set("X-Content-Type-Options", "nosniff")
|
||||
header.Set("X-XSS-Protection", "1; mode=block")
|
||||
header.Set("X-Frame-Options", "DENY")
|
||||
|
||||
Reference in New Issue
Block a user