{"id":13430819,"url":"https://github.com/google/go-safeweb","last_synced_at":"2026-10-19T12:44:12.728Z","repository":{"id":44773389,"uuid":"265190306","full_name":"google/go-safeweb","owner":"google","description":"Secure-by-default HTTP servers in Go.","archived":true,"fork":false,"pushed_at":"2025-05-30T15:31:02.000Z","size":4824,"stargazers_count":1491,"open_issues_count":59,"forks_count":86,"subscribers_count":35,"default_branch":"master","last_synced_at":"2026-09-28T03:24:23.931Z","etag":null,"topics":["golang","http","http-server","security","security-hardening"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/google.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/contributing.md","funding":null,"license":"LICENSE","code_of_conduct":"docs/code-of-conduct.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-05-19T08:30:35.000Z","updated_at":"2026-09-27T16:25:17.000Z","dependencies_parsed_at":"2023-12-19T07:36:18.367Z","dependency_job_id":"8fa48fde-61fb-45c5-bee1-0d488ef3732a","html_url":"https://github.com/google/go-safeweb","commit_stats":{"total_commits":755,"total_committers":15,"mean_commits":"50.333333333333336","dds":0.7099337748344371,"last_synced_commit":"f1150765a6462e3597c03aa1f32beb8fd94570c5"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/google/go-safeweb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google%2Fgo-safeweb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google%2Fgo-safeweb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google%2Fgo-safeweb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google%2Fgo-safeweb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/google","download_url":"https://codeload.github.com/google/go-safeweb/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/google%2Fgo-safeweb/sbom","scorecard":{"id":437061,"data":{"date":"2025-08-11","repo":{"name":"github.com/google/go-safeweb","commit":"70ff0f2fa2945c0c9498a2a4bc4f416e50384f9b"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.9,"checks":[{"name":"Maintained","score":1,"reason":"2 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":7,"reason":"Found 12/16 approved changesets -- score normalized to 7","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/main.yaml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/google/go-safeweb/main.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/google/go-safeweb/main.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/google/go-safeweb/main.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/google/go-safeweb/main.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/google/go-safeweb/main.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:57: update your workflow using https://app.stepsecurity.io/secureworkflow/google/go-safeweb/main.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:69: update your workflow using https://app.stepsecurity.io/secureworkflow/google/go-safeweb/main.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:75: update your workflow using https://app.stepsecurity.io/secureworkflow/google/go-safeweb/main.yaml/master?enable=pin","Info:   0 out of   8 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: github.com/google/.github/SECURITY.md:1","Info: Found linked content: github.com/google/.github/SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: github.com/google/.github/SECURITY.md:1","Info: Found text in security policy: github.com/google/.github/SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 2 commits out of 26 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":6,"reason":"4 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2025-3487 / GHSA-hcg3-q754-cr77","Warn: Project is vulnerable to: GO-2024-3333","Warn: Project is vulnerable to: GO-2025-3503 / GHSA-qxp5-gwg8-xv66","Warn: Project is vulnerable to: GO-2025-3595 / GHSA-vvgc-356p-c3xw"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T04:56:23.347Z","repository_id":44773389,"created_at":"2025-08-19T04:56:23.347Z","updated_at":"2025-08-19T04:56:23.347Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":344872684,"owners_count":38356472,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-10-03T21:59:58.778Z","status":"online","status_checked_at":"2026-10-19T02:00:06.414Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","http","http-server","security","security-hardening"],"created_at":"2024-07-31T02:00:58.097Z","updated_at":"2026-10-19T12:44:12.397Z","avatar_url":"https://github.com/google.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# go-safeweb\n\n**DISCLAIMER**: This is not an officially supported Google product.\n\n`go-safeweb` is a collection of libraries for writing secure-by-default HTTP\nservers in Go.\n\n## Contributing\n\nThis project is in an early stage. We are currently **not accepting** any\ncontributions.\n\n## Overview\n\nThe flexibility of Go’s [`net/http`](https://pkg.go.dev/net/http/) package\nallows users to quickly implement HTTP servers.\n\nResponses are then written simply as slices of bytes, headers can be arbitrarily\nmanipulated and so on. This approach offers much needed flexibility for these\nwho really need it.\n\nUnfortunately, this approach leaves great space for introducing security\nvulnerabilities and even experienced developers tend to do so.\n\nThis document aims to design an HTTP API that eliminates whole classes of bugs,\nlike Cross-Site Scripting (XSS) or Cross-Site Request Forgery (XSRF). This can\nbe achieved by an approach known at Google as _safe coding_. Learn more at\n[Securing the Tangled Web (Chistoph Kern, 2014)](http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/42934.pdf)\nor\n[Preventing Security Bugs through Software Design (Christoph Kern, 2016)](https://www.youtube.com/watch?v=ccfEu-Jj0as).\n\n## Goals and Non-Goals\n\n### Goals\n\n#### G1: Secure-by-default\n\nSecurity mechanisms are applied by default (opt-out, not opt-in).\n\n#### G2: Unsafe Usage is Easy to Review, Track and Restrict\n\nAll opt-outs from security mechanisms are explicit. Wherever possible, they’re\ncontained inside a package or an option that’s easy to restrict.\n\n#### G3: Designed for Evolving Security Requirements\n\nEnforcing new security measures is feasible through AST manipulation. Existing\nusers can be migrated using static analysis and/or runtime monitoring. Read more\n[here](#evolving-security-requirements-example).\n\n#### G4: High Compatibility with Go’s Standard Library and Existing Open-Source Frameworks\n\nWhenever possible, keep existing layouts, function signatures and other API\nparts the same as the Go’s standard library. High compatibility enables wide\nadoption.\n\n### Non Goals\n\n#### NG1: Safe API [Completeness](\u003chttps://en.wikipedia.org/wiki/Completeness_(logic)\u003e)\n\nCreating safe APIs for all the corner cases might result in a bloated codebase.\nOur experience shows that this isn’t necessary.\n\n#### NG2: Full Compatibility with Go’s Standard Library and Existing Open-Source Frameworks\n\nExisting open-source frameworks or the Go standard library need to support each\ndeveloper scenario. This would have left us with limited options of creating\nsafe-by-default HTTP servers.\n\n#### NG3: Features That Are Not Security Critical\n\nGo Safe Web aims to help you create a secure-by-default Go HTTP server and\nnothing more. Features that are not security critical will not be added.\nFocusing solely on security allows us to maintain high compatibility with the\nstandard library and makes adoption easier.\n\n## Security Vulnerabilities and Mitigations\n\nOn a high level, we plan to address, or provide the needed infrastructure to\naddress, following issues (not an exhaustive list):\n\n- **XSS (cross-site scripting) and XSSI (cross-site script inclusion)** - e.g.\n  by controlling how responses are generated\n- **XSRF (cross-site request forgery)** - e.g. by using Fetch Metadata policies,\n  supporting token-based XSRF protection\n- **CORS (cross-origin resource sharing)** - e.g. by taking control of CORS\n  response headers and handling CORS preflight requests\n- [**CSP (content security policy)**](https://csp.withgoogle.com/docs/index.html) -\n  e.g. by automatically adding script nonces to HTML responses, adding relevant\n  security headers\n- **Transport Security** - e.g. by\n  [enforcing HSTS support](safehttp/plugins/hsts)\n- **IFraming** - e.g. by setting relevant HTTP headers to restrict framing or\n  providing server-side support for origin selection\n- **Auth (access control)** - e.g. by providing infrastructure for plugging in\n  access control logic in an uniform, auditable way\n- **HTTP Request Parsing Bugs** - e.g. by implementing strict and well\n  documented parsing behavior\n- **Error responses** - e.g. by providing infrastructure for uniform error\n  handling (e.g. to prevent accidental leaks or XSS from error responses)\n- **Enforcement of other security specific HTTP headers** -\n  [here](safehttp/plugins/staticheaders)\n\n## Appendix\n\n### Evolving Security Requirements (example)\n\nImagine an API for configuring access control. It features three types of rules:\n\n- `ALLOW(user)` - allows a given `user`\n- `DENY(user)` - denies a given `user` (has priority over `ALLOW`)\n- `REPORT(user)` - reports that it has seen a request from a given `user`\n\nImagine now that at some point, security standards need to be increased and\n`user = \"frombulator\"` has been determined to not meet the desired bar.\n\nHow do we, for all the services running in our company, address this?\n\n1.  For existing services, we add a `LegacyFrombulatorAccess` option like so:\n    `security.AccessControl(rules, unsafe.LegacyFrombulatorAccess())`.\n1.  We change the `security.AccessControl()` call to add by default a\n    `DENY(\"frombulator\")` rule. This rule **is not added** if\n    `unsafe.LegacyFrombulatorAccess` is applied.\n1.  Instead, `unsafe.LegacyFrombulatorAccess` adds a `REPORT(\"frombulator\")`\n    rule.\n\nThis way, we have:\n\n- Ensured that all new callers of `security.AccessControl` use the safe setting\n  by default.\n- Can monitor existing services dependence on calls from the `frombulator`.\n  After a period of observation (let’s say, 30 days):\n  - If the service doesn’t receive requests from the `frombulator`: **prune the\n    `unsafe.LegacyFrombulatorAccess`** option.\n  - If the service does receive requests from the `frombulator`: **inform the\n    service owners and plan a fix.**\n\nCrucially, only the last case (dependence on unsafe configuration) requires\nengineering work per service. The rest can be automated.\n\n**This approach is possible due to careful API design.** A missing `DENY` or\n`REPORT` rule, or a single sink in the form of `security.AccessControl` would\nmake this infeasible.\n\n### Source Code Headers\n\nEvery file containing source code must include copyright and license\ninformation. This includes any JS/CSS files that you might be serving out to\nbrowsers. (This is to help well-intentioned people avoid accidental copying that\ndoesn't comply with the license.)\n\nApache header:\n\n    Copyright 2020 Google LLC\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n        https://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoogle%2Fgo-safeweb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoogle%2Fgo-safeweb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoogle%2Fgo-safeweb/lists"}