Sound

An experimental Swift web framework.

Sound is a web framework built with Swift and Swift-NIO. It should be seen as a playground for bike-shedding usable security in web frameworks. It is not intended to power production applications; though, for certain use-cases, it should be more than capable of doing so. Longterm, the goal is for security features implemented in Sound to act as a blueprint for other modern frameworks.

Usable Web Framework Security

A philosophy of "usable security" is the driving force behind features implemented in Sound. Users should be able to make any insecure choice they want, but it should be a conscious choice. For instance, Sound allows developers to serve files from the filesystem, but, by default, only allows files to be served from the "public" directory. Users who want to send files from arbitrary directories must specifically opt out of the security check.

For example, this will succeed:

app.get("/file") { conn, _ in 
    let cwd = FileManager.default.currentDirectoryPath
    conn.sendFile(cwd + "/public/file.txt")
}

This will fail:

app.get("/file") { conn, _ in 
    conn.sendFile("/etc/passwd")
}

And this will succeed:

app.get("/file") { conn, _ in 
    conn.sendFile("/etc/passwd", safe: false)
}

Such features will continue to be baked into the framework. As they mature, these features will be documented and the documentation will be made available here and on GitHub.

Contributing

This kind of project is only productive (and fun!) with input, so any and all contribution is welcome.

For changes that don't effect the framework API, such as documentation, style, and performance improvements, please feel free to open a PR. There is plenty that can be done here; a lot of the code could be improved, and documentation is currently lacking.

If you would like to introduce API changes or additional security features, please open up an issue so we can discuss (read: bike-shed) the security aspects. Once we formalize a feature, then you (or anyone else) can implement and make a PR.