Skip to content
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

feat(gnoweb): add secure headers by default & timeout configuration #3619

Merged
merged 6 commits into from
Feb 14, 2025

Conversation

gfanton
Copy link
Member

@gfanton gfanton commented Jan 28, 2025

This PR adds the following secure headers by default strict=true to gnoweb:

func SecureHeadersMiddleware(next http.Handler, strict bool) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// Prevent MIME type sniffing by browsers. This ensures that the browser
		// does not interpret files as a different MIME type than declared.
		w.Header().Set("X-Content-Type-Options", "nosniff")

		// Prevent the page from being embedded in an iframe. This mitigates
		// clickjacking attacks by ensuring the page cannot be loaded in a frame.
		w.Header().Set("X-Frame-Options", "DENY")

		// Control the amount of referrer information sent in the Referer header.
		// 'no-referrer' ensures that no referrer information is sent, which
		// enhances privacy and prevents leakage of sensitive URLs.
		w.Header().Set("Referrer-Policy", "no-referrer")

		// In `strict` mode, prevent cross-site resource forgery and enforce https
		if strict {
			// Define a Content Security Policy (CSP) to restrict the sources of
			// scripts, styles, images, and other resources. This helps prevent
			// cross-site scripting (XSS) and other code injection attacks.
			// - 'self' allows resources from the same origin.
			// - '*' allows images from any external source.
			// - data: is not included to prevent inline images (e.g., base64-encoded images).
			w.Header().Set("Content-Security-Policy", "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' *; font-src 'self'")

			// Enforce HTTPS by telling browsers to only access the site over HTTPS
			// for a specified duration (1 year in this case). This also applies to
			// subdomains and allows preloading into the browser's HSTS list.
			w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
		}

		next.ServeHTTP(w, r)
	})
}

I've also enforced a timeout on read/write/idle (default to 1 minute).

cc @kristovatlas

@github-actions github-actions bot added the 📦 ⛰️ gno.land Issues or PRs gno.land package related label Jan 28, 2025
@Gno2D2
Copy link
Collaborator

Gno2D2 commented Jan 28, 2025

🛠 PR Checks Summary

🔴 Must not contain the "don't merge" label

Manual Checks (for Reviewers):
  • IGNORE the bot requirements for this PR (force green CI check)
Read More

🤖 This bot helps streamline PR reviews by verifying automated checks and providing guidance for contributors and reviewers.

✅ Automated Checks (for Contributors):

🟢 Maintainers must be able to edit this pull request (more info)
🔴 Must not contain the "don't merge" label

☑️ Contributor Actions:
  1. Fix any issues flagged by automated checks.
  2. Follow the Contributor Checklist to ensure your PR is ready for review.
    • Add new tests, or document why they are unnecessary.
    • Provide clear examples/screenshots, if necessary.
    • Update documentation, if required.
    • Ensure no breaking changes, or include BREAKING CHANGE notes.
    • Link related issues/PRs, where applicable.
☑️ Reviewer Actions:
  1. Complete manual checks for the PR, including the guidelines and additional checks if applicable.
📚 Resources:
Debug
Automated Checks
Maintainers must be able to edit this pull request (more info)

If

🟢 Condition met
└── 🟢 And
    ├── 🟢 The base branch matches this pattern: ^master$
    └── 🟢 The pull request was created from a fork (head branch repo: gfanton/gno)

Then

🟢 Requirement satisfied
└── 🟢 Maintainer can modify this pull request

Must not contain the "don't merge" label

If

🟢 Condition met
└── 🟢 A label matches this pattern: don't merge (label: don't merge)

Then

🔴 Requirement not satisfied
└── 🔴 On no pull request

Manual Checks
**IGNORE** the bot requirements for this PR (force green CI check)

If

🟢 Condition met
└── 🟢 On every pull request

Can be checked by

  • Any user with comment edit permission

Signed-off-by: gfanton <[email protected]>
Copy link

codecov bot commented Jan 28, 2025

Codecov Report

Attention: Patch coverage is 16.98113% with 44 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
gno.land/cmd/gnoweb/main.go 16.98% 43 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Contributor

@aeddi aeddi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM 👍 I just asked a question bellow about your strict mode

Co-authored-by: Antoine Eddi <[email protected]>
@gfanton gfanton added the don't merge Please don't merge this functionality temporarily label Jan 28, 2025
@kristovatlas
Copy link
Contributor

Can a user upload a .js file as part of their realm and use this to bypass CSP projection due to script-src 'self' ?

@kristovatlas
Copy link
Contributor

This is a good resource for security headers:
https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html

Notwithstanding my above query, the other headers set look good.

Another header we might want to consider:

Permissions-Policy: geolocation=(), camera=(), microphone=()

Once this is deployed somewhere we should double check headers with https://securityheaders.com/

@alexiscolin
Copy link
Member

@gfanton I fixed the inline CSS issue. It should be better now, even if the render should not be as fast as before (If this causes a FOUSVG issue, I will create a dedicated PR 👍)

@gfanton gfanton removed the don't merge Please don't merge this functionality temporarily label Feb 10, 2025
Copy link
Member

@thehowl thehowl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good after changes

@gfanton gfanton added the don't merge Please don't merge this functionality temporarily label Feb 10, 2025
@gfanton
Copy link
Member Author

gfanton commented Feb 10, 2025

just waiting for @sw360cab for last review, then we can merge

@gfanton gfanton requested a review from sw360cab February 10, 2025 16:28
@sw360cab sw360cab self-assigned this Feb 10, 2025
@sw360cab
Copy link
Contributor

LGTM 👍

Headers should be automatically forwarded back and forth in case Gnoweb is behind Proxy/Gateway

@gfanton gfanton merged commit 9884ba1 into gnolang:master Feb 14, 2025
61 of 64 checks passed
@gfanton gfanton deleted the feat/gnoweb/secure-headers branch February 14, 2025 13:09
thehowl pushed a commit that referenced this pull request Feb 17, 2025
Related to #3619, this PR is a hotfix for blog images from
[gno.land](https://gnolang.github.io/) until a proper generic
whitelisted image provider is implemented.

Or do we want to use base64 and replace all images from blog and realm
instead?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
don't merge Please don't merge this functionality temporarily 📦 ⛰️ gno.land Issues or PRs gno.land package related
Projects
Development

Successfully merging this pull request may close these issues.

8 participants