mirror of
https://github.com/TecharoHQ/anubis.git
synced 2026-04-09 10:08:45 +00:00
Compare commits
2 Commits
Xe/docs-im
...
Xe/double-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6f02ac5f9 | ||
|
|
2ea8296682 |
@@ -99,6 +99,7 @@ There are a bunch of other assorted features and fixes too:
|
|||||||
- Allow [Common Crawl](https://commoncrawl.org/) by default so scrapers have less incentive to scrape
|
- Allow [Common Crawl](https://commoncrawl.org/) by default so scrapers have less incentive to scrape
|
||||||
- The [bbolt storage backend](./admin/policies.mdx#bbolt) now runs its cleanup every hour instead of every five minutes.
|
- The [bbolt storage backend](./admin/policies.mdx#bbolt) now runs its cleanup every hour instead of every five minutes.
|
||||||
- Don't block Anubis starting up if [Thoth](./admin/thoth.mdx) health checks fail.
|
- Don't block Anubis starting up if [Thoth](./admin/thoth.mdx) health checks fail.
|
||||||
|
- Multiple consecutive slashes are supported in upstream application URLs ([#754](https://github.com/TecharoHQ/anubis/issues/754)).
|
||||||
|
|
||||||
### Potentially breaking changes
|
### Potentially breaking changes
|
||||||
|
|
||||||
|
|||||||
@@ -67,14 +67,15 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
next http.Handler
|
next http.Handler
|
||||||
mux *http.ServeMux
|
mux *http.ServeMux
|
||||||
policy *policy.ParsedConfig
|
policy *policy.ParsedConfig
|
||||||
OGTags *ogtags.OGTagCache
|
OGTags *ogtags.OGTagCache
|
||||||
ed25519Priv ed25519.PrivateKey
|
ed25519Priv ed25519.PrivateKey
|
||||||
hs512Secret []byte
|
hs512Secret []byte
|
||||||
opts Options
|
opts Options
|
||||||
store store.Interface
|
store store.Interface
|
||||||
|
internalPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) getTokenKeyfunc() jwt.Keyfunc {
|
func (s *Server) getTokenKeyfunc() jwt.Keyfunc {
|
||||||
|
|||||||
@@ -204,6 +204,63 @@ func TestCVE2025_24369(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDoubleSlashes(t *testing.T) {
|
||||||
|
pol := loadPolicies(t, "", 0)
|
||||||
|
|
||||||
|
path := ""
|
||||||
|
|
||||||
|
srv := spawnAnubis(t, Options{
|
||||||
|
Next: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
path = r.URL.Path
|
||||||
|
}),
|
||||||
|
Policy: pol,
|
||||||
|
})
|
||||||
|
|
||||||
|
ts := httptest.NewServer(internal.RemoteXRealIP(true, "tcp", srv))
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
cli := httpClient(t)
|
||||||
|
chall := makeChallenge(t, ts, cli)
|
||||||
|
resp := handleChallengeZeroDifficulty(t, ts, cli, chall)
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusFound {
|
||||||
|
t.Fatal("can't solve challenge, see logs")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range []struct {
|
||||||
|
name, path string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "basic",
|
||||||
|
path: "/foo",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "leading slashes",
|
||||||
|
path: "//foo",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "mid slashes",
|
||||||
|
path: "/foo//bar///baz",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "trailing slashes",
|
||||||
|
path: "/foo/bar///",
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if _, err := cli.Get(ts.URL + tt.path); err != nil {
|
||||||
|
t.Errorf("can't make request to %s: %v", tt.path, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if path != tt.path {
|
||||||
|
t.Logf("want: %s", tt.path)
|
||||||
|
t.Logf("got: %s", path)
|
||||||
|
t.Error("invalid path sent to server")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCookieCustomExpiration(t *testing.T) {
|
func TestCookieCustomExpiration(t *testing.T) {
|
||||||
pol := loadPolicies(t, "", 0)
|
pol := loadPolicies(t, "", 0)
|
||||||
ckieExpiration := 10 * time.Minute
|
ckieExpiration := 10 * time.Minute
|
||||||
|
|||||||
@@ -101,13 +101,14 @@ func New(opts Options) (*Server, error) {
|
|||||||
anubis.BasePrefix = opts.BasePrefix
|
anubis.BasePrefix = opts.BasePrefix
|
||||||
|
|
||||||
result := &Server{
|
result := &Server{
|
||||||
next: opts.Next,
|
next: opts.Next,
|
||||||
ed25519Priv: opts.ED25519PrivateKey,
|
ed25519Priv: opts.ED25519PrivateKey,
|
||||||
hs512Secret: opts.HS512Secret,
|
hs512Secret: opts.HS512Secret,
|
||||||
policy: opts.Policy,
|
policy: opts.Policy,
|
||||||
opts: opts,
|
opts: opts,
|
||||||
OGTags: ogtags.NewOGTagCache(opts.Target, opts.Policy.OpenGraph, opts.Policy.Store),
|
OGTags: ogtags.NewOGTagCache(opts.Target, opts.Policy.OpenGraph, opts.Policy.Store),
|
||||||
store: opts.Policy.Store,
|
store: opts.Policy.Store,
|
||||||
|
internalPath: opts.BasePrefix + anubis.StaticPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
@@ -154,7 +155,6 @@ func New(opts Options) (*Server, error) {
|
|||||||
|
|
||||||
registerWithPrefix(anubis.APIPrefix+"pass-challenge", http.HandlerFunc(result.PassChallenge), "GET")
|
registerWithPrefix(anubis.APIPrefix+"pass-challenge", http.HandlerFunc(result.PassChallenge), "GET")
|
||||||
registerWithPrefix(anubis.APIPrefix+"check", http.HandlerFunc(result.maybeReverseProxyHttpStatusOnly), "")
|
registerWithPrefix(anubis.APIPrefix+"check", http.HandlerFunc(result.maybeReverseProxyHttpStatusOnly), "")
|
||||||
registerWithPrefix("/", http.HandlerFunc(result.maybeReverseProxyOrPage), "")
|
|
||||||
|
|
||||||
//goland:noinspection GoBoolExpressions
|
//goland:noinspection GoBoolExpressions
|
||||||
if anubis.Version == "devel" {
|
if anubis.Version == "devel" {
|
||||||
|
|||||||
@@ -200,7 +200,12 @@ func (s *Server) respondWithStatus(w http.ResponseWriter, r *http.Request, msg s
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
s.mux.ServeHTTP(w, r)
|
switch strings.HasPrefix(r.URL.Path, s.internalPath) {
|
||||||
|
case true:
|
||||||
|
s.mux.ServeHTTP(w, r)
|
||||||
|
case false:
|
||||||
|
s.maybeReverseProxyOrPage(w, r)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) stripBasePrefixFromRequest(r *http.Request) *http.Request {
|
func (s *Server) stripBasePrefixFromRequest(r *http.Request) *http.Request {
|
||||||
|
|||||||
Reference in New Issue
Block a user