Skip to content

Commit

Permalink
Add security headers to all responses
Browse files Browse the repository at this point in the history
  • Loading branch information
mczachurski committed Nov 10, 2024
1 parent f25c9c5 commit de9ea2b
Show file tree
Hide file tree
Showing 43 changed files with 216 additions and 26 deletions.
8 changes: 6 additions & 2 deletions Sources/VernissageServer/Application+Configure.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,15 @@ extension Application {
)
let corsMiddleware = CORSMiddleware(configuration: corsConfiguration)
self.middleware.use(corsMiddleware, at: .beginning)

// Catches errors and converts to HTTP response.
// Custom response header middleware.
let errorMiddleware = CustomErrorMiddleware()
self.middleware.use(errorMiddleware)

// Atatch common headers to HTTP response.
let commonHeadersMiddleware = CommonHeadersMiddleware()
self.middleware.use(commonHeadersMiddleware)

// Configure public files middleware.
let publicFolderPath = self.directory.publicDirectory
let fileMiddleware = FileMiddleware(
Expand Down
17 changes: 0 additions & 17 deletions Sources/VernissageServer/Cache/CacheControlMiddleware.swift

This file was deleted.

13 changes: 13 additions & 0 deletions Sources/VernissageServer/Controllers/AccountController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ extension AccountController: RouteCollection {

accountGroup
.grouped(LoginHandlerMiddleware())
.grouped(CacheControlMiddleware(.noStore))
.post("login", use: login)

accountGroup
.grouped(EventHandlerMiddleware(.accountLogout))
.grouped(CacheControlMiddleware(.noStore))
.post("logout", use: logout)

accountGroup
.grouped(EventHandlerMiddleware(.accountConfirm))
.grouped(CacheControlMiddleware(.noStore))
.grouped("email")
.post("confirm", use: confirm)

Expand All @@ -35,6 +38,7 @@ extension AccountController: RouteCollection {
.grouped(UserPayload.guardMiddleware())
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.accountConfirm))
.grouped(CacheControlMiddleware(.noStore))
.grouped("email")
.post("resend", use: resend)

Expand All @@ -43,54 +47,63 @@ extension AccountController: RouteCollection {
.grouped(UserPayload.guardMiddleware())
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.accountChangeEmail))
.grouped(CacheControlMiddleware(.noStore))
.put("email", use: changeEmail)

accountGroup
.grouped(UserAuthenticator())
.grouped(UserPayload.guardMiddleware())
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.accountChangePassword, storeRequest: false))
.grouped(CacheControlMiddleware(.noStore))
.put("password", use: changePassword)

accountGroup
.grouped(EventHandlerMiddleware(.accountForgotToken))
.grouped(CacheControlMiddleware(.noStore))
.grouped("forgot")
.post("token", use: forgotPasswordToken)

accountGroup
.grouped(EventHandlerMiddleware(.accountForgotConfirm, storeRequest: false))
.grouped(CacheControlMiddleware(.noStore))
.grouped("forgot")
.post("confirm", use: forgotPasswordConfirm)

accountGroup
.grouped(EventHandlerMiddleware(.accountRefresh))
.grouped(CacheControlMiddleware(.noStore))
.post("refresh-token", use: refresh)

accountGroup
.grouped(UserAuthenticator())
.grouped(UserPayload.guardMiddleware())
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.accountRevoke))
.grouped(CacheControlMiddleware(.noStore))
.delete("refresh-token", ":username", use: revoke)

accountGroup
.grouped(UserAuthenticator())
.grouped(UserPayload.guardMiddleware())
.grouped(EventHandlerMiddleware(.accountGetTwoFactorToken))
.grouped(CacheControlMiddleware(.noStore))
.get("get-2fa-token", use: getTwoFactorToken)

accountGroup
.grouped(UserAuthenticator())
.grouped(UserPayload.guardMiddleware())
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.accountEnableTwoFactorAuthentication))
.grouped(CacheControlMiddleware(.noStore))
.post("enable-2fa", use: enableTwoFactorAuthentication)

accountGroup
.grouped(UserAuthenticator())
.grouped(UserPayload.guardMiddleware())
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.accountDisableTwoFactorAuthentication))
.grouped(CacheControlMiddleware(.noStore))
.post("disable-2fa", use: disableTwoFactorAuthentication)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ extension ActivityPubActorController: RouteCollection {

actorGroup
.grouped(EventHandlerMiddleware(.actorRead))
.grouped(CacheControlMiddleware(.public()))
.get(use: read)

actorGroup
.grouped(EventHandlerMiddleware(.activityPubInbox))
.grouped(CacheControlMiddleware(.noStore))
.post("inbox", use: inbox)

actorGroup
.grouped(EventHandlerMiddleware(.activityPubOutbox))
.grouped(CacheControlMiddleware(.noStore))
.post("outbox", use: outbox)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,39 @@ extension ActivityPubActorsController: RouteCollection {

activityPubGroup
.grouped(EventHandlerMiddleware(.activityPubRead))
.grouped(CacheControlMiddleware(.noStore))
.get(":name", use: read)

activityPubGroup
.grouped(EventHandlerMiddleware(.activityPubInbox))
.grouped(CacheControlMiddleware(.noStore))
.post(":name", "inbox", use: inbox)

activityPubGroup
.grouped(EventHandlerMiddleware(.activityPubOutbox))
.grouped(CacheControlMiddleware(.noStore))
.post(":name", "outbox", use: outbox)

activityPubGroup
.grouped(EventHandlerMiddleware(.activityPubFollowing))
.grouped(CacheControlMiddleware(.noStore))
.get(":name", "following", use: following)

activityPubGroup
.grouped(EventHandlerMiddleware(.activityPubFollowers))
.grouped(CacheControlMiddleware(.noStore))
.get(":name", "followers", use: followers)

// Support for: https://example.com/@johndoe/statuses/:id
activityPubGroup
.grouped(EventHandlerMiddleware(.activityPubStatus))
.grouped(CacheControlMiddleware(.noStore))
.get(":name", "statuses", ":id", use: status)

// Support for: https://example.com/statuses/:id
statusesGroup
.grouped(EventHandlerMiddleware(.activityPubStatus))
.grouped(CacheControlMiddleware(.noStore))
.get(":id", use: status)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ extension ActivityPubSharedController: RouteCollection {

activityPubSharedGroup
.grouped(EventHandlerMiddleware(.activityPubSharedInbox))
.grouped(CacheControlMiddleware(.noStore))
.post("inbox", use: inbox)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,41 @@ extension AttachmentsController: RouteCollection {
photosGroup
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.attachmentsCreate))
.grouped(CacheControlMiddleware(.noStore))
.on(.POST, AttachmentsController.uri, body: .collect(maxSize: "20mb"), use: upload)

photosGroup
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.attachmentsHdrCreate))
.grouped(CacheControlMiddleware(.noStore))
.on(.POST, AttachmentsController.uri, ":id", "hdr", body: .collect(maxSize: "20mb"), use: uploadHdr)

photosGroup
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.attachmentsHdrDelete))
.grouped(CacheControlMiddleware(.noStore))
.on(.DELETE, AttachmentsController.uri, ":id", "hdr", use: deleteHdr)

photosGroup
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.attachmentsUpdate))
.grouped(CacheControlMiddleware(.noStore))
.put(AttachmentsController.uri, ":id", use: update)

photosGroup
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.attachmentsDelete))
.grouped(CacheControlMiddleware(.noStore))
.delete(AttachmentsController.uri, ":id", use: delete)

photosGroup
.grouped(EventHandlerMiddleware(.attachmentsDescribe))
.grouped(CacheControlMiddleware(.noStore))
.get(AttachmentsController.uri, ":id", "describe", use: describe)

photosGroup
.grouped(EventHandlerMiddleware(.attachmentsHashtags))
.grouped(CacheControlMiddleware(.noStore))
.get(AttachmentsController.uri, ":id", "hashtags", use: hashtags)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@ extension AuthenticationClientsController: RouteCollection {
.grouped(UserPayload.guardIsAdministratorMiddleware())
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.authClientsCreate))
.grouped(CacheControlMiddleware(.noStore))
.post(use: create)

authClientsGroup
.grouped(EventHandlerMiddleware(.authClientsList))
.grouped(CacheControlMiddleware(.noStore))
.get(use: list)

authClientsGroup
.grouped(EventHandlerMiddleware(.authClientsRead))
.grouped(CacheControlMiddleware(.noStore))
.get(":id", use: read)

authClientsGroup
Expand All @@ -39,6 +42,7 @@ extension AuthenticationClientsController: RouteCollection {
.grouped(UserPayload.guardIsAdministratorMiddleware())
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.authClientsUpdate))
.grouped(CacheControlMiddleware(.noStore))
.put(":id", use: update)

authClientsGroup
Expand All @@ -47,6 +51,7 @@ extension AuthenticationClientsController: RouteCollection {
.grouped(UserPayload.guardIsAdministratorMiddleware())
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.authClientsDelete))
.grouped(CacheControlMiddleware(.noStore))
.delete(":id", use: delete)
}
}
Expand Down
2 changes: 2 additions & 0 deletions Sources/VernissageServer/Controllers/AvatarsController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ extension AvatarsController: RouteCollection {
usersGroup
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.avatarUpdate))
.grouped(CacheControlMiddleware(.noStore))
.on(.POST, ":name", body: .collect(maxSize: "2mb"), use: update)

usersGroup
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.avatarDelete))
.grouped(CacheControlMiddleware(.noStore))
.delete(":name", use: delete)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ extension BookmarksController: RouteCollection {

timelinesGroup
.grouped(EventHandlerMiddleware(.bookmarksList))
.grouped(CacheControlMiddleware(.noStore))
.get(use: list)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ extension CategoriesController: RouteCollection {

locationsGroup
.grouped(EventHandlerMiddleware(.categoriesList))
.grouped(CacheControlMiddleware(.public()))
.get(use: list)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ extension CountriesController: RouteCollection {

locationsGroup
.grouped(EventHandlerMiddleware(.countriesList))
.grouped(CacheControlMiddleware())
.grouped(CacheControlMiddleware(.public()))
.get(use: list)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,20 @@ extension ErrorItemsController: RouteCollection {
errorItemsGroup
.grouped(UserPayload.guardIsModeratorMiddleware())
.grouped(EventHandlerMiddleware(.errorList))
.grouped(CacheControlMiddleware(.noStore))
.get(use: list)

errorItemsGroup
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.errorCreate))
.grouped(CacheControlMiddleware(.noStore))
.post(use: create)

errorItemsGroup
.grouped(UserPayload.guardIsModeratorMiddleware())
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.errorDelete))
.grouped(CacheControlMiddleware(.noStore))
.delete(":id", use: delete)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ extension FavouritesController: RouteCollection {

timelinesGroup
.grouped(EventHandlerMiddleware(.favouritesList))
.grouped(CacheControlMiddleware(.noStore))
.get(use: list)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,19 @@ extension FollowRequestsController: RouteCollection {

relationshipsGroup
.grouped(EventHandlerMiddleware(.followRequestList))
.grouped(CacheControlMiddleware(.noStore))
.get(use: list)

relationshipsGroup
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.followRequestApprove))
.grouped(CacheControlMiddleware(.noStore))
.post(":id", "approve", use: approve)

relationshipsGroup
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.followRequestReject))
.grouped(CacheControlMiddleware(.noStore))
.post(":id", "reject", use: reject)
}
}
Expand Down
2 changes: 2 additions & 0 deletions Sources/VernissageServer/Controllers/HeadersController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ extension HeadersController: RouteCollection {
usersGroup
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.headerUpdate))
.grouped(CacheControlMiddleware(.noStore))
.on(.POST, ":name", body: .collect(maxSize: "2mb"), use: update)

usersGroup
.grouped(XsrfTokenValidatorMiddleware())
.grouped(EventHandlerMiddleware(.headerDelete))
.grouped(CacheControlMiddleware(.noStore))
.delete(":name", use: delete)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ extension HealthController: RouteCollection {

locationsGroup
.grouped(EventHandlerMiddleware(.healthRead))
.grouped(CacheControlMiddleware(.noStore))
.get(use: read)
}
}
Expand Down
3 changes: 3 additions & 0 deletions Sources/VernissageServer/Controllers/IdentityController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@ extension IdentityController: RouteCollection {
.grouped(IdentityController.uri)

identityGroup
.grouped(CacheControlMiddleware(.noStore))
.get("authenticate", ":uri", use: authenticate)

identityGroup
.grouped(CacheControlMiddleware(.noStore))
.get("callback", ":uri", use: callback)

identityGroup
.grouped(CacheControlMiddleware(.noStore))
.post("login", use: login)
}
}
Expand Down
Loading

0 comments on commit de9ea2b

Please sign in to comment.