Mitigate CSRF attacks (#206)
This commit is contained in:
		
							parent
							
								
									97652be545
								
							
						
					
					
						commit
						031d2cb7e8
					
				|  | @ -0,0 +1,19 @@ | ||||||
|  | package handler | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"github.com/labstack/echo/v4" | ||||||
|  | 	"net/http" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // ContentTypeJson checks that the requests have the Content-Type header set to "application/json".
 | ||||||
|  | // This helps against CSRF attacks.
 | ||||||
|  | func ContentTypeJson(next echo.HandlerFunc) echo.HandlerFunc { | ||||||
|  | 	return func(c echo.Context) error { | ||||||
|  | 		contentType := c.Request().Header.Get("Content-Type") | ||||||
|  | 		if contentType != "application/json" { | ||||||
|  | 			return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Only JSON allowed"}) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return next(c) | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										54
									
								
								main.go
								
								
								
								
							
							
						
						
									
										54
									
								
								main.go
								
								
								
								
							|  | @ -96,7 +96,7 @@ func init() { | ||||||
| 	fmt.Println("Email from name\t:", util.EmailFromName) | 	fmt.Println("Email from name\t:", util.EmailFromName) | ||||||
| 	//fmt.Println("Session secret\t:", util.SessionSecret)
 | 	//fmt.Println("Session secret\t:", util.SessionSecret)
 | ||||||
| 	fmt.Println("Custom wg.conf\t:", util.WgConfTemplate) | 	fmt.Println("Custom wg.conf\t:", util.WgConfTemplate) | ||||||
| 	fmt.Println("Base path\t:", util.BasePath + "/") | 	fmt.Println("Base path\t:", util.BasePath+"/") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func main() { | func main() { | ||||||
|  | @ -124,8 +124,8 @@ func main() { | ||||||
| 	app.GET(util.BasePath, handler.WireGuardClients(db), handler.ValidSession) | 	app.GET(util.BasePath, handler.WireGuardClients(db), handler.ValidSession) | ||||||
| 
 | 
 | ||||||
| 	if !util.DisableLogin { | 	if !util.DisableLogin { | ||||||
| 		app.GET(util.BasePath + "/login", handler.LoginPage()) | 		app.GET(util.BasePath+"/login", handler.LoginPage()) | ||||||
| 		app.POST(util.BasePath + "/login", handler.Login(db)) | 		app.POST(util.BasePath+"/login", handler.Login(db)) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var sendmail emailer.Emailer | 	var sendmail emailer.Emailer | ||||||
|  | @ -135,32 +135,32 @@ func main() { | ||||||
| 		sendmail = emailer.NewSmtpMail(util.SmtpHostname, util.SmtpPort, util.SmtpUsername, util.SmtpPassword, util.SmtpNoTLSCheck, util.SmtpAuthType, util.EmailFromName, util.EmailFrom) | 		sendmail = emailer.NewSmtpMail(util.SmtpHostname, util.SmtpPort, util.SmtpUsername, util.SmtpPassword, util.SmtpNoTLSCheck, util.SmtpAuthType, util.EmailFromName, util.EmailFrom) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	app.GET(util.BasePath + "/_health", handler.Health()) | 	app.GET(util.BasePath+"/_health", handler.Health()) | ||||||
| 	app.GET(util.BasePath + "/logout", handler.Logout(), handler.ValidSession) | 	app.GET(util.BasePath+"/logout", handler.Logout(), handler.ValidSession) | ||||||
| 	app.POST(util.BasePath + "/new-client", handler.NewClient(db), handler.ValidSession) | 	app.POST(util.BasePath+"/new-client", handler.NewClient(db), handler.ValidSession, handler.ContentTypeJson) | ||||||
| 	app.POST(util.BasePath + "/update-client", handler.UpdateClient(db), handler.ValidSession) | 	app.POST(util.BasePath+"/update-client", handler.UpdateClient(db), handler.ValidSession, handler.ContentTypeJson) | ||||||
| 	app.POST(util.BasePath + "/email-client", handler.EmailClient(db, sendmail, defaultEmailSubject, defaultEmailContent), handler.ValidSession) | 	app.POST(util.BasePath+"/email-client", handler.EmailClient(db, sendmail, defaultEmailSubject, defaultEmailContent), handler.ValidSession, handler.ContentTypeJson) | ||||||
| 	app.POST(util.BasePath + "/client/set-status", handler.SetClientStatus(db), handler.ValidSession) | 	app.POST(util.BasePath+"/client/set-status", handler.SetClientStatus(db), handler.ValidSession, handler.ContentTypeJson) | ||||||
| 	app.POST(util.BasePath + "/remove-client", handler.RemoveClient(db), handler.ValidSession) | 	app.POST(util.BasePath+"/remove-client", handler.RemoveClient(db), handler.ValidSession, handler.ContentTypeJson) | ||||||
| 	app.GET(util.BasePath + "/download", handler.DownloadClient(db), handler.ValidSession) | 	app.GET(util.BasePath+"/download", handler.DownloadClient(db), handler.ValidSession) | ||||||
| 	app.GET(util.BasePath + "/wg-server", handler.WireGuardServer(db), handler.ValidSession) | 	app.GET(util.BasePath+"/wg-server", handler.WireGuardServer(db), handler.ValidSession) | ||||||
| 	app.POST(util.BasePath + "/wg-server/interfaces", handler.WireGuardServerInterfaces(db), handler.ValidSession) | 	app.POST(util.BasePath+"/wg-server/interfaces", handler.WireGuardServerInterfaces(db), handler.ValidSession, handler.ContentTypeJson) | ||||||
| 	app.POST(util.BasePath + "/wg-server/keypair", handler.WireGuardServerKeyPair(db), handler.ValidSession) | 	app.POST(util.BasePath+"/wg-server/keypair", handler.WireGuardServerKeyPair(db), handler.ValidSession, handler.ContentTypeJson) | ||||||
| 	app.GET(util.BasePath + "/global-settings", handler.GlobalSettings(db), handler.ValidSession) | 	app.GET(util.BasePath+"/global-settings", handler.GlobalSettings(db), handler.ValidSession) | ||||||
| 	app.POST(util.BasePath + "/global-settings", handler.GlobalSettingSubmit(db), handler.ValidSession) | 	app.POST(util.BasePath+"/global-settings", handler.GlobalSettingSubmit(db), handler.ValidSession, handler.ContentTypeJson) | ||||||
| 	app.GET(util.BasePath + "/status", handler.Status(db), handler.ValidSession) | 	app.GET(util.BasePath+"/status", handler.Status(db), handler.ValidSession) | ||||||
| 	app.GET(util.BasePath + "/api/clients", handler.GetClients(db), handler.ValidSession) | 	app.GET(util.BasePath+"/api/clients", handler.GetClients(db), handler.ValidSession) | ||||||
| 	app.GET(util.BasePath + "/api/client/:id", handler.GetClient(db), handler.ValidSession) | 	app.GET(util.BasePath+"/api/client/:id", handler.GetClient(db), handler.ValidSession) | ||||||
| 	app.GET(util.BasePath + "/api/machine-ips", handler.MachineIPAddresses(), handler.ValidSession) | 	app.GET(util.BasePath+"/api/machine-ips", handler.MachineIPAddresses(), handler.ValidSession) | ||||||
| 	app.GET(util.BasePath + "/api/suggest-client-ips", handler.SuggestIPAllocation(db), handler.ValidSession) | 	app.GET(util.BasePath+"/api/suggest-client-ips", handler.SuggestIPAllocation(db), handler.ValidSession) | ||||||
| 	app.GET(util.BasePath + "/api/apply-wg-config", handler.ApplyServerConfig(db, tmplBox), handler.ValidSession) | 	app.POST(util.BasePath+"/api/apply-wg-config", handler.ApplyServerConfig(db, tmplBox), handler.ValidSession, handler.ContentTypeJson) | ||||||
| 	app.GET(util.BasePath + "/wake_on_lan_hosts", handler.GetWakeOnLanHosts(db), handler.ValidSession) | 	app.GET(util.BasePath+"/wake_on_lan_hosts", handler.GetWakeOnLanHosts(db), handler.ValidSession) | ||||||
| 	app.POST(util.BasePath + "/wake_on_lan_host", handler.SaveWakeOnLanHost(db), handler.ValidSession) | 	app.POST(util.BasePath+"/wake_on_lan_host", handler.SaveWakeOnLanHost(db), handler.ValidSession, handler.ContentTypeJson) | ||||||
| 	app.DELETE(util.BasePath + "/wake_on_lan_host/:mac_address", handler.DeleteWakeOnHost(db), handler.ValidSession) | 	app.DELETE(util.BasePath+"/wake_on_lan_host/:mac_address", handler.DeleteWakeOnHost(db), handler.ValidSession, handler.ContentTypeJson) | ||||||
| 	app.PUT(util.BasePath + "/wake_on_lan_host/:mac_address", handler.WakeOnHost(db), handler.ValidSession) | 	app.PUT(util.BasePath+"/wake_on_lan_host/:mac_address", handler.WakeOnHost(db), handler.ValidSession, handler.ContentTypeJson) | ||||||
| 
 | 
 | ||||||
| 	// servers other static files
 | 	// servers other static files
 | ||||||
| 	app.GET(util.BasePath + "/static/*", echo.WrapHandler(http.StripPrefix(util.BasePath + "/static/", assetHandler))) | 	app.GET(util.BasePath+"/static/*", echo.WrapHandler(http.StripPrefix(util.BasePath+"/static/", assetHandler))) | ||||||
| 
 | 
 | ||||||
| 	app.Logger.Fatal(app.Start(util.BindAddress)) | 	app.Logger.Fatal(app.Start(util.BindAddress)) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -103,11 +103,6 @@ func New(tmplBox *rice.Box, extraData map[string]string, secret []byte) *echo.Ec | ||||||
| 	e.Logger.SetLevel(log.DEBUG) | 	e.Logger.SetLevel(log.DEBUG) | ||||||
| 	e.Pre(middleware.RemoveTrailingSlash()) | 	e.Pre(middleware.RemoveTrailingSlash()) | ||||||
| 	e.Use(middleware.Logger()) | 	e.Use(middleware.Logger()) | ||||||
| 	e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ |  | ||||||
| 		AllowOrigins: []string{"*"}, |  | ||||||
| 		AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept, echo.HeaderAuthorization}, |  | ||||||
| 		AllowMethods: []string{echo.GET, echo.HEAD, echo.PUT, echo.PATCH, echo.POST, echo.DELETE}, |  | ||||||
| 	})) |  | ||||||
| 	e.HideBanner = true | 	e.HideBanner = true | ||||||
| 	e.Validator = NewValidator() | 	e.Validator = NewValidator() | ||||||
| 	e.Renderer = &TemplateRegistry{ | 	e.Renderer = &TemplateRegistry{ | ||||||
|  |  | ||||||
|  | @ -494,7 +494,7 @@ | ||||||
|             $("#apply_config_confirm").click(function () { |             $("#apply_config_confirm").click(function () { | ||||||
|                 $.ajax({ |                 $.ajax({ | ||||||
|                     cache: false, |                     cache: false, | ||||||
|                     method: 'GET', |                     method: 'POST', | ||||||
|                     url: '{{.basePath}}/api/apply-wg-config', |                     url: '{{.basePath}}/api/apply-wg-config', | ||||||
|                     dataType: 'json', |                     dataType: 'json', | ||||||
|                     contentType: "application/json", |                     contentType: "application/json", | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue