Skip to content

Commit ca893ac

Browse files
Add SecureHeaders pipe to default web pipeline
Co-authored-by: renich <225115+renich@users.noreply.github.com>
1 parent 0715387 commit ca893ac

4 files changed

Lines changed: 52 additions & 0 deletions

File tree

.jules/sentinel.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## 2024-05-24 - [Missing Default Security Headers]
2+
**Vulnerability:** Newly generated Amber framework apps omit foundational HTTP security headers (e.g., XSS Protection, Content-Type Options).
3+
**Learning:** The pipeline configuration in `routes.cr.ecr` lacked a dedicated middleware pipe to enforce baseline security headers for web routes.
4+
**Prevention:** Always include a SecureHeaders middleware in the default web pipeline to ensure a defense-in-depth posture out of the box.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
require "../../spec_helper"
2+
3+
module Amber::Pipe
4+
describe SecureHeaders do
5+
it "adds security headers to the response" do
6+
request = HTTP::Request.new("GET", "/")
7+
response = HTTP::Server::Response.new(IO::Memory.new)
8+
context = HTTP::Server::Context.new(request, response)
9+
10+
pipe = SecureHeaders.new
11+
pipe.next = HTTP::Handler::HandlerProc.new { |ctx| }
12+
13+
pipe.call(context)
14+
15+
context.response.headers["X-Content-Type-Options"].should eq "nosniff"
16+
context.response.headers["X-XSS-Protection"].should eq "1; mode=block"
17+
context.response.headers["X-Frame-Options"].should eq "SAMEORIGIN"
18+
context.response.headers["Strict-Transport-Security"].should eq "max-age=31536000; includeSubDomains"
19+
end
20+
end
21+
end

src/amber/cli/templates/app/config/routes.cr.ecr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Amber::Server.configure do
1010
plug Amber::Pipe::Session.new
1111
plug Amber::Pipe::Flash.new
1212
plug Amber::Pipe::CSRF.new
13+
plug Amber::Pipe::SecureHeaders.new
1314
end
1415

1516
pipeline :api do

src/amber/pipes/secure_headers.cr

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module Amber
2+
module Pipe
3+
# The SecureHeaders pipe sets security-related HTTP headers to help
4+
# protect against common vulnerabilities like XSS, clickjacking, and MIME sniffing.
5+
class SecureHeaders < Base
6+
def call(context : HTTP::Server::Context)
7+
headers = context.response.headers
8+
9+
# Prevent browser from guessing the MIME type
10+
headers["X-Content-Type-Options"] ||= "nosniff"
11+
12+
# Enable XSS filtering in browsers
13+
headers["X-XSS-Protection"] ||= "1; mode=block"
14+
15+
# Prevent clickjacking by not allowing the page to be framed
16+
headers["X-Frame-Options"] ||= "SAMEORIGIN"
17+
18+
# Enforce HTTPS connections (if using HTTPS)
19+
# Note: In a real production app, you might want to configure max-age or includeSubDomains
20+
headers["Strict-Transport-Security"] ||= "max-age=31536000; includeSubDomains"
21+
22+
call_next(context)
23+
end
24+
end
25+
end
26+
end

0 commit comments

Comments
 (0)