Skip to content

fix: Keyword score deduplication and threshold re-check after vhost k…#33

Merged
mclueppers merged 1 commit intomainfrom
fix/update-spam-scoring-logic
Jan 12, 2026
Merged

fix: Keyword score deduplication and threshold re-check after vhost k…#33
mclueppers merged 1 commit intomainfrom
fix/update-spam-scoring-logic

Conversation

@mclueppers
Copy link
Contributor

…eywords

  • Add vhost override keyword detection in defense_mechanisms.lua keyword_filter
  • Skip global keywords when vhost/endpoint has the same keyword (vhost takes precedence)
  • Add threshold re-check in waf_handler.lua after vhost keyword scores are added
  • Fix instance_coordinator timer callback with premature parameter and pcall wrapper

This fixes two issues:

  1. Keywords in both global and vhost configs were summing scores instead of vhost overriding global (e.g., global test:70 + vhost test:20 = 90, now = 20)
  2. Vhost keyword scores pushing total over threshold didn't change action to block

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request attempts to fix keyword score deduplication and threshold checking after vhost keyword evaluation. It addresses two main issues: preventing global and vhost keywords from summing their scores when they should override, and ensuring that vhost keyword scores trigger threshold-based blocking.

Changes:

  • Add vhost keyword override detection to skip global keywords when vhost/endpoint defines the same keyword
  • Add threshold re-check after vhost keyword scores are applied to change action to block if threshold exceeded
  • Fix instance_coordinator timer callback to properly handle premature parameter and add pcall error wrapper

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
openresty/lua/waf_handler.lua Adds threshold re-check logic after vhost keyword scores to trigger blocking when score exceeds threshold
openresty/lua/defense_mechanisms.lua Adds vhost override keyword detection to skip global keywords that should be overridden by vhost configuration
openresty/lua/instance_coordinator.lua Adds premature parameter handling and pcall wrapper to initialization timer callback for better error handling

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

local block_threshold = vhost_resolver.get_block_threshold(context)
if profile_result.score and profile_result.score >= block_threshold then
profile_result.action = "block"
profile_result.blocked_by = profile_result.blocked_by or {}
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The profile_result.flags table might be nil at this point if the condition at line 540 is false (no additional keywords). The flags initialization at line 552 only happens inside that condition block. This line should either check if flags exists first or initialize it, similar to how blocked_by is handled at line 591.

Suggested change
profile_result.blocked_by = profile_result.blocked_by or {}
profile_result.blocked_by = profile_result.blocked_by or {}
profile_result.flags = profile_result.flags or {}

Copilot uses AI. Check for mistakes.
local kw_lower = kw:lower()
if vhost_override_keywords[kw_lower] then
-- Skip: vhost/endpoint has override for this keyword (will use vhost score instead)
table.insert(flags, "kw:" .. kw .. ":vhost_override")
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When flagged keywords are skipped due to vhost overrides, their scores remain included in the total score from keyword_filter.scan() at line 262. This means global keyword scores are still being added even when they should be overridden by vhost keywords. The score variable should be adjusted to subtract the scores of overridden keywords, or the logic should be restructured to compute scores only for non-overridden keywords.

Suggested change
table.insert(flags, "kw:" .. kw .. ":vhost_override")
table.insert(flags, "kw:" .. kw .. ":vhost_override")
-- Adjust score so that overridden global keywords do not contribute
if result.keyword_scores and result.keyword_scores[kw] then
score = score - result.keyword_scores[kw]
end

Copilot uses AI. Check for mistakes.
…eywords

- Add vhost override keyword detection in defense_mechanisms.lua keyword_filter
- Skip global keywords when vhost/endpoint has the same keyword (vhost takes precedence)
- Subtract global keyword scores when overridden (fixes score summing bug)
- Add get_flagged_keyword_scores() to keyword_filter.lua for score lookup
- Add threshold re-check in waf_handler.lua after vhost keyword scores are added
- Fix potential nil flags in threshold re-check (initialize before insert)
- Fix instance_coordinator timer callback with premature parameter and pcall wrapper

This fixes two issues:
1. Keywords in both global and vhost configs were summing scores instead of
   vhost overriding global (e.g., global test:70 + vhost test:20 = 90, now = 20)
2. Vhost keyword scores pushing total over threshold didn't change action to block
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mclueppers mclueppers merged commit bf7aef4 into main Jan 12, 2026
9 checks passed
@mclueppers mclueppers deleted the fix/update-spam-scoring-logic branch January 12, 2026 16:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant