Skip to content

Commit b76d2f5

Browse files
authored
refactor: change to check by prefix (#1)
1 parent 9e78dff commit b76d2f5

File tree

5 files changed

+131
-50
lines changed

5 files changed

+131
-50
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## 1.0.0 (2024-11-11)
2+
3+
- Implement Allowed Host Middleware

Package.resolved

Lines changed: 106 additions & 43 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ let package = Package(
1616
],
1717
dependencies: [
1818
// 💧 A server-side Swift web framework.
19-
.package(url: "https://github.com/vapor/vapor.git", from: "4.0.0"),
19+
.package(url: "https://github.com/vapor/vapor.git", from: "4.115.0"),
2020
],
2121
targets: [
2222
// Targets are the basic building blocks of a package, defining a module or a test suite.

Sources/AllowedHostsMiddleware/AllowedHostsMiddleware.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,17 @@ public struct AllowedHostsMiddleware: AsyncMiddleware {
3939
public func respond(to request: Request, chainingTo next: AsyncResponder) async throws -> Response {
4040
request.logger.debug("IpAddress headers - \(String(describing: request.headers))")
4141
guard let ipAddress = request.remoteAddress?.ipAddress else {
42-
request.application.logger.error("Access attempt without an authorized IP address")
42+
request.application.logger.error("Access attempt without an authorized IP address. IP address: \(String(describing: request.remoteAddress?.ipAddress))")
4343
throw HostError.notAcceptable
4444
}
45-
if !request.application.allowedHosts.contains(ipAddress) {
46-
request.application.logger.error("Unauthorized access attempt from IP address: \(ipAddress)")
47-
throw HostError.unauthorizedAccessAttempt
45+
let parts = ipAddress.split(separator: ".")
46+
let prefix = parts.dropLast().joined(separator: ".")
47+
request.application.logger.debug("Prefix of IP address: \(prefix)")
48+
for allowedHost in request.application.allowedHosts {
49+
guard allowedHost.hasPrefix(prefix) else {
50+
request.application.logger.error("Unauthorized access attempt from IP address: \(ipAddress)")
51+
throw HostError.unauthorizedAccessAttempt
52+
}
4853
}
4954
return try await next.respond(to: request)
5055
}

Sources/AllowedHostsMiddleware/Extensions/Application+Extensions.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,25 @@
2424

2525
import Vapor
2626

27-
/// Extension for core type representing a Vapor application.
2827
extension Application {
28+
/// Stores and manages a list of allowed hostnames for the application.
29+
/// This extension adds a typed storage property `allowedHosts` to the `Application`
30+
/// instance. It uses Vapor's `StorageKey` mechanism to safely store and retrieve
31+
/// an array of allowed hostnames, typically used for validating incoming requests
32+
/// or enforcing CORS/security rules. If the value is not found in storage, an
33+
/// error is logged and an empty array is returned.
2934
/// A `AllowedHostsKey` conform to StorageKey protocol
3035
private struct AllowedHostsKey: StorageKey {
3136
/// Less verbose typealias for `[String]`.
3237
typealias Value = [String]
3338
}
3439

35-
/// Setup `allowedHosts` in application storage
40+
/// Gets or sets the list of allowed hosts for the application.
41+
/// Accesses an array of strings representing allowed hostnames stored
42+
/// in the application's storage. If accessed before a value is set,
43+
/// the function logs an error and returns an empty array. Values assigned
44+
/// to this property are persisted in `Application.Storage` via the
45+
/// `AllowedHostsKey`.
3646
public var allowedHosts: [String] {
3747
get {
3848
guard let allowedHosts = storage[AllowedHostsKey.self] else {

0 commit comments

Comments
 (0)