This post covers the disclosure process for the vulnerabilities described in my RPKI exploit chain, through RIPE NCC’s Responsible Disclosure Policy.
What went well
RIPE NCC engaged in good faith throughout. All security issues I reported were fixed. The first XSS vulnerabilities were fixed within two weeks of being reported. They broke some of their normal release cycles to ship security fixes urgently. Once the database team had a direct explanation from me, they fixed the CSRF in RIPE Database within a day.
What was hard
The process was exhausting in a way that is hard to convey without the full timeline, which is included at the end. The short version:
- 14 months
- five separate communication channels: (1) Intigriti; (2) a support ticket (3) a Jira thread; (4) direct email thread to staff after not getting replies from security@ripe.net; (5) an email thread with the database team directly in response to a public announcement
- three rounds of fixing a vulnerability that was declared resolved twice before it actually was, including once after a public release announcement
- 26 emails or messages sent by me
The RIPE NCC Responsible Disclosure Policy strives to respond “within three business days with our evaluation of the report and an expected resolution date.” I’ve rarely received either, and definitely not within three business days.
Coordinating fixes across multiple teams for an unusual attack chain is difficult. The individual staff I worked with were responsive and capable when they had the right context. But the process around them seemed under-resourced for the complexity: it looked to me that reports were not tracked well, and overview was lost. I was regularly not informed when issues were resolved, timelines were unclear, and communication was fragmented across multiple channels.
In each report, I recommended structural defenses beyond fixing the specific
bugs: a Content-Security-Policy on Atlas and RIPEstat and a tighter
crowd.token_key cookie scope are recurring points.
Each would block a class of future vulnerabilities, not just the ones I’d
reported.
A year later, none had shipped. The XSS through TLS certificate fields I found in February 2026 would have been blocked by CSP, and with CSRF-DB still unfixed, it chained immediately to RIPE Database. Atlas has since gained a strict CSP. Cookie scope is still pending. I imagine this was more about competing priorities than disagreement, but the result was that specific fixes shipped, while structural gaps stayed open.
Example: the bizarre arc of CSRF-DB
CSRF-DB took 13 months and three separate fixes to resolve. Each fix could have been verified as incomplete by RIPE NCC re-running the proof of concept I submitted with my original report.
- I reported it in February 2025.
- In June 2025, RIPE NCC modified the CORS headers.
My report included a working proof of concept that used
no-corsmode, and I specifically noted that. CORS headers are irrelevant tono-corsrequests, so the fix was not complete, though I didn’t realise that at the time. - On February 26, 2026, I re-ran my original proof of concept to be thorough. To my surprise, it still worked. Assuming it had been fixed, I had freely discussed the details with various people, but not in writing.
- I immediately mailed security@ripe.net, warning that RIPE DB has a live vulnerability that is no longer confidential. Remembering their ticketing system as unreliable, I sent a second message in an open Intigriti issue the next day. By this point, I had also reported a new XSS that made CSRF-DB immediately exploitable.
- On March 9, having had no visible response (a reply was lost in Intigriti as an internal comment, I learned later), I tracked down the individual RIPE NCC address of the staff member I had communicated with.
- On March 12, 14 days after my first warning, I received my first response.
- On March 16, RIPE NCC announced RIPE Database 1.121.1 with another incorrect fix, described in the release notes only as “a fix for a cross-site vulnerability affecting the Syncupdates service”. Again, my original proof of concept still worked. The situation had now worsened: they had publicly stated the type of vulnerability, and that it was severe enough to break release cycle, without actually fixing it.
- March 16-18, I directly engaged with the Database team.
1.121.2
finally closed CSRF-DB. The real fix was
this db-web-ui commit,
which started forwarding the
Originheader to the whois backend so it could reject cross-origin requests. During this conversation, we also found that the syncupdates GET endpoint was vulnerable, which the Database team addressed by removing GET support. The public 1.121.2 release notes describe only the GET removal, which is a bit confusing.
With a total time between report and known resolution of 407 days, it exceeds my record of 404 days when I compromised Apple keychain access groups.
Important clarification: CSRF-DB was only exploitable if there was another XSS
in any *.ripe.net website. When CSRF-DB took so long to be fixed in 2025, there
were no known XSS, although I had stressed that more may exist that I did not
know of, and that would escalate them immediately to RIPE Database. In
hindsight, this was true, as I found the XSS through TLS in February 2026.
Unsurprising, given the large attack surface under *.ripe.net.
Bug bounties and time spent
I received bug bounties totalling € 3200 across three reports. Finding the vulnerabilities took days. The 14 months after that I spent retesting fixes that did not work, explaining browser mechanics, and chasing responses across five communication channels. That said, when it came to bounty amounts, RIPE NCC met their advertised process.
The bounties were:
- RIPENCC-MMP7ZVEF: € 1100 (tier 1, critical). Covered XSS in the old RIPEstat UI through version.bind, and CSRF from there to RIPE Database, and CAA issues (will be covered in another blog soon). Released to me by RIPE NCC 11 months after the report.
- RIPENCC-N3UMARGC: € 100 (tier 2, high). Covered XSS in atlas.ripe.net through NSID, an extra starting point for the CSRFs, and allowing actions on RIPE Atlas on behalf of the logged in user. Released to me by RIPE NCC 11 months after the report.
- RIPENCC-JXRK76XO: € 2000 (tier 1, exceptional). Covered XSS in atlas.ripe.net through TLS certificate fields, and CSRF from there to RPKI dashboard. Released to me by RIPE NCC 46 days after the report.
Dealing with a bug bounty platform

Bug bounty platforms optimise for common web vulnerabilities. Reports involving DNS, TLS, and routing security don’t fit that model.
This was my first experience with a bug bounty platform. My exploit chain was very domain specific: it used DNS and TLS certificate fields, and escalated to RIPE Database and RPKI. These aren’t just websites where someone might change some data: they can have a severe impact on internet operations.
The deep domain knowledge required to understand the severity is completely absent from the platform triage process. Interactions with Intigriti triage were frustrating, as they did not understand how to plant the XSS or why the vulnerability was serious.
Eventually I learned to focus on getting reports escalated to RIPE NCC directly, ignoring Intigriti’s triage conclusions. For organisations operating critical infrastructure, this is a structural problem worth thinking about: having people who do not understand the domain early in the triage path may cause you to miss out on serious reports.
Building a Proof of Concept
Ideally, I’d build an end-to-end proof of concept. This was straightforward for my OpenWRT vulnerabilities, as it ran in a contained environment on my testing hardware.
If however, I embedded an example RPKI dashboard payload into a TLS certificate, that would risk unintended disclosure to anyone who examined the certificate or the Atlas measurement. The TLS certificate and the Atlas page showing it would immediately reveal the XSS, CSRF, and their target, and could be automatically indexed.
The absence of a full end-to-end PoC made it harder to show how severe this was, both in writing the report and in passing Intigriti triage. This is a structural problem: the standard expectation of a complete, runnable exploit works against reports like mine, where fully demonstrating the vulnerability could easily disclose the details.
The published security reports
The RIPE NCC Responsible Disclosure Policy states:
After a major security issue has been solved, we will publish a report on our website explaining the vulnerability discovered and how we fixed it on a case-by-case basis
- For one of my XSS injections, RIPE Atlas published a note, with credit.
- For CSRF-RPKI, RIPE NCC published a two-paragraph PDF. It describes the issue as “a misconfiguration of CORS in the RPKI Dashboard”. But, there’s something more curious about that PDF: I reported the “simple requests” method on February 26, and the weak CORS headers on March 3rd. RIPE NCC claims to have fixed the CORS headers (and Atlas XSS) on February 26, and the “simple requests” method on March 10. RIPE NCC’s PDF has my reports the wrong way around.
No report mentions the complete chain, its severity, or reflections on the process. Except the one RIPE Atlas XSS report, I am not named or credited. Nothing was published on RIPE NCC’s Disclosures and Reports page. A future joint RIPE Labs article was mentioned several times, and RIPE NCC began drafting their perspective, but it was never finalised.
What better looks like
Fortunately, all of this is fixable. A few specific things that would have helped, and that I’d suggest any organisation operating critical infrastructure think about:
Solid vulnerability tracking
Any security team should have a single record per disclosure, tracking the reporter’s description, affected teams, current fix status per component, who has been briefed, and a verification checklist. This prevents knowledge from being lost between handoffs and ensures fixes are verified against the original proof of concept before being declared complete. This feels like standard practice for any security function, but in any case, it was not functional here.
Keeping the reporter in the loop
I was regularly not given expected fix timelines, and discovered several fixes independently by testing rather than being notified. Reasonable practice is to share a timeline and notify the reporter when a fix ships so they can verify it. This is also what closes the loop on disclosure timing, and is a sign of respect to the reporter.
Domain expertise in triage
This is a challenge, as anyone with a bug bounty receives plenty of poor reports. However, I’ve consistently run into problems where my findings are too complicated for people trained at regular web security. This causes delays and frustration. This could be improved with a specialist review path for infrastructure security reports, or a clear escalation route when the impact depends on domain knowledge the triage team doesn’t have.
Being thoughtful of the reporter’s time
The disclosure should be driven by the security team’s own process, not by reminders from the reporter. Someone internal should own each report end-to-end and chase blocked teams without needing to be prompted. Status updates, fix announcements, and bounty payouts should arrive without the reporter having to chase.
Final notes
None of these practices are unusual. These are basic security operations, and the fact that
none of this worked for my reports suggests that the security process was not ready
for this level of complexity or severity.
RPKI has HSMs, key ceremonies, and SOC 2 assurance1 for the trust anchor, but the
RPKI dashboard did not have CSRF protection. The most likely targets for XSS to
be planted, like Atlas and RIPEstat, did not have Content-Security-Policy.
But most of all, incident response seems to struggle.
Organisations and communities sometimes try to address this by adding more compliance and certification. But formal compliance and operational security are not at all the same, and in my own limited experience with disclosure, more certifications do not necessarily result in better incident response.
RIPE NCC has lately been focussing a lot on certifications and compliance2, also due to interest in this from the community. Certifications consume the same limited security budget and staff time3, and they build a process around audits and checklists rather than handling the unexpected. I would rather see that investment go towards empowering the engineers who actually build and secure the systems. Then again, there may be regulatory requirements that are not entirely visible to me, which could be constraining the RIPE NCC’s options.
Overall, there is much room for improvement. RIPE NCC has said they took my feedback into account to reflect and improve their processes around vulnerability reporting. I’ve suggested sharing those reflections with the community.
The full timeline
The following timeline includes all significant communication across all channels, not just report and resolution dates. Events on the same day through different platforms may not be in chronological order for that day.
| Date | Event |
|---|---|
| 2025-02-02 | Ticket 820367: I report an XSS in the old RIPEstat UI through DNS version.bind to security@ripe.net. In a follow-up mail, I indicate I want to submit this through the bug bounty program, but the link in the disclosure policy was broken. |
| 2025-02-04 | 820367: RIPE NCC confirms reproducing the XSS, and provides an updated bug bounty program URL. |
| 2025-02-04 | Intigriti: I report RIPENCC-MMP7ZVEF on Intigriti: the XSS through version.bind, and CSRF from there to RIPE Database. My recommendations: fix the XSS, use CSRF protection, use Content-Security-Policy, limit the power of crowd.token_key. |
| 2025-02-04 | Intigriti: Intigriti triage downgraded MMP7ZVEF from critical in tier 1 (https://github.com/RIPE-NCC/whois) to high in tier 2 (*.ripe.net) and asked how to reproduce the XSS themselves. I explained they likely could not without their own address space and disagreed with the downgrade. |
| 2025-02-04 | Intigriti: I follow up 2x in MMP7ZVEF with two CAA issues: CAA-MTG and CAA-ATLAS. I will cover these in a separate blog: they are also very serious, but rather different. Included in this timeline for transparency. I specifically stress again how weak crowd.token_key is. |
| 2025-02-05 | 820367: I inform RIPE NCC I have reported XSS version.bind through the bug bounty, and that I have also reported CSRF-DB, CAA-ATLAS, and CAA-MTG in Intigriti. |
| 2025-02-05 | 820367: RIPE NCC confirms receiving my report and will discuss it internally. |
| 2025-02-05 | Intigriti: Intigriti passed MMP7ZVEF to RIPE NCC. |
| 2025-02-05 | Intigriti: I report RIPENCC-N3UMARGC on Intigriti: XSS in atlas.ripe.net through DNS NSID, along with impact on RIPE Atlas. Can also be used for CSRF to RIPE Database. My recommendations: fix the XSS, use Content-Security-Policy. |
| 2025-02-07 | Intigriti: RIPE NCC confirms receipt of MMP7ZVEF and N3UMARGC, are reviewing. |
| 2025-02-14 | Intigriti: RIPE NCC confirms my reported XSS were fixed, one of the CAA issues, and say they are working on preventing CSRF from other ripe.net hosts, limiting trust on the crowd.token_key. Bounty will be discussed internally. |
| 2025-02-26 | Intigriti: I ask for a timeline in changes to crowd.token_key, as it is high risk. I confirm my reported XSS and CAA-MTG as fixed. CAA-ATLAS and CSRF-DB are not fixed. I indicate I want to publish at some point. |
| 2025-03-03 | Intigriti: RIPE NCC says my report is critical in tier 1, but does not assign the bounty in Intigriti. They can not give a timeline on crowd.token_key. CSRF-DB is expected to be fixed in several weeks. CAA-ATLAS is still under discussion. RIPE NCC requests to hold on publication and coordinate after resolving all. |
| 2025-03-04 | Intigriti: I thank RIPE NCC for the update and commit to hold publications. |
| 2025-03-10 | Intigriti: RIPE NCC says they will fix CAA-ATLAS soon, and requests a meeting around disclosure. They suggest a joint RIPE Labs article. |
| 2025-03-27 | Intigriti: I meet with RIPE NCC staff in their office. I do not have notes, I do remember again stressing the crowd.token_key cookie is dangerous, and several design issues create a high risk for my reported issues to reoccur. |
| 2025-05-14 | 820367: I ask for a status update on CSRF-DB. I note that I saw CAA-ATLAS is fixed. |
| 2025-06-16 | INFOSEC-55: RIPE NCC responds after one month to 820367 that due to a ticketing system migration for security@ripe.net, mails were not being properly forwarded, so they had not seen my previous email. They will discuss CSRF-DB with the database team. They also invite me to work on the RIPE Labs article together. |
| 2025-06-17 | INFOSEC-55: RIPE NCC confirms that the CORS headers for RIPE DB were updated, implying that CSRF-DB is resolved. They ask for a call to discuss publication. This fix was turned out not to be correct, as my original proof of concept used no-cors mode, and I specifically noted that, i.e., CORS headers have no impact. I did not realise the fix was incomplete at the time. |
| 2025-07-23 | INFOSEC-55: I thank RIPE NCC for the update, and attach a draft publication. |
| 2025-08-15 | INFOSEC-55: RIPE NCC mails that they couldn’t finalize their writeup of the RIPE NCC perspective on the vulnerabilities, will return to it in the second week of September. |
I sent a draft publication on 23 July 2025. On August 15, RIPE NCC mailed that their writeup was delayed would follow in mid-September. It never came, and I did not hear back for four months. During this time, the bounty was also not payable, as the status remained “pending”, and not “accepted”.
| Date | Event |
|---|---|
| 2026-01-05 | Intigriti: I ask in Intigriti MMP7ZVEF for RIPE NCC to assign the bug bounty. |
| 2026-01-07 | Intigriti: RIPE NCC apologises, as the topic was “parked before the summer break, and never got the time to revisit it”. Confirms that they believe all issues are fixed, and will resume work on reporting. Bounties are assigned and the issues are marked “accepted”. |
| 2026-02-25 | INFOSEC-55: I indicate to RIPE NCC that I believe Intigriti imposes requirements on me that do not comply with the GDPR and/or Dutch UAVG (in previous emails, I have asked privacy@intigriti.net and legal@intigriti.net for clarification, but they have never replied) and ask for alternate payout methods. |
| 2026-02-26 | INFOSEC-55: I write that the previous patch for CSRF-DB has not fixed the issue. My original proof of concept, as reported in February 2025, works on first try. I indicate that while I have not published anything written, I have discussed this openly, though not in writing. I also provide advance notice that RIPENCC-JXRK76XO is on the way. |
| 2026-02-26 | Intigriti: I report RIPENCC-JXRK76XO on Intigriti: XSS in Atlas through TLS SubjectAlternativeName, and CSRF from there to RPKI dashboard GraphQL API. Recommendations: fix the XSS, require application/json in the GraphQL API, use Content-Security-Policy, limit the power of crowd.token_key. |
| 2026-02-26 | Intigriti: Intigriti triage downgrades the issue from exceptional in tier 1 (https://github.com/RIPE-NCC/rpki-core) to high in tier 2 (*.ripe.net). |
| 2026-02-26 | Intigriti: RIPE NCC confirms receipt of JXRK76XO, are reviewing. |
| 2026-02-27 | Intigriti: I respond in Intigriti MMP7ZVEF that I have sent emails to security@ripe.net on 25 and 26 February, pointing out again that CSRF-DB is unfixed and has been publicly discussed. |
| 2026-03-03 | Intigriti: I follow up in JXRK76XO that the RPKI dashboard GraphQL API also does not set restrictive CORS headers, making the exploit simpler. |
| 2026-03-09 | Infosec email thread: I mail the staff member I had most communication with on their personal RIPE NCC address. I indicate I am not sure if their ticketing system is working, as I haven’t been getting substantive responses in INFOSEC-55 since June 2025. I ask for a specific timeline for resolution, as I want to submit to conferences, and need to know their planning. I list all vulnerabilities I have reported, their status to my knowledge, and recommended resolutions, asking for a reply within one week. I also note my legal disagreement with Intigriti. I note XSS through TLS was fixed some time after my report (I was not notified, I checked it myself). |
| 2026-03-12 | Infosec email thread: the RIPE NCC staff member replies. CSRF-DB will be fixed within two weeks, CSRF-RPKI is fixed. The SSO token is under discussion. They want to coordinate on disclosure and ensure details are aligned. The RIPE NCC believes Intigriti is GDPR compliant and shares the privacy statement, and that regardless, they are now bound to them through their contract with Intigriti. |
| 2026-03-16 | Infosec email thread: I ask for RIPE NCC to assign a bug bounty to JXRK76XO, say that I do not agree in Intigriti/GDPR but will relent. I flag a tracking pixel injection in RIPEstat, due to insufficient HTML cleaning in RIPE Database displays, but it is not otherwise exploitable, only a small privacy leak. Though I do stress I recommend against HTML cleaning attempts. |
| 2026-03-16 | DB team email thread: RIPE NCC announces RIPE Database 1.121.1 as a security release for a CSRF vulnerability, adding Origin validation in an API. This fix was not correct. |
| 2026-03-16 | DB team email thread: I respond to the DB team and the security team staff member that I do not believe their patch has resolved it: my original proof of concept still executes. |
| 2026-03-16 | DB team email thread: RIPE NCC DB team responds with questions about my proof of concept. |
| 2026-03-17 | DB team email thread: I respond with a deeper explanation, a cleaned up proof of concept, explanation of the wider context and exploitation chain, and the interactions of Origin, CORS, no-cors in browsers. |
| 2026-03-17 | DB team email thread: RIPE NCC DB team fixes this by passing the Origin header from frontend to API. Indicates GET requests can also be used to change RIPE DB objects. |
| 2026-03-18 | Infosec email thread: RIPE NCC confirms the RIPEstat tracking pixel issue and has patched it, will discuss JXRK76XO bounty internally. |
| 2026-03-18 | DB team email thread: I report that the original vulnerability seems resolved, but GET requests are still vulnerable, as same-site GET requests do not include an Origin header. |
| 2026-03-18 | DB team email thread: RIPE NCC confirms reproducing the vulnerability with GET requests, and will decommission that option. |
| 2026-03-18 | RIPE NCC releases RIPE Database 1.121.2 to production, with all patches. This closes CSRF-DB. |
| 2026-03-20 | I noticed atlas.ripe.net now has a Content-Security-Policy header. |
| 2026-03-25 | Infosec email thread: I inform RIPE NCC I will be submitting to conferences. Reminded them of JXRK76XO bounty. |
| 2026-03-25 | Intigriti: RIPE NCC assigns JXRK76XO to tier 2, exceptional. |
| 2026-03-25 | Intigriti: I appeal the tier assignment, arguing that while technically correct, RPKI is evidently a high tier issue. |
| 2026-04-02 | Infosec email thread: I send a reminder regarding the tier assignment. |
| 2026-04-13 | Intigriti: RIPE NCC assigns JXRK76XO to tier 1, exceptional, and release it for payout. Expects to improve on the crowd.token_key later in 2026. |
Discussions around the contents of these blog posts and a draft slide deck followed, but are not included in this timeline.
These posts were shared with RIPE NCC for factual review prior to publication. Factual feedback from RIPE NCC has been incorporated.
I'm Sasha Romijn, an independent developer and internet infrastructure specialist in Amsterdam. I find security issues in internet infrastructure, usually in configurations, trust relationships, and cross-system behaviour that got overlooked. Previous finds include rooting OpenWrt via SSID and, some years back, compromising Apple keychain access groups.
Find me on Mastodon, Bluesky, or work with me.
At RIPE 88 in May 2024, the RIPE NCC CTO announced that the SOC 2 Type I report for RPKI could only be disclosed to members on request under an NDA. Community members raised questions about whether this was appropriate given that many more parties rely on RPKI than just RIPE NCC members. As I will not sign the NDA, I can’t determine whether the SOC 2 process mentioned anything relating to my findings. ↩︎
The RIPE NCC Activity Plan 2026 places a lot of focus on compliance for the information security team. ↩︎
At the time, RIPE NCC was engaged in a major compliance effort including ISO 27001 and SOC 2 Type II certification, which were seen as major projects with significant staff effort involved. ↩︎