Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ jobs:
name: Release ${{ needs.check-inputs.outputs.version }}
draft: true
prerelease: ${{ inputs.release_reason == 'prerelease' }}
generate_release_notes: true
generate_release_notes: false
body: |
See ${{ needs.check-inputs.outputs.changelog-url }}
files: |
Expand Down
17 changes: 10 additions & 7 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
authentik takes security very seriously. We follow the rules of [responsible disclosure](https://en.wikipedia.org/wiki/Responsible_disclosure), and we urge our community to do so as well, instead of reporting vulnerabilities publicly. This allows us to patch the issue quickly, announce it's existence and release the fixed version.
authentik takes security very seriously. We follow the rules of [responsible disclosure](https://en.wikipedia.org/wiki/Responsible_disclosure), and we urge our community to do so as well, instead of reporting vulnerabilities publicly. This allows us to patch the issue quickly, announce its existence and release the fixed version.

## Independent audits and pentests

We are committed to engaging in regular pentesting and security audits of authentik. Defining and adhering to a cadence of external testing ensures a stronger probability that our code base, our features, and our architecture is as secure and non-exploitable as possible. For more details about specific audits and pentests, refer to "Audits and Certificates" in our [Security documentation](https://docs.goauthentik.io/docs/security).

## What authentik classifies as a CVE

CVE (Common Vulnerability and Exposure) is a system designed to aggregate all vulnerabilities. As such, a CVE will be issued when there is a either vulnerability or exposure. Per NIST, A vulnerability is:
CVE (Common Vulnerability and Exposure) is a system designed to aggregate all vulnerabilities. As such, a CVE will be issued when there is either a vulnerability or exposure. Per NIST, A vulnerability is:

“Weakness in an information system, system security procedures, internal controls, or implementation that could be exploited or triggered by a threat source.”

Expand All @@ -25,10 +25,7 @@ Even if the issue is not a CVE, we still greatly appreciate your help in hardeni

## Reporting a Vulnerability

If you discover a potential vulnerability, please report it responsibly through one of the following channels:

- **Email**: [security@goauthentik.io](mailto:security@goauthentik.io)
- **GitHub**: Submit a private security advisory via our [repository’s advisory portal](https://github.com/goauthentik/authentik/security/advisories/new)
If you discover a potential vulnerability, please report it responsibly by submitting a private security advisory via our [repository’s advisory portal](https://github.com/goauthentik/authentik/security/advisories/new).

When submitting a report, please include as much detail as possible, such as:

Expand Down Expand Up @@ -96,7 +93,7 @@ The destinations of outgoing network requests (HTTP, TCP, etc.) made by authenti

## Disclosure process

1. Report from Github or Issue is reported via Email as listed above.
1. Vulnerability is reported via a GitHub Security Advisory, as listed above.
2. The authentik Security team will try to reproduce the issue and ask for more information if required.
3. A severity level is assigned.
4. A fix is created, and if possible tested by the issue reporter.
Expand All @@ -107,3 +104,9 @@ The destinations of outgoing network requests (HTTP, TCP, etc.) made by authenti
## Getting security notifications

To get security notifications, subscribe to the mailing list [here](https://groups.google.com/g/authentik-security-announcements) or join the [discord](https://goauthentik.io/discord) server.

## Contact

For general inquiries, you can reach the authentik Security team at [security@goauthentik.io](mailto:security@goauthentik.io).

_Please do not use email for vulnerability reports, instead use our [repository’s advisory portal](https://github.com/goauthentik/authentik/security/advisories/new)._
23 changes: 23 additions & 0 deletions internal/web/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,25 @@ const (
maxBodyBytes = 32 * 1024 * 1024
)

var djangoHTTPMethods = map[string]struct{}{
http.MethodGet: {},
http.MethodHead: {},
http.MethodPost: {},
http.MethodPut: {},
http.MethodPatch: {},
http.MethodDelete: {},
http.MethodOptions: {},
http.MethodTrace: {},
}

func handleUnsupportedHTTPMethod(rw http.ResponseWriter, r *http.Request) bool {
if _, ok := djangoHTTPMethods[r.Method]; ok {
return false
}
http.Error(rw, "Unsupported HTTP method.", http.StatusNotImplemented)
return true
}

func (ws *WebServer) configureProxy() {
// Reverse proxy to the application server
director := func(req *http.Request) {
Expand Down Expand Up @@ -91,6 +110,10 @@ func (ws *WebServer) configureProxy() {
return
}

if handleUnsupportedHTTPMethod(rw, r) {
return
}

r.Body = http.MaxBytesReader(rw, r.Body, maxBodyBytes)
rp.ServeHTTP(rw, r)

Expand Down
45 changes: 43 additions & 2 deletions src/server/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ use axum::{
body::Body,
extract::{OriginalUri, Request, State},
http::{
HeaderName, HeaderValue, StatusCode, Uri,
HeaderName, HeaderValue, Method, StatusCode, Uri,
header::{ACCEPT, CONTENT_TYPE, HOST, LOCATION, RETRY_AFTER},
},
response::Response,
response::{IntoResponse as _, Response},
routing::any,
};
use http_body_util::BodyExt as _;
Expand Down Expand Up @@ -61,6 +61,13 @@ const X_FORWARDED_CLIENT_CERT: HeaderName = HeaderName::from_static("x-forwarded
const X_FORWARDED_FOR: HeaderName = HeaderName::from_static("x-forwarded-for");
const X_FORWARDED_PROTO: HeaderName = HeaderName::from_static("x-forwarded-proto");

fn is_django_http_method(method: &Method) -> bool {
matches!(
method.as_str(),
"GET" | "HEAD" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS" | "TRACE"
)
}

const FORWARD_ALWAYS_REMOVED_HEADERS: [HeaderName; 7] = [
HeaderName::from_static("forwarded"),
HeaderName::from_static("host"),
Expand Down Expand Up @@ -112,6 +119,9 @@ async fn forward_request(
if !GUNICORN_READY.load(Ordering::Relaxed) {
return Ok(startup_response(&accept_header));
}
if !is_django_http_method(request.method()) {
return Ok((StatusCode::NOT_IMPLEMENTED, "Unsupported HTTP method.\n").into_response());
}

let uri = Uri::builder()
.scheme("http")
Expand Down Expand Up @@ -309,6 +319,37 @@ pub(super) fn build_router(server: &Arc<Server>) -> eyre::Result<Router> {
Ok(router)
}

#[cfg(test)]
mod tests {
use axum::http::Method;

use super::is_django_http_method;

#[test]
fn django_http_methods_are_allowed() {
for method in [
Method::GET,
Method::HEAD,
Method::POST,
Method::PUT,
Method::PATCH,
Method::DELETE,
Method::OPTIONS,
Method::TRACE,
] {
assert!(is_django_http_method(&method));
}
}

#[test]
fn unsupported_http_methods_are_rejected() {
assert!(!is_django_http_method(&Method::CONNECT));
assert!(!is_django_http_method(
&Method::from_bytes(b"PROPFIND").expect("method")
));
}
}

mod websockets {
use std::sync::Arc;

Expand Down
57 changes: 0 additions & 57 deletions web/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions web/src/user/ak-interface-user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,9 @@ class UserInterface extends WithLicenseSummary(
navItems.push({ label: msg("Discover"), link: "/requests" });
}
if (
this.can(CapabilitiesEnum.CanAgentSelfService) &&
this.uiConfig.enabledFeatures.agents
this.licenseSummary?.status !== LicenseSummaryStatusEnum.Unlicensed &&
this.uiConfig.enabledFeatures.agents &&
this.can(CapabilitiesEnum.CanAgentSelfService)
) {
navItems.push({ label: msg("Agents"), link: "/agents" });
}
Expand Down
Loading