Firewall

3 min read Original article ↗

Buttondown's "Firewall" (a slightly aggressive term, but illustrative enough) is an opt-in feature that audits all incoming subscribers to confirm that they're legitimate people.

It's not obvious why a malicious actor would want to subscribe to your newsletter. What is there to gain?

Large email providers like Gmail largely judge your newsletter based on the reputation of your email, sending domain, and sending IP. That reputation itself is based off of engagement: an email going to one thousand subscribers, nine hundred of whom engage with it, will have a stronger reputation than an email going to one thousand subscribers, one hundred of whom engage with it.

Now imagine that you foist an additional thousand subscribers onto that newsletter. Most of them won't engage with it; many will unsubscribe or even mark it as spam. This will tank your reputation, making it more difficult to send emails to your actual subscribers.

---
config:
  layout: elk
  elk:
    mergeEdges: true
    nodePlacementStrategy: LINEAR_SEGMENTS
---

flowchart-elk
  request([Incoming request]) -->|"POST ip_address=X,email_address=Y"| payload
  score --> you[Your newsletter]
  you -->|"risk_score < THRESHOLD"| newsletter[Regular subscriber]
  you -->|"risk_score >= THRESHOLD && PERSIST_BLOCKED = true"| blocked[Blocked subscriber]
  you -->|"risk_score >= THRESHOLD"| subscriber_blocked>firewall.blocked]
  newsletter --> subscriber_created>subscriber.created]
  blocked --> subscriber_created

  subgraph sync[Synchronous firewall]
    payload[Payload] --> ip[IP address]
    payload --> email[Email address]
    payload --> newsletter_history[Secret sauce]
    ip[IP address] --> score[Reputation]
    email[Email address] --> score[Reputation]
    newsletter_history --> score[Reputation]
  end

  click subscriber_blocked href "event-types#firewall.blocked"
  click subscriber_created href "event-types#subscriber.created"

The firewall is conceptually simple: whenever we receive an incoming request across a common vector (such as an embedded subscription form, a POST to /v1/subscribers, or a comment on a newsletter), we check the reputation of the IP address and email address of the incoming request as well as some additional metadata. We tally up the various facets and arrive at a risk_score. If the risk_score is below a threshold, we let the subscriber through. If it's above the threshold, we block the subscriber.

As a newsletter owner, you are given two knobs to tune the firewall and how it interacts with your newsletter:

  • The threshold: This is the point at which we block a subscriber.
  • By default, we do not surface blocked subscribers to your newsletter. If you prefer, you can opt to surface them in the subscriber dashboard with a special type of "Blocked".

Buttondown's firewall ultimately buckets the spectrum of all risk scores into four buckets:

RangeLabelDescription
< -0.5Very safeSubscriber is highly likely to be legitimate.
-0.5 — 0.5SafeSubscriber appears normal, with no suspicious signals.
0.5 — 1RiskySome suspicious signals detected; may be a bot or spam.
≥ 1Very riskyStrong indicators of spam or malicious activity.

Setting a firewall mode of "aggressive" will proactively block risky and very risky subscribers; a firewall mode of "enabled" only blocks very risky subscribers.

You can test how your firewall configuration responds to different risk scores using sandbox test addresses. These special email addresses allow you to simulate specific risk scores to verify your firewall threshold settings.

How sandbox addresses work

Sandbox addresses use the domain sandbox.buttondown.com with a special format in the local part: +firewall-{number}. The number you specify will be added directly to the firewall risk score for that email address. Sandbox addresses are only available for testing purposes and will not receive actual emails.

Format: {anything}+firewall-{score}@sandbox.buttondown.com

Examples:

  • test+firewall-2@sandbox.buttondown.com - Adds 2.0 to the risk score (will be blocked if your threshold is 2.0 or lower)
  • user+firewall-0.5@sandbox.buttondown.com - Adds 0.5 to the risk score (will be blocked if your threshold is 0.5 or lower)
  • anything+firewall-10@sandbox.buttondown.com - Adds 10.0 to the risk score (will be blocked regardless of threshold)