improve (security): add support for the X-Requested-With header

This commit is contained in:
Mickael KERJEAN
2019-03-08 17:49:17 +11:00
parent c431b64b64
commit ea48dbe128
3 changed files with 29 additions and 14 deletions
+5 -1
View File
@@ -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
View File
@@ -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
+11 -1
View File
@@ -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")