diff --git a/docs/docs/CHANGELOG.md b/docs/docs/CHANGELOG.md
index e503a78..8b2c9aa 100644
--- a/docs/docs/CHANGELOG.md
+++ b/docs/docs/CHANGELOG.md
@@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add the `DIFFICULTY_IN_JWT` option, which allows one to add the `difficulty` field in the JWT claims which indicates the difficulty of the token ([#1063](https://github.com/TecharoHQ/anubis/pull/1063)).
- Ported the client-side JS to TypeScript to avoid egregious errors in the future.
- Fixes concurrency problems with very old browsers ([#1082](https://github.com/TecharoHQ/anubis/issues/1082)).
+- Randomly use the Refresh header instead of the meta refresh tag in the metarefresh challenge.
- Update OpenRC service to truncate the runtime directory before starting Anubis.
### Bug Fixes
diff --git a/lib/challenge/interface.go b/lib/challenge/interface.go
index 963d6ca..c7a1944 100644
--- a/lib/challenge/interface.go
+++ b/lib/challenge/interface.go
@@ -61,7 +61,7 @@ type Impl interface {
Setup(mux *http.ServeMux)
// Issue a new challenge to the user, called by the Anubis.
- Issue(r *http.Request, lg *slog.Logger, in *IssueInput) (templ.Component, error)
+ Issue(w http.ResponseWriter, r *http.Request, lg *slog.Logger, in *IssueInput) (templ.Component, error)
// Validate a challenge, making sure that it passes muster.
Validate(r *http.Request, lg *slog.Logger, in *ValidateInput) error
diff --git a/lib/challenge/metarefresh/metarefresh.go b/lib/challenge/metarefresh/metarefresh.go
index 75ac70f..c554b91 100644
--- a/lib/challenge/metarefresh/metarefresh.go
+++ b/lib/challenge/metarefresh/metarefresh.go
@@ -23,7 +23,7 @@ type Impl struct{}
func (i *Impl) Setup(mux *http.ServeMux) {}
-func (i *Impl) Issue(r *http.Request, lg *slog.Logger, in *challenge.IssueInput) (templ.Component, error) {
+func (i *Impl) Issue(w http.ResponseWriter, r *http.Request, lg *slog.Logger, in *challenge.IssueInput) (templ.Component, error) {
u, err := r.URL.Parse(anubis.BasePrefix + "/.within.website/x/cmd/anubis/api/pass-challenge")
if err != nil {
return nil, fmt.Errorf("can't render page: %w", err)
@@ -35,9 +35,15 @@ func (i *Impl) Issue(r *http.Request, lg *slog.Logger, in *challenge.IssueInput)
q.Set("id", in.Challenge.ID)
u.RawQuery = q.Encode()
+ showMeta := in.Challenge.RandomData[0]%2 == 0
+
+ if !showMeta {
+ w.Header().Add("Refresh", fmt.Sprintf("%d; url=%s", in.Rule.Challenge.Difficulty+1, u.String()))
+ }
+
loc := localization.GetLocalizer(r)
- result := page(u.String(), in.Rule.Challenge.Difficulty, loc)
+ result := page(u.String(), in.Rule.Challenge.Difficulty, showMeta, loc)
return result, nil
}
diff --git a/lib/challenge/metarefresh/metarefresh.templ b/lib/challenge/metarefresh/metarefresh.templ
index dccf765..c074f59 100644
--- a/lib/challenge/metarefresh/metarefresh.templ
+++ b/lib/challenge/metarefresh/metarefresh.templ
@@ -7,12 +7,14 @@ import (
"github.com/TecharoHQ/anubis/lib/localization"
)
-templ page(redir string, difficulty int, loc *localization.SimpleLocalizer) {
+templ page(redir string, difficulty int, showMeta bool, loc *localization.SimpleLocalizer) {
{ loc.T("loading") }
{ loc.T("connection_security") }
-
+ if showMeta {
+
+ }
}
diff --git a/lib/challenge/metarefresh/metarefresh_templ.go b/lib/challenge/metarefresh/metarefresh_templ.go
index 048260b..f54c45a 100644
--- a/lib/challenge/metarefresh/metarefresh_templ.go
+++ b/lib/challenge/metarefresh/metarefresh_templ.go
@@ -15,7 +15,7 @@ import (
"github.com/TecharoHQ/anubis/lib/localization"
)
-func page(redir string, difficulty int, loc *localization.SimpleLocalizer) templ.Component {
+func page(redir string, difficulty int, showMeta bool, loc *localization.SimpleLocalizer) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
@@ -88,20 +88,30 @@ func page(redir string, difficulty int, loc *localization.SimpleLocalizer) templ
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var6 string
- templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d; url=%s", difficulty+1, redir))
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `metarefresh.templ`, Line: 16, Col: 85}
+ if showMeta {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\">")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
diff --git a/lib/challenge/preact/preact.go b/lib/challenge/preact/preact.go
index 0276d7d..a785f98 100644
--- a/lib/challenge/preact/preact.go
+++ b/lib/challenge/preact/preact.go
@@ -38,7 +38,7 @@ type impl struct{}
func (i *impl) Setup(mux *http.ServeMux) {}
-func (i *impl) Issue(r *http.Request, lg *slog.Logger, in *challenge.IssueInput) (templ.Component, error) {
+func (i *impl) Issue(w http.ResponseWriter, r *http.Request, lg *slog.Logger, in *challenge.IssueInput) (templ.Component, error) {
u, err := r.URL.Parse(anubis.BasePrefix + "/.within.website/x/cmd/anubis/api/pass-challenge")
if err != nil {
return nil, fmt.Errorf("can't render page: %w", err)
diff --git a/lib/challenge/proofofwork/proofofwork.go b/lib/challenge/proofofwork/proofofwork.go
index 8cd3127..b9be014 100644
--- a/lib/challenge/proofofwork/proofofwork.go
+++ b/lib/challenge/proofofwork/proofofwork.go
@@ -27,7 +27,7 @@ type Impl struct {
func (i *Impl) Setup(mux *http.ServeMux) {}
-func (i *Impl) Issue(r *http.Request, lg *slog.Logger, in *chall.IssueInput) (templ.Component, error) {
+func (i *Impl) Issue(w http.ResponseWriter, r *http.Request, lg *slog.Logger, in *chall.IssueInput) (templ.Component, error) {
loc := localization.GetLocalizer(r)
return page(loc), nil
}
diff --git a/lib/challenge/proofofwork/proofofwork_test.go b/lib/challenge/proofofwork/proofofwork_test.go
index 4e71bcf..c0611a5 100644
--- a/lib/challenge/proofofwork/proofofwork_test.go
+++ b/lib/challenge/proofofwork/proofofwork_test.go
@@ -4,6 +4,7 @@ import (
"errors"
"log/slog"
"net/http"
+ "net/http/httptest"
"testing"
"github.com/TecharoHQ/anubis/lib/challenge"
@@ -133,7 +134,7 @@ func TestBasic(t *testing.T) {
},
}
- if _, err := i.Issue(cs.req, lg, inp); err != nil {
+ if _, err := i.Issue(httptest.NewRecorder(), cs.req, lg, inp); err != nil {
t.Errorf("can't issue challenge: %v", err)
}
diff --git a/lib/http.go b/lib/http.go
index 7209d58..1332035 100644
--- a/lib/http.go
+++ b/lib/http.go
@@ -29,19 +29,19 @@ var domainMatchRegexp = regexp.MustCompile(`^((xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[
// internal glob matcher. Matching is case-insensitive on hostnames.
func matchRedirectDomain(allowed []string, host string) bool {
h := strings.ToLower(strings.TrimSpace(host))
- for _, pat := range allowed {
- p := strings.ToLower(strings.TrimSpace(pat))
- if strings.Contains(p, glob.GLOB) {
- if glob.Glob(p, h) {
- return true
- }
- continue
- }
- if p == h {
- return true
- }
- }
- return false
+ for _, pat := range allowed {
+ p := strings.ToLower(strings.TrimSpace(pat))
+ if strings.Contains(p, glob.GLOB) {
+ if glob.Glob(p, h) {
+ return true
+ }
+ continue
+ }
+ if p == h {
+ return true
+ }
+ }
+ return false
}
type CookieOpts struct {
@@ -214,7 +214,7 @@ func (s *Server) RenderIndex(w http.ResponseWriter, r *http.Request, cr policy.C
Store: s.store,
}
- component, err := impl.Issue(r, lg, in)
+ component, err := impl.Issue(w, r, lg, in)
if err != nil {
lg.Error("[unexpected] challenge component render failed, please open an issue", "err", err) // This is likely a bug in the template. Should never be triggered as CI tests for this.
s.respondWithError(w, r, fmt.Sprintf("%s \"RenderIndex\"", localizer.T("internal_server_error")))