Skip to content

fix: add stricter rules for the admin email field#441

Open
khendrikse wants to merge 2 commits into
masterfrom
SEC-860/stricter-from-email-rules
Open

fix: add stricter rules for the admin email field#441
khendrikse wants to merge 2 commits into
masterfrom
SEC-860/stricter-from-email-rules

Conversation

@khendrikse
Copy link
Copy Markdown
Contributor

- Summary

Adds validation to SMTPConfiguration that rejects admin_email values using Netlify-owned domains (netlify.com, netlify.app), closing a vulnerability where an attacker could send SPF/DKIM/DMARC-authenticated phishing emails from team@netlify.com via Netlify's mail infrastructure. Validation runs at update time in UpdateInstance and covers exact domain matches, subdomains, and invalid email formats.

- Test plan

- Description for the changelog

- A picture of a cute animal (not mandatory but encouraged)

@khendrikse khendrikse requested a review from a team as a code owner May 13, 2026 09:37
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d6387952-bccf-4817-b6b0-69ab4c3475f8

📥 Commits

Reviewing files that changed from the base of the PR and between 7614198 and 10a228b.

📒 Files selected for processing (3)
  • api/instance.go
  • conf/configuration.go
  • conf/configuration_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • conf/configuration_test.go
  • conf/configuration.go

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Create and update operations now validate SMTP admin email domains; requests with disallowed or malformed admin emails return a 400 Bad Request.
    • SMTP secrets remain masked in responses.
  • Tests

    • Added unit tests covering SMTP admin email validation, including reserved domains and invalid formats.

Walkthrough

Adds SMTP admin email validation: a new SMTPConfiguration.Validate() parses AdminEmail, rejects addresses in netlify.com or netlify.app (including subdomains), and is invoked in CreateInstance and UpdateInstance when BaseConfig is provided, returning 400 on failure. A table-driven test covers allowed, reserved, subdomain, invalid, empty, and quoted-local-part cases.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding stricter validation rules for the admin email field to prevent use of Netlify-owned domains.
Description check ✅ Passed The description is related to the changeset, explaining the security vulnerability being addressed and the validation approach implemented.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch SEC-860/stricter-from-email-rules

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions
The command is terminated due to an error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
conf/configuration_test.go (1)

33-39: ⚡ Quick win

Add a regression case for quoted local-parts containing @.

Please add a case like "\"a@b\"@netlify.com" expecting an error, so this bypass path stays covered long-term.

🧪 Suggested test case addition
 	{
 		{"", false},                     // empty is fine
 		{"noreply@example.com", false},  // valid non-Netlify domain
 		{"team@netlify.com", true},      // reserved domain
 		{"user@netlify.app", true},      // reserved domain
 		{"user@sub.netlify.com", true},  // subdomain of reserved
+		{"\"a@b\"@netlify.com", true},   // quoted local-part with '@' must still be blocked
 		{"not-an-email", true},          // invalid format
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@conf/configuration_test.go` around lines 33 - 39, Add a regression test entry
for quoted local-parts containing @ by inserting the case
{"\"a@b\"@netlify.com", true} into the existing test cases array in
configuration_test.go (the same table with entries like {"noreply@example.com",
false} and {"team@netlify.com", true}) so the validation logic that handles
quoted local-parts is exercised and expected to error; ensure the string is
properly escaped in the Go source.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@api/instance.go`:
- Around line 111-115: CreateInstance currently skips SMTP validation allowing
bypass of reserved-domain rules; add the same SMTP config validation used in the
update path by invoking params.BaseConfig.SMTP.Validate() inside CreateInstance
(the same check you see in the UpdateInstance branch) and return
badRequestError("Invalid SMTP configuration: %v", err) on failure so
BaseConfig.SMTP.AdminEmail is enforced at creation time as well.

In `@conf/configuration.go`:
- Around line 297-305: The current validation uses strings.Split(addr.Address,
"@") which fails for quoted local-parts containing '@' (e.g.,
"\"a@b\"@netlify.com") and thus skips reserved-domain checks; change the logic
in the block that reads addr.Address to find the last '@' using
strings.LastIndex, if idx >= 0 extract domain :=
strings.ToLower(addr.Address[idx+1:]), then iterate over reservedDomains and use
domain == reserved or strings.HasSuffix(domain, "."+reserved) to return the same
error; also handle the case idx < 0 by skipping validation (or treating as
invalid per existing behavior) so behavior is correct for RFC5322 addresses.

---

Nitpick comments:
In `@conf/configuration_test.go`:
- Around line 33-39: Add a regression test entry for quoted local-parts
containing @ by inserting the case {"\"a@b\"@netlify.com", true} into the
existing test cases array in configuration_test.go (the same table with entries
like {"noreply@example.com", false} and {"team@netlify.com", true}) so the
validation logic that handles quoted local-parts is exercised and expected to
error; ensure the string is properly escaped in the Go source.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bfcb455c-1810-4382-8b44-d74e3e002906

📥 Commits

Reviewing files that changed from the base of the PR and between ab1bf15 and 7614198.

📒 Files selected for processing (3)
  • api/instance.go
  • conf/configuration.go
  • conf/configuration_test.go

Comment thread api/instance.go
Comment thread conf/configuration.go Outdated
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.

2 participants