diff --git a/openflare_agent/internal/nginx/manager_test.go b/openflare_agent/internal/nginx/manager_test.go
index 5562f9f3..3a5bf367 100644
--- a/openflare_agent/internal/nginx/manager_test.go
+++ b/openflare_agent/internal/nginx/manager_test.go
@@ -1003,6 +1003,18 @@ func TestManagedPowLuaFilesUseInternalChallengeFlow(t *testing.T) {
if !strings.Contains(openRestyPowChallengeLua, ``) {
t.Fatal("expected challenge html to force Anubis frontend to reuse the current URL as redir target")
}
+ if !strings.Contains(openRestyPowCheckLua, `pow_sessions:set(session_key, "1", session_ttl)`) {
+ t.Fatal("expected check.lua to refresh the PoW session TTL on each valid request")
+ }
+ if !strings.Contains(openRestyPowCheckLua, `ngx.header["Set-Cookie"] = session_cookie(cookie_val, session_ttl)`) {
+ t.Fatal("expected check.lua to refresh the browser session cookie on each valid request")
+ }
+ if !strings.Contains(openRestyPowChallengeLua, `local session_ttl = config.session_ttl or 600`) {
+ t.Fatal("expected challenge.lua to default session TTL to 10 minutes")
+ }
+ if !strings.Contains(openRestyPowVerifyLua, `local session_ttl = challenge_info.session_ttl or 600`) {
+ t.Fatal("expected verify.lua to default session TTL to 10 minutes")
+ }
if !strings.Contains(openRestyPowVerifyLua, `if ngx.var.scheme == "https" then`) {
t.Fatal("expected verify.lua to only mark the session cookie as Secure for HTTPS requests")
}
diff --git a/openflare_agent/internal/nginx/pow_assets.go b/openflare_agent/internal/nginx/pow_assets.go
index df1d497d..b41d16aa 100644
--- a/openflare_agent/internal/nginx/pow_assets.go
+++ b/openflare_agent/internal/nginx/pow_assets.go
@@ -25,6 +25,14 @@ local policy = require "pow.policy"
local pow_config_dict = ngx.shared.openflare_pow_config
local pow_sessions = ngx.shared.openflare_pow_sessions
+local function session_cookie(value, ttl)
+ local cookie = "__openflare_pow=" .. value .. "; Path=/; HttpOnly; SameSite=Lax; Max-Age=" .. tostring(ttl)
+ if ngx.var.scheme == "https" then
+ cookie = cookie .. "; Secure"
+ end
+ return cookie
+end
+
-- Lazy-load pow_config from file; reload when content changes
local function load_pow_config()
local config_paths = {
@@ -95,6 +103,7 @@ if not route_config.enabled then
end
local config = route_config.config or {}
+local session_ttl = config.session_ttl or 600
local uri = ngx.var.uri or ""
local ua = ngx.var.http_user_agent or ""
local remote_ip = ngx.var.remote_addr or ""
@@ -123,8 +132,11 @@ end
-- Check valid session cookie
local cookie_val = ngx.var["cookie___openflare_pow"]
if cookie_val and cookie_val ~= "" then
- local session_data = pow_sessions:get(host .. ":" .. cookie_val)
+ local session_key = host .. ":" .. cookie_val
+ local session_data = pow_sessions:get(session_key)
if session_data then
+ pow_sessions:set(session_key, "1", session_ttl)
+ ngx.header["Set-Cookie"] = session_cookie(cookie_val, session_ttl)
return
end
end
@@ -187,7 +199,7 @@ local config = route_config.config or {}
local difficulty = config.difficulty or 4
local algorithm = config.algorithm or "fast"
local challenge_ttl = config.challenge_ttl or 300
-local session_ttl = config.session_ttl or 86400
+local session_ttl = config.session_ttl or 600
-- Generate challenge data without depending on ngx.random_bytes, which is not
-- available in every OpenResty runtime build.
@@ -307,7 +319,7 @@ end
local challenge_data = challenge_info.data or ""
local difficulty = challenge_info.difficulty or 4
local host = challenge_info.host or ngx.var.host or ""
-local session_ttl = challenge_info.session_ttl or 86400
+local session_ttl = challenge_info.session_ttl or 600
-- Compute SHA-256(challenge_data + nonce)
local calc_string = challenge_data .. tostring(math.floor(nonce))
diff --git a/openflare_server/service/agent_test.go b/openflare_server/service/agent_test.go
index f1796eaf..f021673b 100644
--- a/openflare_server/service/agent_test.go
+++ b/openflare_server/service/agent_test.go
@@ -1,6 +1,9 @@
package service
-import "testing"
+import (
+ "strings"
+ "testing"
+)
func TestGetActiveConfigForAgentIncludesPoWConfig(t *testing.T) {
setupServiceTestDB(t)
@@ -39,3 +42,37 @@ func TestGetActiveConfigForAgentIncludesPoWConfig(t *testing.T) {
t.Fatal("expected agent config to include pow_config.json support file")
}
}
+
+func TestGetActiveConfigForAgentUsesTenMinutePoWSessionDefault(t *testing.T) {
+ setupServiceTestDB(t)
+
+ _, err := CreateProxyRoute(ProxyRouteInput{
+ Domain: "pow-default.example.com",
+ OriginURL: "https://origin.internal",
+ Enabled: true,
+ PoWEnabled: true,
+ PoWConfig: `{}`,
+ })
+ if err != nil {
+ t.Fatalf("CreateProxyRoute failed: %v", err)
+ }
+
+ if _, err := PublishConfigVersion("root"); err != nil {
+ t.Fatalf("PublishConfigVersion failed: %v", err)
+ }
+
+ activeConfig, err := GetActiveConfigForAgent()
+ if err != nil {
+ t.Fatalf("GetActiveConfigForAgent failed: %v", err)
+ }
+
+ for _, file := range activeConfig.SupportFiles {
+ if file.Path == "pow_config.json" {
+ if !strings.Contains(file.Content, `"session_ttl":600`) {
+ t.Fatalf("expected default PoW session TTL to be 600 seconds, got %s", file.Content)
+ }
+ return
+ }
+ }
+ t.Fatal("expected agent config to include pow_config.json support file")
+}
diff --git a/openflare_server/service/proxy_route.go b/openflare_server/service/proxy_route.go
index 6ea9f704..3ff9ad32 100644
--- a/openflare_server/service/proxy_route.go
+++ b/openflare_server/service/proxy_route.go
@@ -1097,7 +1097,7 @@ func defaultPoWConfig() ProxyRoutePoWConfig {
return ProxyRoutePoWConfig{
Difficulty: 4,
Algorithm: "fast",
- SessionTTL: 86400,
+ SessionTTL: 600,
ChallengeTTL: 300,
Whitelist: ProxyRoutePoWListConfig{IPs: []string{}, IPCidrs: []string{}, Paths: []string{}, PathRegexes: []string{}, UserAgents: []string{}},
Blacklist: ProxyRoutePoWListConfig{IPs: []string{}, IPCidrs: []string{}, Paths: []string{}, PathRegexes: []string{}, UserAgents: []string{}},
diff --git a/openflare_server/web/features/proxy-routes/components/proxy-route-config-page.tsx b/openflare_server/web/features/proxy-routes/components/proxy-route-config-page.tsx
index eb3ededd..5314cc57 100644
--- a/openflare_server/web/features/proxy-routes/components/proxy-route-config-page.tsx
+++ b/openflare_server/web/features/proxy-routes/components/proxy-route-config-page.tsx
@@ -806,7 +806,7 @@ function PowSection({
pow_enabled: route.pow_enabled,
difficulty: powConfig?.difficulty ?? 4,
algorithm: powConfig?.algorithm ?? 'fast',
- session_ttl: powConfig?.session_ttl ?? 86400,
+ session_ttl: powConfig?.session_ttl ?? 600,
challenge_ttl: powConfig?.challenge_ttl ?? 300,
whitelist: buildPowListFromConfig(powConfig?.whitelist),
blacklist: buildPowListFromConfig(powConfig?.blacklist),
@@ -818,7 +818,7 @@ function PowSection({
pow_enabled: route.pow_enabled,
difficulty: powConfig?.difficulty ?? 4,
algorithm: powConfig?.algorithm ?? 'fast',
- session_ttl: powConfig?.session_ttl ?? 86400,
+ session_ttl: powConfig?.session_ttl ?? 600,
challenge_ttl: powConfig?.challenge_ttl ?? 300,
whitelist: buildPowListFromConfig(powConfig?.whitelist),
blacklist: buildPowListFromConfig(powConfig?.blacklist),
@@ -904,8 +904,8 @@ function PowSection({