Skip to content

Conversation

skizzerz
Copy link
Contributor

@skizzerz skizzerz commented Jul 16, 2025

This adds a new flag that causes other actions attached to that filter to apply even if the target user or channel is +u. In other words, it is not possible to "opt out" of filters using the bypass flag. Opers remain immune, both as senders and recipients, so that spamfilter cannot be abused to lock people out of managing filters, talking to services, etc.

By default, this flag only works if combined with the "drop" action however a new ircd.conf setting can be used to allow it to apply to "kill" and "alarm" as well. Another new ircd.conf setting can expose the nick!user@host of the sender to the filtering engine (previously this depended on changing compile-time macros). If either of these settings are enabled, a new user-visible "F" flag will appear in VERSION output to indicate that the spamfilter engine has these capabilities.

This new action works the same as drop, however it applies even if the
target user or channel is +u. In other words, it is not possible to "opt
out" of the superdrop action. Opers remain immune, both as senders and
recipients, so that spamfilter cannot be abused to lock people out of
managing filters, talking to services, etc.
aaronmdjones
aaronmdjones previously approved these changes Jul 26, 2025
@jillest
Copy link
Contributor

jillest commented Jul 27, 2025

So the idea here is that some regexes will be drop and some will be superdrop? Otherwise, it would be simpler to remove the ability to set +u instead.

@skizzerz
Copy link
Contributor Author

So the idea here is that some regexes will be drop and some will be superdrop? Otherwise, it would be simpler to remove the ability to set +u instead.

Yes, superdrop is for some patterns that should always trigger the filter, even if the target is set +u. One use case would be RCEs exploitable over IRC.

Target is -u Target is +u
drop Message dropped, sender given ERR_CANNOTSENDTOCHAN Nothing happens
kill Message dropped, sender disconnected with quit reason FILTER_EXIT_MSG Nothing happens
alarm Filter snote shown to opers Nothing happens
superdrop Message dropped, sender given ERR_CANNOTSENDTOCHAN Message dropped, sender given ERR_CANNOTSENDTOCHAN

This keeps the functionality of +u to opt out of filtering, including filtering for the kill/alarm actions, while giving opers a lever they can use for things that would be potentially too dangerous to opt out of.

(sidenote: while making the above table I noticed that the default ACT_KILL for messages is to drop the message, but ACT_KILL is no-op for quit message filtering. It should maybe set the quit reason to NULL as well if it matches a filter to keep the same semantics as regular message filtering)

@aaronmdjones
Copy link
Member

aaronmdjones commented Jul 27, 2025

@skizzerz The code changes in this pull request do not match the table you just provided for the ALARM case.

If it should be as you described you are missing 2 instances of

-if (r & ACT_ALARM) {
+if (r & ACT_ALARM && mask != ACT_SUPERDROP) {

EDIT: Nevermind. Masking it off ensures this can't happen. Ignore me.

Copy link
Member

@dwfreed dwfreed left a comment

Choose a reason for hiding this comment

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

As actions are not mutually exclusive, I would rather this operated as a flag that meant "Ignore +u when applying actions" so that alerts and kills also still happened if appropriate for the given pattern.

@dwfreed
Copy link
Member

dwfreed commented Jul 28, 2025

(sidenote: while making the above table I noticed that the default ACT_KILL for messages is to drop the message, but ACT_KILL is no-op for quit message filtering. It should maybe set the quit reason to NULL as well if it matches a filter to keep the same semantics as regular message filtering)

Kill sets approved = 1 for messages because its exit_client call sends the quit to everyone else immediately, so otherwise the message would appear to come from a client that doesn't exist anymore. It's a safety net in case the database creator forgot to include the drop action. Since actions aren't mutually exclusive, as mentioned, the pattern should use both the drop and kill actions if it's intended to kill the user and apply to both regular messages and quit messages.

@skizzerz
Copy link
Contributor Author

@dwfreed That doesn't really match the desired goal here, which is that +u can only be overridden via the drop action, and kill/alarm will always respect +u preference. Drop has no oper-visible tells, unlike kill/alarm, and as such cannot be abused as a dysfunctional spying platform. While I wasn't around at the time it was introduced, I heard that concerns about potential oper abuse of the filters is (partly) why +u exists in the first place, and letting opers render the mode obsolete would remove that privacy protection.

@bakerst-221b
Copy link
Contributor

bakerst-221b commented Jul 30, 2025

In my opinion there should be a firm restriction in the IRCD that prevents the "alarm" action (and to a lesser degree also the "kill" action) from applying to +u targets.

The reason why I think this is a requirement is to show good faith by not implementing abuse-prone features. The IRCD is open source, while the tools used for creating and uploading databases aren't. Having the restriction in the IRCD allows networks to point at the source code and say: "We specifically designed this feature so that the IRCD doesn't allow opers to bypass +u and spy on your private messages using this feature."

The superdrop action / this PR achieves that. (edited for clearer wording)

I suppose we could also use a flag to implement this but rather than saying "Ignore +u when applying actions", that flag would need to say "Ignore +u when applying the drop action".

The flag is now named ACT_BYPASS, and serves as a generic flag to bypass
+u if set, depending on configuration. Three new configuration items
were added to the general section of ircd.conf to control filter
behaviour:

- filter_sees_user_info: This replaces the old #defines for FILTER_NICK,
  FILTER_IDENT, and FILTER_HOST to determine whether the hostmask of the
  user is passed to the spamfilter or whether we pass a dummy *!*@*.
- filter_bypass_all: If set, the new ACT_BYPASS can allow every filter
  action (DROP, KILL, ALARM) to bypass +u if set in conjunction with
  those flags. If unset, only the DROP action can bypass +u.
- filter_exit_message: This is the quit reason displayed, to move it out
  of a #define (we still keep a define around for a default reason in
  case it is unspecified).

If either filter_sees_user_info or filter_bypass_all are set, the
VERSION command will display a new 'F' flag to indicate the ability for
filter to spy on users.
@skizzerz skizzerz requested a review from dwfreed September 5, 2025 16:29
@skizzerz skizzerz changed the title Add "superdrop" capability to spamfilter Add bypass capability to spamfilter Sep 5, 2025
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.

5 participants