-
Notifications
You must be signed in to change notification settings - Fork 215
Add wai-csp middleware for type-safe Content Security Policy #2187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Co-authored-by: amitaibu <125707+amitaibu@users.noreply.github.com>
Co-authored-by: amitaibu <125707+amitaibu@users.noreply.github.com>
Co-authored-by: amitaibu <125707+amitaibu@users.noreply.github.com>
Guide/csp.markdown
Outdated
| |] | ||
| where | ||
| customScript = do | ||
| let CSP.CSPNonce nonce = fromFrozenContext |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be injected from the controller to the view
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in commit 66c4bd5. The nonce is now injected from the middleware into the request vault, and views retrieve it using Vault.lookup CSP.cspNonceKey request.vault. The guide now shows the recommended pattern with a helper function in Web/View/Prelude.hs for cleaner access.
|
I think this might be more useful if we design it as a generic wai middleware. basically |
|
I'll redesign this as a |
Co-authored-by: amitaibu <125707+amitaibu@users.noreply.github.com>
…ormIO, simplify bindings Co-authored-by: amitaibu <125707+amitaibu@users.noreply.github.com>
Guide/csp.markdown
Outdated
| |] | ||
| where | ||
| customScript = | ||
| let Just (CSP.CSPNonce nonceValue) = Vault.lookup CSP.cspNonceKey request.vault |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot View shouldn't deal with the valut, just extract the nonceValue. That (noneValue :: Maybe Text) should be injected via Controller.
But more importantly we already have Using Nonces in Views so consoldiate. Review entire markdown to confirm it's up to date
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in commit e12c9b4.
Changes made:
- Views now use
fromFrozenContextto get the nonce (following IHP patterns) - Controllers extract the nonce from the request vault and inject it into context using
putContext - Consolidated the duplicate "Using Nonces in Views" sections
- Reviewed and updated the entire guide to follow consistent IHP patterns throughout
The guide now shows the proper three-step pattern:
- Step 1: Add middleware in Config
- Step 2: Extract nonce in controller's beforeAction and putContext
- Step 3: Use fromFrozenContext in views
…and fromFrozenContext Co-authored-by: amitaibu <125707+amitaibu@users.noreply.github.com>
Co-authored-by: amitaibu <125707+amitaibu@users.noreply.github.com>
Adds a new
wai-csppackage providing type-safe CSP middleware for WAI applications with nonce support, replacing error-prone string concatenation.Package Structure
Key Features
cspMiddleware- Static CSP policycspMiddlewareWithNonce- Auto-generates cryptographically secure nonces per requestcspNonceKey)defaultCSP(safe baseline),strictCSP(nonce-based)self,none,nonce,host,data',strictDynamic, etc.reportUri,upgradeInsecureRequestsIHP Integration Pattern
The implementation follows standard IHP patterns for data flow:
Step 1: Add middleware in
Config/Config.hs:Step 2: Extract nonce in controller's
beforeActionand inject into context:Step 3: Use
fromFrozenContextin views:This follows the standard IHP convention where controllers use
putContextto inject data into the context, and views usefromFrozenContextto retrieve it, maintaining proper separation of concerns.Usage Comparison
Before (manual string-based):
After (type-safe middleware):
Custom policies:
Documentation
Architecture
The middleware follows the pattern of existing IHP WAI packages like
wai-flash-messagesandwai-asset-path, making it framework-agnostic and easy to integrate globally via the middleware stack. For IHP applications, the nonce is extracted from the request vault in the controller and injected into the context, allowing views to access it using the standardfromFrozenContextpattern.Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.