<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Jonathan Leitschuh on Medium]]></title>
        <description><![CDATA[Stories by Jonathan Leitschuh on Medium]]></description>
        <link>https://medium.com/@jonathan.leitschuh?source=rss-bbb358f1d950------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*2llGt3HNFHy8WfZyJPNiqg.jpeg</url>
            <title>Stories by Jonathan Leitschuh on Medium</title>
            <link>https://medium.com/@jonathan.leitschuh?source=rss-bbb358f1d950------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 19:42:06 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@jonathan.leitschuh/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Digital Travel App TripBFF Exposed Location Data Way Too Accurately]]></title>
            <link>https://infosecwriteups.com/digital-travel-app-tripbff-exposed-location-data-way-too-accurately-524cd0792a7d?source=rss-bbb358f1d950------2</link>
            <guid isPermaLink="false">https://medium.com/p/524cd0792a7d</guid>
            <category><![CDATA[information-security]]></category>
            <category><![CDATA[security]]></category>
            <category><![CDATA[travel]]></category>
            <category><![CDATA[penetration-testing]]></category>
            <dc:creator><![CDATA[Jonathan Leitschuh]]></dc:creator>
            <pubDate>Thu, 08 Jan 2026 14:02:50 GMT</pubDate>
            <atom:updated>2026-01-10T08:05:14.461Z</atom:updated>
            <cc:license>https://creativecommons.org/licenses/by-nc/4.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*Dz9wWNv1n2KkkEno0E0WlQ.png" /></figure><h4>TripBFF exposed recent live latitude &amp; longitude data and birth date for every user on their platform</h4><p><strong>TL;DR</strong>: <em>The TripBFF App, which the founders say has over 1M downloads, 100k active users, and earns them over $1M ARR was found to be exposing exact user location and exact birthdays via an internal API to any end-user. We also found that we could move our location to any point in the world, and enumerate the local users in that area, giving us an accurate recent app-open location of every single active user on the app.</em></p><p><em>The TripBFF founders were incredibly receptive to our report and immediately fixed the identified privacy exposure. We were impressed with the rapid response by the TripBFF team. However, after initially responding warmly to the reported issues, the TripBFF team ended up ghosting us, leaving a few open and unanswered questions.</em></p><p>I’m currently living the life of a digital nomad, traveling the world. I’ve been looking to meet fellow world travelers. When I saw the app <a href="https://tripbff.com/">TripBFF</a> mentioned in a Reddit post I got curious. I installed the app and paid for a pro account. After poking around a bit, I was confronted with a map of Seattle with location pins of everyone using the app in the City.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*is5iMrB4TH3F12z3bL3AXQ.jpeg" /><figcaption>TripBFF App: Map Page of Seattle</figcaption></figure><p>While the app’s map prevented users zooming in far enough to get an accurate location on other users visually, my security research spidey sense was saying, <strong>“Huh, that location pin for me looks surprisingly accurate, I wonder what the client is receiving on the backend”</strong>. I was concerned that the zoom fidelity filter was only at a visual level within the app; so, I decided to take a deeper look.</p><h3>Enter Adam Baldwin (aka. EvilPacket)</h3><p><a href="https://evilpacket.net/">Adam</a> and I have been friends since 2019. We first met at Microsoft’s micro-conference Package Con where a bunch of package maintainers came together to discuss the security of packaging ecosystems. At the time, I was representing Gradle, and Adam was representing pre-acquisition NPM. Over the years, I’ve called Adam up when I’ve been in over my head and have always appreciated his mentorship and support. Adam lives in the greater Seattle area, and since I was in town, I figured I’d drive up to see him. I mentioned to him this app that I’d found earlier in the day and my curiosity regarding the map and we decided to sit down and take a crack at it.</p><h3>Hacking TripBFF</h3><p>I’d never tried any form of mobile hacking before, so this was an awesome opportunity to get my feet wet with someone more experienced than myself. In order to just get a bit of information regarding what internal tooling/libraries we were working with I decided to take a quick peek at the iOS application. Initial pass was to download the iOS binary ipa file with a helpful tool called ipatool (<a href="https://github.com/majd/ipatool">majd/ipatool</a>). This gave me insights into the libraries being used under the hood, including nanopb, Google Firebase, and MapBox for map rendering. I was thinking that in order to do any dynamic testing, I was going to need to work with the app with something like <a href="https://www.corellium.com/">Corellum</a>, but Adam said &quot;why don&#39;t we just intercept the traffic with BurpSuite&quot;. This isn&#39;t something I&#39;d ever done before but after following PortSwigger&#39;s rather short and <a href="https://portswigger.net/burp/documentation/desktop/mobile/config-ios-device">straightforward guide</a> I was seeing HTTP traffic from my phone!</p><p><strong>Aside:</strong> If trying to reproduce this, ensure you’re not on a WiFi network at an internet cafe or library. Many public networks, and home guest networks — if securely configured — will have <a href="https://documentation.meraki.com/MR/Firewall_and_Traffic_Shaping/Wireless_Client_Isolation">client isolation</a> enabled, meaning this will not work. I tried to figure out how to make this work with <a href="https://tailscale.com/">TailScale</a>, unfortunately <a href="https://github.com/tailscale/tailscale/issues/17164">without success</a>. Late into this research I discovered ProxyMan for iOS that allows you to do this sort of on-device HTTP request/response inspection and rewriting without needing to route your HTTP traffic through your computer.</p><h3>Findings</h3><p>Although I’d chosen to sign up for the TripBFF premium trial, Adam did not. As such, we got the opportunity to observe how the application behaved differently between the two of us.</p><p>Looking at all the requests, we quickly saw the primary authentication mechanism for the back-end servers is a <a href="https://www.jwt.io/">JWT token</a> sent in the Authorization: header. This is generally easy to spot when you see a long string of characters that begin with eyj or even just ey.</p><h4>You’re initially ”shadowBanned”: true</h4><p>One of the first requests Adam saw was a call to POST /checkShadowbanStatus which, for his account, seemed to initially return &quot;shadowbanned&quot;:true. Adam used a simple Burp find-and-replace rule to configure the proxy so that the endpoint always returned &quot;shadowbanned&quot;:false instead. We believed that this would begin to unlock functionality of the app.</p><p>Ethan Brimhall, TripBFF&#39;s CTO stated that: &quot;This has nothing to do with paying customers and new users are not initially shadowbanned. We have an extensive algo to determine if a user is &quot;spam&quot; that is checked on every app open. Additionally, the &quot;result&quot; from that function does absolutely nothing client side. It&#39;s always validated on the server.&quot; Given this context from Ethan, we&#39;re not sure why the client makes a request for this API, but regardless, the API is one of the first API calls made when the app initially opens.</p><p><strong>Request</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2cd814ed2e85b6e0d9eba5fc7675496c/href">https://medium.com/media/2cd814ed2e85b6e0d9eba5fc7675496c/href</a></iframe><p><strong>Response</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5c8180169bdcaf5820252ef421cc88b5/href">https://medium.com/media/5c8180169bdcaf5820252ef421cc88b5/href</a></iframe><h4>Location Data Sent to TripBFF Servers</h4><p>After the POST request to /checkShadowbanStatus, the next interesting request we see sent from the TripBFF app to the backend servers is a POST request to /updateLocation. This seems to be how the app tells the TripBFF servers where you are in the world both via the 7 digit &quot;geoHash&quot;, and the &quot;latitude&quot; and &quot;longitude&quot; values. The &quot;neighbors&quot; are also the neighboring geohash values of the 4 digit geoHash area surrounding the more precise &quot;geoHash&quot; value.</p><p><strong>Request</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6f22a1423728117a8d1b6c1dec40406e/href">https://medium.com/media/6f22a1423728117a8d1b6c1dec40406e/href</a></iframe><p><strong>Response</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ae80f7eb400f884e271f26b0463fff29/href">https://medium.com/media/ae80f7eb400f884e271f26b0463fff29/href</a></iframe><h4><strong>Exposing Location Data that is waaay too Accurate</strong></h4><p>One of the first things we spotted was a POST request to /fetchNearbyUsers. This POST request takes four arguments: isPremiumUser, latitude, longitude, and geoHash. The latitude, longitude, and geoHash values come from the user&#39;s current location, except when they&#39;ve used the in-app &quot;Teleport&quot; feature to move to a different location. Of course, for Adam isPremiumUser was false but for me, it was true. Again, with another few configuration tweaks to the Burp Proxy, and any proxied requests to /fetchNearbyUsers would automatically get set to true.</p><p><strong>Request</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/28307843b70346bee7c0f219ca188951/href">https://medium.com/media/28307843b70346bee7c0f219ca188951/href</a></iframe><p>Interestingly, isPremiumUser is not validated by the backend. Adam, aka &quot;Joe McPwnerson&quot;, still running the app through a proxy, and having not paid for the app, set it to true to get full user data on any account without paying for it. In Burp Repeater, Adam set up an interceptor rule that replaced all &quot;isPremiumUser&quot;: false with &quot;isPremiumUser&quot;: true.</p><p>As a non-premium user, any user could easily reproduce this with a ProxyMan rule on your device, replacing the request data on every call, thus always returning more rich information, even if you weren’t paying for premium. However, a ProxyMan license costs $99/year if you’d like to continue to receive updates, which is more than TripBFF costs at $55.99/year.</p><p><strong>Response</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7d21a40ba1a058b321d9258b8ae14a26/href">https://medium.com/media/7d21a40ba1a058b321d9258b8ae14a26/href</a></iframe><p>With Adam sitting right next to me, using the /fetchNearbyUsers API I was able to locate his user account in the list. I quickly grabbed the latitude and longitude data out of the entry tied to his account and dropped it into Google maps. Turning the Google Maps screen around to face him, I asked:</p><blockquote><strong><em>“That location pin is directly on your house, isn’t it?”</em></strong></blockquote><blockquote><strong><em>To which Adam replied with both a grimace and a laugh…</em></strong></blockquote><blockquote><strong><em>“Yes… Yes it is.”</em></strong></blockquote><p>Further, we were able to manipulate the latitude and longitude values in the POST request to /fetchNearbyUsers. <strong>This could have allowed us to scan the entire globe for the most recent app-open location of every single user of the app, without physically moving ourselves.</strong></p><p>Because the TripBFF services introduced no randomization/jitter into the data sent to their services, and this exact data is retrievable by any other user, <strong>all users were able to view the exact location where any user last opened the app</strong>.</p><p>Additionally, the /fetchNearbyUsers response returns, in Seattle, a list of ~10 users. However, the app then makes another call to /fetchNumberOfNearbyUsersLast30Days which at time-of-writing, returns 224 users with each element containing both a filled out latitude and longitude value as well as realLatitude and realLongitude values.</p><p>Interestingly, these two latitudes and longitudes are different from one another, usually starting at the decimal point. It’s not clear to me what these different values are intended to represent and why they deviate so far from one another.</p><h4>The Security Protection That Won’t Save You</h4><p>The app has a “Hide my nearby distance” feature that you can use to hide how close/far you are from another user. This is disabled by default but can be enabled by a user, presumably for additional security protections.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VCrPV6NgHqdPSTftELvDrg.jpeg" /><figcaption>TripBFF settings page with “Hide my nearby destination” setting checked</figcaption></figure><p>Unfortunately, this security protection had a critical security flaw. While the &quot;distanceKM&quot; and &quot;distanceMI&quot; values are changed to &quot;Nearby&quot;. The &quot;realLatitude&quot; and &quot;realLongitude&quot; values continue to expose the exact latitude and longitude of the user.</p><p>Below is a sample POST /fetchNearbyUsers response for a user with &quot;Hide my nearby distance&quot; enabled. Again, bogus but realistic latitude and longitude data.</p><p><strong>Response</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f27ae4d352c3eb559636716d54b98756/href">https://medium.com/media/f27ae4d352c3eb559636716d54b98756/href</a></iframe><p>Basically, even when you had “Hide my nearby distance” enabled, your exact location data was still being leaked.</p><h4>Saving Grace</h4><p>As far as we can tell, the iOS app only updated your location (by sending a POST to /updateLocation) when you initially open the app, so as long as you&#39;re actively moving you shouldn&#39;t be easily trackable. However, if you&#39;re using the app at home, hotel, AirBnB or hostel, you&#39;d be easily traceable to your exact location.</p><h4>I Know Your Birth Date</h4><p>The birthday in the response from /fetchUserProfile, unfortunately, exposed the full user&#39;s birthday using the unix epoch date that was provided during app sign-up.</p><p><strong>Request</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2e2376f88e8078e1c134a89eb332a829/href">https://medium.com/media/2e2376f88e8078e1c134a89eb332a829/href</a></iframe><p><strong>Response</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/42f0404b8b4ddfcc5bc9ce67c3c9523a/href">https://medium.com/media/42f0404b8b4ddfcc5bc9ce67c3c9523a/href</a></iframe><p>Throwing the &quot;birthday&quot;.&quot;_seconds&quot; value of 337404978 into an <a href="https://www.epochconverter.com/">epoch converter</a>, we are quickly able to determine that value maps to Wednesday, September 10, 1980, Joe McPwnerson&#39;s fake birthday used at account creation.</p><h4>Stealing Data En-Mass</h4><p>Since the /fetchNearbyUsers endpoint allows you to set the location you&#39;d like to search, it would be rather easy to create a script to walk the planet, <strong>searching the app&#39;s databases for every single active user and exfiltrating that data.</strong> If this behaviour were to go undetected by the TripBFF developers, this could be used by third parties to track the locations of users of the TripBFF app on a near continuous basis.</p><h4>The out-of-date Privacy Policy</h4><p>In reviewing the TripBFF Privacy Policy (<a href="https://web.archive.org/web/20250919011930/https://tripbff.com/privacy">WayBack Machine: September 19th 2025</a>) we found <strong>no mention of the fact that TripBFF collects location information.</strong> Although the iOS app does list that location data may be collected. Obviously, in order for the app and service to function properly, it must be collecting and storing user location information.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/986/1*oxZViLPutr5AhrdEQD2wlA.png" /><figcaption>Apple Permissions Requested page for TripBFF which includes requesting “Location” permission</figcaption></figure><p>I pointed out this gap between the Privacy Policy and the app’s obvious feature set to the TripBFF team, and while it was confirmed that they planned to fix this, as of the date of publication, the Privacy Policy has yet to be updated. Although I’m not a lawyer, I would assume that not explicitly stating what/how location data is being used for their EU users is likely a potential GDPR violation.</p><h3>Proposed Fixes</h3><p>When reported to the TripBFF team, we submitted the following proposed fixes for the identified data exposures:</p><ul><li>Fifteen decimal precision on latitude/longitudes is completely unnecessary to be sending to a backend server. Limit the accuracy to two decimal places of real data, with a third decimal place should be randomly generated, to create some skew/anonymization.</li><li>All geohash values should be reduced to a maximum of 6 characters of precision. This would limit the granularity to a cell ≤ 1.22km width x 0.61km cell.</li><li>Don’t send the full epoch birthday value back in the /fetchUserProfile response.</li><li>Implement rate-limiting for users that request data from the /fetchNearbyUsers endpoint too quickly as this could be an attempt by a malicious actor to scrape data from the API.</li><li>“Hide my Distance” should pin the user’s location to the center of the nearest city, or do more to fully anonymize the location of the user that has enabled this setting.</li></ul><h3>Response by the TripBFF Team</h3><p>The TripBFF team was incredibly receptive to our report. I initially reached out by simply asking where to report security issues like this to the team, and Ethan, the CTO, responded within 6 min of my having reached out.</p><p>Immediately upon receiving our full report the TripBFF team pushed to prod a change to skew the coordinates returned from the backend when fetching /fetchNearbyUsers as a short-term fix. They also committed to shipping an iOS update that would collect far less accurate coordinates (although as of November 18th, 2025 this has not occurred).</p><p>Further GET requests from /fetchNumberOfNearbyUsersLast30Days will no longer return the exact user&#39;s coordinates anymore. Coordinates now snap to a 1 km grid, and add a + or - 400 m jitter. This jitter has a minimum offset from the true location, and the jitter rotates daily. One concern that does arise from this solution is the question as to if it’s sufficient if the user lives in an incredibly rural area, or is, for example, hiking deep in the wilderness. There are only so many places someone could be along a linear trail, so 1km ± 400m might not be sufficient in all cases.</p><p>Additionally, the updates to the server also fix accounts so if “Hide My Nearby Distance” is enabled, the API will always just return 0.0, 0.0 instead of the real coordinates.</p><p>Finally, a change was pushed to the server to skew the birthday value returned, until they were able to push an iOS update to accept a returned “age” rather than a full date of birth.</p><p>Overall, these seem like adequate changes that add reasonable privacy protections for users while still offering the user experience desired by the app users. Overall we were impressed with TripBFF’s reception to our report and commend them on their fast response to quickly address the security concerns we raised.</p><p>All that being said, the TripBFF maintainers promised that they would “Reduce the accuracy of the coords being sent in /updateLocation POST”. However, as of writing, this fix has not materialized into any release I’ve tested. The data being sent to the TripBFF servers is still incredibly accurate latitude and longitude data. While not a concern if you trust TripBFF, this is something you should be aware of.</p><h3>Areas for Further Exploration</h3><p>We believe that the chat functionality may be leveraging gRPC using nanopb buffers. Using burp we were unable to proxy any of the traffic for any of the chat functionality in the app. We were curious what additional functionality within the app we could unlock, but was beyond what we were willing to explore in the time we had.</p><h3>Conclusion</h3><p>Given that TripBFF does collect user location information, if you’re concerned about your privacy, I’d advise not sharing your location data with the app. Additionally, I’d suggest that you be smart about location sharing, linking Instagram &amp; TikTok to your physical location can be risky if you’re in an at-risk population. You want to be even more careful if you’re planning on traveling to a very remote location, as it will be much easier for other users to locate you even with the skew randomization introduced. All that being said, sharing your location is kinda the whole point of the app, and a core feature of what makes it fun to connect with other travelers, so just understand the risk you’re signing up for.</p><p>Overall, I’ve been pretty impressed with the TripBFF app. The UI design was very clean and user friendly. As a world traveler, I’ve personally found it to be a fun and useful tool for meeting other travelers while exploring the world, especially in Europe. However, as with everything, the devil is in the implementation details. Just a brief dive into the internal interactions between the app and its backend servers were enough to quickly reveal the exposure of sensitive user information for other users. It’s imperative that developers releasing applications like this get their apps professionally pentested by third parties to see if they are exposing their end-users to data theft, especially when working with live or close-to-live location information.</p><h3>📣 I’m on the Market</h3><p>Like what you read? I’m currently exploring my next opportunity in software security, open source, or developer tooling. If this kind of work resonates with you, I’d love to connect.</p><ul><li>📧 Email: <a href="/service/mailto:Jonathan.Leitschuh@gmail.com">Jonathan.Leitschuh@gmail.com</a></li><li>⛓️ LinkedIn: <a href="https://www.linkedin.com/in/jonathan-leitschuh/">https://www.linkedin.com/in/jonathan-leitschuh</a></li><li>📅 Schedule Time: <a href="https://calendly.com/jlleitschuh">https://calendly.com/jlleitschuh</a></li><li>☕️ Buy me a coffee: <a href="https://buymeacoffee.com/jlleitschuh">https://buymeacoffee.com/jlleitschuh</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=524cd0792a7d" width="1" height="1" alt=""><hr><p><a href="https://infosecwriteups.com/digital-travel-app-tripbff-exposed-location-data-way-too-accurately-524cd0792a7d">Digital Travel App TripBFF Exposed Location Data Way Too Accurately</a> was originally published in <a href="https://infosecwriteups.com/">InfoSec Write-ups</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The CVE CNA 72 Hour Rules are Insane]]></title>
            <link>https://infosecwriteups.com/the-cve-cna-72-hour-rules-are-insane-50b7e2ec5045?source=rss-bbb358f1d950------2</link>
            <guid isPermaLink="false">https://medium.com/p/50b7e2ec5045</guid>
            <category><![CDATA[security]]></category>
            <category><![CDATA[information-security]]></category>
            <dc:creator><![CDATA[Jonathan Leitschuh]]></dc:creator>
            <pubDate>Mon, 15 Sep 2025 20:42:31 GMT</pubDate>
            <atom:updated>2025-09-15T21:56:48.903Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8o87LYJk3uddevN2ySLatQ.png" /></figure><h4>The bureaucracy of the CVE system continues to frustrate me. Next up: the publicly disclosed vulnerability 72 hour rule!</h4><p>In theory: you should be able to get a CVE assigned for a publicly disclosed security vulnerability within 72 to 144 hours of a CNA being made aware of it.</p><p>In practice, here’s how the world really works.</p><h3>The 72 Hour Rules</h3><p>There are three 72 hour rules that cover CVE assignment and disclosure for publicly disclosed security vulnerabilities: 4.2.1.2, 4.5.1.4, &amp; 4.5.1.6.</p><p>Let’s say that, as a security researcher, have been made aware of publicly disclosed security vulnerabilities impacting multiple vendors, all in basically the same way. And you’d like to get multiple CVE numbers assigned for those impacted vendors.</p><p>Well, who’s best equipped to handle this mutli-vendor disclosure? In my experience CERT/CC. CERT Coordination Center (CERT/CC) is the coordination center of the computer emergency response team (CERT) for the Software Engineering Institute (SEI), a non-profit United States federally funded research and development center. CERT/CC has a tool called VINCE for handling multi-vendor security vulnerability disclosures.</p><p>But what happens if CERT/CC doesn’t assign CVEs in the 72 hour window? Then based upon my initial reading of the rules, you should be able to appeal to MITRE as the Root CNA.</p><p>With a cursory read of the CNA rules, you’d think that it should be relatively easy to get timely CVE number assignment for publicly disclosed vulnerabilities, ideally within 72 hours. Let’s take a look at the <a href="https://www.cve.org/resourcessupport/allresources/cnarules#section_4-2_CVE_ID_Assignment">CNA Operational Rules</a>:</p><blockquote>4.2.1.2 For Publicly Disclosed Vulnerabilities, if the CNA with the most appropriate scope:</blockquote><blockquote>1. preemptively documents that it will not assign, or</blockquote><blockquote>2. <strong>responds within 72 hours that it will not assign, or</strong></blockquote><blockquote>3. <strong>does not respond within 72 hours,</strong></blockquote><blockquote>then an appropriate Root MUST make a Vulnerability determination. If the Root determines that one or more Vulnerabilities exist, the Root MUST direct a CNA-LR or another CNA with appropriate scope to assign as quickly as possible and no later than <strong>72 hours</strong> after becoming aware of the first refusal. Ownership of the CVE Record MAY be transferred.</blockquote><p>In my case, I believed CERT/CC to be the CNA with the most appropriate scope. CERT/CC’s scope for CVE assignment is “Vulnerability assignment related to its vulnerability coordination role.” Unlike many other non-supplier CNAs, CERT/CC does not have a clause in their scope that forbids assignment of CVE’s in another CNA’s scope. However, at first CERT/CC at first did not respond to my request for CVE assignment within 72 hours, and then later communicated they would not assign.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Dimb7Cj8rIYRYhBrimcdRQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*X65IYIEBbuuPcXMWAxebAg.png" /></figure><h3>MITRE’s Response</h3><p>As I learned from MITRE 4.2.1.2 does not seem to apply if you involve CERT/CC in CVE assignment as MITRE in an email on the 29th of August to me said that “4.2.1.2 relates to Supplier CNAs and CERT/CC is not a Supplier CNA.” In my personal opinion, it does not, the rule nor surrounding rules nowhere mentions “Supplier CNAs”.</p><p>Some individuals who were directly involved in the 4.0 rules change process disagree with MITRE’s current interpretation. Their view is that “appropriate scope” was deliberately left broad, intended to include organizations like CERT/CC, and that limiting 4.2.1.2 to supplier CNAs was never the intent. From this perspective, the ambiguity in the rules is less about exclusion and more about under-definition.</p><blockquote>“appropriate scope” was deliberately left broad, intended to include organizations like CERT/CC, and that limiting 4.2.1.2 to supplier CNAs was never the intent</blockquote><p>MITRE has also said on the 9th of September “4.2.1.2 only applies in a situation where there was a CNA with most appropriate scope, and that CNA either didn’t respond or indicated that it is a valid vulnerability but they are not assigning, none of that is true in this situation, and therefore there is no 72-hour timeline.”</p><p>The insanity of the whole thing is that, according to MITRE, there must exist a CNA with an “appropriate scope” to dispute with in order for the 72 hour CVE assignment to apply. Otherwise, MITRE, as the Top-Level Root, is under no obligation to do anything in a timely manner. And the industry is left with a publicly disclosed security vulnerability floating around for god knows how long without anyone actually being required to act diligently upon it. The current set of circumstances, at least MITRE’s reading of it, that must arise for 4.2.1.2 to actually be useful, is far too narrow.</p><blockquote>The industry is left with a publicly disclosed security vulnerability floating around for god knows how long without anyone actually being required to act diligently upon it</blockquote><p>Meanwhile, 4.5.1.4, &amp; 4.5.1.6 both require that an undisclosed CVE number has been already assigned, so if you can’t convince anyone to assign CVE numbers to your publicly disclosed security vulnerability, you’re shit outta luck!</p><p>So, next time you’ve got a publicly disclosed security vulnerability that you want a rapid CVE assignment on, be prepared for MITRE’s response of… “yea whatev’ man… we’ll get to it someday”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*SUatk0QgYmUcK4Lo3Na4Vw.jpeg" /></figure><h3>FAQ</h3><h4>What was the vulnerability that CVEs were being requested for?</h4><p>Browser plugin password manager clickjacking vulnerabilities disclosed by <a href="https://marektoth.com/blog/dom-based-extension-clickjacking/">Marek Tóth at DEF CON</a> on August 9th, 2025.</p><h4>Did you submit CVE data to MITRE and CERT/CC?</h4><p>Yep. Here’s the link to the original <a href="https://gist.github.com/JLLeitschuh/073c84507f8f73524a27f691bffa36f4">GitHub gist</a>.</p><h4>Have the vulnerabilities been fixed?</h4><p>According to Marek Tóth, all of the impacted vendors have since published fixes for the identified vulnerabilities, <a href="https://support.1password.com/kb/202508/">except for 1Password</a>. 1Password has added mitigations that are not enabled by default.</p><h4>TL;DR?</h4><p>CERT/CC stated on September 2nd, 2025 that they would not assign CVEs for these publicly disclosed security vulnerabilities. MITRE still won’t assign per their role as CNA-LR.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=50b7e2ec5045" width="1" height="1" alt=""><hr><p><a href="https://infosecwriteups.com/the-cve-cna-72-hour-rules-are-insane-50b7e2ec5045">The CVE CNA 72 Hour Rules are Insane</a> was originally published in <a href="https://infosecwriteups.com/">InfoSec Write-ups</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What’s an OSS Vulnerability Janitor?]]></title>
            <link>https://infosecwriteups.com/what-is-a-oss-vulnerability-janitor-b7ab176bdd3f?source=rss-bbb358f1d950------2</link>
            <guid isPermaLink="false">https://medium.com/p/b7ab176bdd3f</guid>
            <category><![CDATA[open-source]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[information-security]]></category>
            <category><![CDATA[security]]></category>
            <dc:creator><![CDATA[Jonathan Leitschuh]]></dc:creator>
            <pubDate>Thu, 31 Jul 2025 14:53:40 GMT</pubDate>
            <atom:updated>2025-08-01T16:02:46.302Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YEy13jn4n1eer9PurAgi8A.png" /></figure><h4>What does it take to sweep up after the industries security vulnerabilities that have been left unpatched or undisclosed?</h4><p>A while ago, I changed my job title on LinkedIn to <strong>OSS Vulnerability Janitor</strong>.</p><p>It perfectly captures the kind of work I find myself doing over and over again in the OSS software industry: <strong>quietly cleaning up security messes that shouldn’t still exist</strong> — things that fell through the cracks, or were swept under the rug, or never properly acknowledged in the first place.</p><p>I <em>love</em> reading security vulnerability disclosures. I love digging into how software breaks in insecure ways. I enjoy reading the patches to understand how, and why the patch was implemented the way it was. But what I started noticing, over and over again, is this: a lot of OSS vulnerabilities <em>don’t get fixed</em>. Or they get do fixed, but quietly, but without a CVE. Or they get patched around downstream, while the root cause in a shared open source dependency stays vulnerable.</p><p>So I started doing something about it. I started sweeping up the vulnerabilities.</p><h3>The CVE Machine</h3><p>The CVE system is like this giant machine. Once a vulnerability is assigned a CVE, it enters a pipeline that kicks off a global process of disclosure automation. Security teams take notice. Tools like GitHub’s Dependabot and Mend’s Renovate light up and begin opening pull requests. Vendors start patching. Downstream consumers get alerts. The machine begins to churn.</p><p>But here’s the unfortunate nature of the beast: <strong>if a vulnerability never enters the pipeline, it often never gets fixed</strong>. It doesn’t show up in dashboards. It doesn’t raise alarms. It doesn’t exist in the industry’s shared mental model of “what we should be worried about.”</p><p>If you maintain open source software, do security research, or hunt for vulnerabilities, one of the highest‑impact actions you can take is to make sure the vulnerabilities you find actually get fixed downstream is by <strong>getting them assigned a CVE ID</strong>.</p><p>Getting a CVE assigned is often the critical step in protecting end users. It’s how the industry declares: <em>this matters</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/523/1*uquI0gHbSjXHhKLuuwrprQ.jpeg" /></figure><h3>The Case of Graphite (and the SSRF That Lingered)</h3><p>One of the first times this really hit me was when I revisited a 2017 critical remote code execution vulnerability discovered by <a href="https://blog.orange.tw/posts/2017-07-how-i-chained-4-vulnerabilities-on/">Orange Tsai</a> in GitHub Enterprise. It was a spectacular exploit chain, and GitHub had rightfully paid a hefty $5,000 bounty for it.</p><p>But years later, I went back to look more closely at the individual components of the chain. One of them involved a library called <a href="https://graphite.dev/"><strong>Graphite</strong></a>. I dug into it and realized: <strong>the vulnerable behavior was still there in the open source code.</strong></p><p>GitHub had addressed the issue in their product, sure. But the underlying OSS library hadn’t been touched.</p><p>So I reached out to the maintainers in 2019 and said, hey, this SSRF is still live (<a href="https://github.com/graphite-project/graphite-web/issues/2008#issuecomment-537174202">link</a>). Their response? <em>“Oh yeah, we don’t even use that part of the code anymore. We can just remove it.”</em></p><p>And they did.</p><p>But <strong>how many people had unknowingly built software on top of that vulnerable code in the years since?</strong> How many more GitHub Enterprises were out there, quietly vulnerable, instead of benefiting from an upstream fix?</p><p>This is what I mean by janitorial work.</p><h3>The Eclipse Theia RCE</h3><p>Another case that stuck with me involved a serious vulnerability in Eclipse Theia — a security researcher, @omespino, hunting against Google’s bug bounty program discovered a way to escalate from an XSS to full root access in Google Cloud Shell, which happened to be using <a href="https://theia-ide.org/">Eclipse Theia</a> under the hood. <a href="https://omespino.com/write-up-google-bug-bounty-xss-to-cloud-shell-instance-takeover-rce-as-root-5000-usd/">The write-up</a> was published October 1, 2020.</p><p>Google patched it. And issued a $5,000 bounty.</p><p>But the vulnerability? <a href="https://github.com/eclipse-theia/theia/issues/7954">Disclosed without a CVE</a>. No advisory. Crickets from Eclipse.</p><p>In February of 2021, a full four months after disclosure, I ended up chasing down the vulnerability through GitHub issues, mailing lists, backchannels at Google, and eventually almost escalating to the <a href="https://www.cve.org/Resources/General/Policies/CVE-Record-Dispute-Policy.pdf">MITRE CVE dispute process</a>.</p><p>This was one case where I found myself quite frustrated with both the Google and Eclipse CNA team. This vulnerability had been exploited in the wild. It had been public since the beginning of October. However, the Eclipse Foundation had a policy of only assigning CVEs if the maintainers requested them explicitly. And the maintainers were unresponsive. The only thing standing between the industry and coordinated disclosure was… bureaucracy.</p><p>I care deeply about this work, and seeing bureaucracy get in the way of informing end-users about vulnerabilities in their OSS components drives me a little crazy.</p><p>After my pushing, a CVE (<a href="https://nvd.nist.gov/vuln/detail/CVE-2020-27224">CVE-2020–27224</a>) was finally assigned.</p><h3>The Real Work: Monotony, Not Glory</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*49Hzuth_ZJq1WJL3_7r2jg.jpeg" /></figure><p>Vulnerability research isn’t always the thrilling, hacker-movie stuff people imagine.</p><p>Frequently, it’s about:</p><ul><li>Waiting out a 90 day disclosure timeline, and hoping the world doesn’t catch on fire in the meantime</li><li>Chasing unresponsive maintainers and vendors</li><li>Submitting a GitHub issue, then sending an email, then another follow up email</li><li>Writing and rewriting an advisory to make it clear enough to matter</li><li>Dealing with the sometimes insane bureaucracy of trying to get a CVE assigned</li><li>Arguing with a CNA about why a CVE should be assigned</li></ul><p>One critical thing I’ve learned is that it’s about <em>closing the loop</em> — making sure vulnerabilities are actually fixed, <em>documented</em>, and known to the broader community.</p><p>That work is often thankless. It’s slow. It’s annoying. And it’s absolutely critical.</p><h3>The SAST Noise Problem (and Why I’m Trying to Delete Alerts)</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/350/1*oAC4AFnjnBrLgY8YI4Xi3g.gif" /></figure><p>One of the most frustrating things in security tooling — especially static analysis (SAST) — is how much noise we’ve normalized.</p><p>In many cases we’ve built this whole industry around flagging the <em>symptoms</em> of insecure defaults rather than fixing the actual root causes.</p><p>We see the same footguns pop up again and again in SAST output because the underlying libraries and APIs were never hardened. Why are we training engineers to duct-tape around dangerous behavior in libraries instead of fixing the damn thing upstream?</p><p>That’s one of the things I try to do now: <strong>follow the alert upstream</strong>, figure out why it exists, and patch the real bug.</p><p>It’s slow. It’s messy. It’s janitorial.</p><p>But every time a <a href="https://medium.com/bugbountywriteup/burn-it-with-fire-how-to-eliminate-an-industry-wide-supply-chain-vulnerability-12515516fb56">dangerous default gets fixed at the source</a>, we eliminate <strong>hundreds or thousands of future alerts</strong>. We make security better for everyone — quietly, invisibly.</p><h3>unCVEed: Feeding the Machine</h3><p>This problem is pervasive, and it’s something I keep running into again and again and again.</p><p>That’s why I created <a href="https://github.com/JLLeitschuh/unCVEed">unCVEed</a> — a project to document and track publicly disclosed vulnerabilities that likely should have CVEs but don’t. It’s a public triage point, a staging area, and a signal boost for overlooked security issues.</p><p>My goal is to raise awareness of vulnerabilities, build pressure, and eventually help push these issues through the CVE system so they can trigger the machinery that leads to actual remediation.</p><p>If you know of a vulnerability that hasn’t gotten the attention it deserves — if the system missed something — please consider opening an issue.</p><h3>Why We Need More Vulnerability Janitors</h3><p>So why isn’t this kind of work more common?</p><p>Because it’s hard. It’s draining. It’s slow. You need tact and persistence and empathy and sometimes a thick skin.</p><p>Most devs are being paid to ship features, not fix industry-endemic issues.</p><p>You have to convince maintainers — often volunteers — that a feature they lovingly built is actually dangerous. That an API they designed ten years ago is <a href="https://infosecwriteups.com/%EF%B8%8F-inside-the-160-comment-fight-to-fix-snakeyamls-rce-default-1a20c5ca4d4c">actively harming people</a>. That the impact of their decision isn’t theoretical — it’s <strong>dozens of CVEs</strong>, <strong>hundreds of security hours wasted downstream</strong>, and <strong>thousands of developers confused</strong>.</p><p>You have to have that conversation with kindness, but also conviction.</p><p>It’s not glamorous. But if we want the open source ecosystem to actually get better — not just shuffle risk around — we need more people doing this work.</p><h3>Why I Do It Anyway</h3><p>I love open source.</p><p>I love that the same project can power a Fortune 500’s flagship product <em>and</em> help a high school student learn how to code.</p><p>That kind of scale and accessibility is magical. But it also means we owe it to the ecosystem to make sure it’s safe.</p><p>That’s why I keep doing this work — even when it’s exhausting. Even when it feels like yelling into the void.</p><p>Because someone needs to.</p><h3>Are You a Vulnerability Janitor Too?</h3><p>If this resonates with you — if you also find yourself cleaning up long-forgotten security issues, chasing down unpatched footguns, or yelling into the CVE void — you might be a vulnerability janitor too.</p><p>You’re not alone.</p><p>I’m involved in the <a href="https://openssf.org/">Open Source Security Foundation (OpenSSF)</a>, (join us on <a href="https://slack.openssf.org/">Slack</a>) particularly in the <a href="https://openssf.org/technical-initiatives/vulnerability-disclosures/">Vulnerability Disclosure Working Group</a>. If this kind of work speaks to you, we’d love to have you join us. Or just shoot me a message. I’d love to hear your story.</p><p>We need more janitors.</p><p>Because if we don’t clean up the messes, who will?</p><h3>📣 Let’s Chat!</h3><p>If you found this post insightful reach out, I’m always curious to hear about software security, open source, or developer tooling. Happy to hop on a call to connect!</p><p>📧 Email: <a href="/service/mailto:Jonathan.Leitschuh@gmail.com">Jonathan.Leitschuh@gmail.com</a><br>⛓️ LinkedIn: <a href="https://www.linkedin.com/in/jonathan-leitschuh/">https://www.linkedin.com/in/jonathan-leitschuh/</a><br>📅 Schedule Time: <a href="https://calendly.com/jlleitschuh">https://calendly.com/jlleitschuh</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b7ab176bdd3f" width="1" height="1" alt=""><hr><p><a href="https://infosecwriteups.com/what-is-a-oss-vulnerability-janitor-b7ab176bdd3f">What’s an OSS Vulnerability Janitor?</a> was originally published in <a href="https://infosecwriteups.com/">InfoSec Write-ups</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Burn It With Fire: How to Eliminate an Industry-Wide Supply Chain Vulnerability]]></title>
            <link>https://infosecwriteups.com/burn-it-with-fire-how-to-eliminate-an-industry-wide-supply-chain-vulnerability-12515516fb56?source=rss-bbb358f1d950------2</link>
            <guid isPermaLink="false">https://medium.com/p/12515516fb56</guid>
            <category><![CDATA[java]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[information-security]]></category>
            <category><![CDATA[application-security]]></category>
            <dc:creator><![CDATA[Jonathan Leitschuh]]></dc:creator>
            <pubDate>Wed, 02 Jul 2025 15:06:58 GMT</pubDate>
            <atom:updated>2025-07-09T16:45:00.874Z</atom:updated>
            <cc:license>https://creativecommons.org/licenses/by-nc/4.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qSnF-RR1j8-tNSaQwJdKeA.png" /></figure><h4>🔥 The supply chain bug that couldn’t be ignored — so I torched it</h4><h3>Introduction: A Typo That Could Compromise the JVM</h3><p>In 2019, while debugging one of my own builds, I noticed something odd. The build was resolving dependencies over http:// instead of https://. Just one character off — a typo. Harmless? Not quite.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/faae35fe5a0d30e8cb6cb9c720bb08dc/href">https://medium.com/media/faae35fe5a0d30e8cb6cb9c720bb08dc/href</a></iframe><p>That tiny misconfiguration opened the door to a broader realization: the Java ecosystem was riddled with this insecure dependency resolution pattern. This wasn’t just my build. It was absolutely everywhere.</p><p>The vulnerability itself was simple: if you could man-in-the-middle an HTTP connection, you could inject malicious code into thousands of Java builds. And worse, some of the biggest names in the ecosystem were affected: JetBrains, Apache, Red Hat, Spring, Jenkins, Gradle, ElasticSearch, and many more.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*9QJRmJt-KpA_dmr1NuiPXA.jpeg" /></figure><p>That single character typo led me down a wild multi-year rabbit hole — one that started with <a href="https://medium.com/bugbountywriteup/want-to-take-over-the-java-ecosystem-all-you-need-is-a-mitm-1fc329d898fb">uncovering an industry-wide supply chain vulnerability</a>, and ended with a simple mission: driving coordinated changes across artifact hosts, build tools, and open source projects to eliminate the vulnerability class entirely.</p><p>This is the story of how I did it — and what I learned along the way.</p><h3>Part I: Understanding the Threat — Dependency Resolution over HTTP</h3><p>Dependency resolution is at the heart of every build system. When you build a Java project, tools like Maven and Gradle fetch external libraries — often from public artifact repositories like Maven Central, JCenter, or custom corporate mirrors. These dependencies are downloaded and cached locally.</p><p>But for years, many of those download URLs, hard coded in build systems, were configured using plain old http://. No encryption. No integrity checking. No other guarantee the content came from who it claimed to.</p><p>Incredibly, back in 2012, Sonatype charged a $10 donation fee for projects to be allowed to use HTTPS with Maven Central (<a href="https://www.sonatype.com/blog/2012/10/now-available-ssl-connectivity-to-central">source</a>) — a barrier that predictably saw little adoption.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*NOM75exrjGq0DeuBa1iJUw.jpeg" /><figcaption>In defense of Maven Central, they are basically operating as a free CDN for OSS maintainers</figcaption></figure><p>In 2014, Max Veytsman wrote about this in his excellent post <a href="https://max.computer/blog/how-to-take-over-the-computer-of-any-java-or-clojure-or-scala-developer/">How to Take Over the Computer of Any Java Developer</a>. His tool, Dilettante, was a proof-of-concept proxy that injected malicious payloads into JARs as they were downloaded over HTTP. It simply rendered a picture of a cat. It could’ve just as easily delivered malware. This blog post, and the resulting outcry, finally pushed Sonatype to offer HTTPS for-free to everyone.</p><p>However, years later, many of the same vulnerabilities were still present — not due to malice, but due to typos, insecure defaults, and bad copied &amp; pasted code. After extensive GitHub searches I found the problem was very much still alive, and it was everywhere!</p><h3>Part II: Enlisting the Artifact Hosts — Shutting the Door for Good</h3><p>One of the earliest realizations I had was that even if developers fixed their projects and tools improved their defaults, it wouldn’t matter if the servers still allowed insecure downloads. The problem needed to be addressed at the very foundation: the artifact hosts.</p><p>So I reached out to the largest public artifact hosts in the JVM ecosystem — Maven Central (Sonatype), JCenter (JFrog), the Gradle Plugin Portal, Spring, JetBrains, Eclipse, and Red Hat — and proposed a coordinated timeline to <strong>block all HTTP-based artifact downloads</strong>.</p><p>To my surprise, many of them agreed.</p><p>By <strong>January 15, 2020</strong>, Maven Central, JCenter, and Spring had all shipped changes to reject HTTP requests. This was a massive milestone. It meant even if a user or build tool <em>tried</em> to fetch dependencies over HTTP, it would simply fail.</p><p>This move was covered in official blog posts from:</p><ul><li><a href="https://blog.gradle.org/decommissioning-http">Gradle</a></li><li><a href="https://spring.io/blog/2019/09/16/goodbye-http-repo-spring-use-https">Spring</a></li><li><a href="https://jfrog.com/blog/secure-jcenter-with-https/">JFrog</a></li><li><a href="https://central.sonatype.org/news/20190405_http_deprecation_notice/">Sonatype</a></li></ul><p>It was one of the clearest examples of the ecosystem coming together to shut a door — not just for new code, but for old habits and bad defaults.</p><p><strong>Aside:</strong> Between the start of this research and the January 15, 2020 cut-off, I’d joined Gradle’s security team. That gave me the surreal experience of being the one to actually pull the plug on Gradle’s support for HTTP.</p><p>At the time the shutdown occurred, Sonyatype noted that they were still seeing 20% of their traffic still using HTTP. On and after January 15th, 2020, there were <a href="https://stackoverflow.com/search?q=maven+http+January+15+2020">several confused StackOverflow posts</a> asking why builds were suddenly failing.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/735/1*RWuC7npFZx7ft4S8jT-FHA.jpeg" /></figure><h3>Part III: Shifting the Foundations — Changing the Build Tools Themselves</h3><p>Once artifact hosts began shutting off HTTP support, the next logical step was ensuring that the build tools themselves would reinforce this security posture. Fixing infrastructure was important — but, as CISA notes in their “<a href="https://www.cisa.gov/securebydesign">Secure by Design</a>” initiative, fixing the developer defaults is just as critical.</p><h3>🐘 Gradle</h3><p>While working at Gradle, I authored <a href="https://github.com/gradle/gradle/pull/10065">PR #10065</a> to introduce a strict mode that required developers to explicitly opt in to resolving dependencies over HTTP. This change ensured that a one-character typo (http:// instead of https://) could no longer silently open a security hole — it had to be intentional.</p><h3>🔧 Bazel</h3><p>I reached out to the Bazel team at Google and filed <a href="https://github.com/bazelbuild/bazel/issues/8607">issue #8607</a>. Their response was the creation of the flag:</p><p>--incompatible_disallow_unverified_http_downloads</p><p>This flag blocks HTTP downloads unless a checksum is provided or a fallback HTTPS URL is available.</p><h3>🛡️ SBT</h3><p>I also engaged the maintainers of the Scala build tool, SBT, filing <a href="https://github.com/sbt/sbt/issues/4905">SBT issue #4905</a>. They too responded positively and shipped changes to mitigate the same HTTP repository injection risks.</p><p>Each of these tools implemented different mechanisms — opt-in flags, verification requirements, or outright blocks — but the goal was the same: <strong>secure-by-default</strong> builds that reduce the blast radius of a typo.</p><h3>Part IV: Cracking the Toughest Nut — The Apache Maven Saga</h3><p>While Gradle, Bazel, and SBT responded with relatively swift and thoughtful fixes, Maven proved to be a far harder challenge.</p><p>In late 2020, I began a coordinated disclosure process to report a critical issue in Maven: <strong>transitive repository injection</strong>. Maven projects could inherit http:// repositories from dependencies without the developer even realizing it. It meant you could write a perfectly secure POM — and still get compromised.</p><p>My colleague at Gradle, <a href="https://github.com/melix">Cédric Champeau</a>, authored a proof-of-concept, and I submitted it while engaging in the back-and-forth disclosure process with the Apache Security Team and the Maven PMC. The back-and-forth stretched across <strong>months</strong>. Emails went unanswered. Conversations stalled. Multiple reminders were sent. At one point, I had to loop in <a href="https://en.wikipedia.org/wiki/CERT_Coordination_Center">CERT/CC to</a> escalate.</p><p>Meanwhile, I wrote code to scan the entire Maven Central index — parsing <strong>millions of POM files</strong> to identify real-world usage and generate a list of affected coordinates. The results were staggering. Over <strong>100,000</strong> libraries were affected. Mend later published a public write-up summarizing the issue and its implications, which you can read here: <a href="https://www.mend.io/blog/maven-security-vulnerability-cve-2021-26291/">Maven Security Vulnerability: CVE-2021–26291</a>.</p><p>Eventually, after significant pressure — and after weeks of unanswered emails, stalled conversations, and repeated follow-ups — I wrote to the ASF security team:</p><blockquote><em>“What fundamentally disturbs me here is that all of us as individuals, and the companies we work for… all play a critical role in protecting the supply chain of the JVM ecosystem. To that end, we’ve all failed in some way here… This game of ‘not my problem, it’s yours’ does nothing to protect users.”</em></blockquote><p>I believed this issue was real. And someone had to push to get it fixed.</p><p>CERT/CC eventually threatened to go over the Apache Security Team’s head and issue a CVE for the unpatched vulnerability. This threat finally spurred the Apache Maven team into action. Apache Maven issued <a href="https://nvd.nist.gov/vuln/detail/cve-2021-26291"><strong>CVE-2021–26291</strong></a> and shipped a fix in version 3.8.1, changing the default behavior to block HTTP repository resolution.</p><p>This was a hard-fought win — and one that highlighted just how difficult it can be to drive coordinated change even when the risk is well-documented and easily fixed.</p><h3>Part V: Fixing It at Scale — From Bulk PRs to Black Hat</h3><p>With changes underway across artifact hosts and build tools, I wanted to see just how far I could take this — not just by changing policies or defaults, but by actually eliminating the vulnerable code in the wild. That’s when I built an automation engine for secure pull request generation.</p><p>To do that, I built a tool: the <a href="https://github.com/JLLeitschuh/bulk-security-pr-generator"><strong>bulk-security-pr-generator</strong></a>. In early 2020, I live streamed myself using it to generate 1,596 pull requests in one sitting, patching insecure dependency resolution across the JVM ecosystem. Over the past several years, <strong>over 40% of these pull requests have been merged</strong>. That means that 600+ OSS repositories that were vulnerable, no longer are.</p><p>This wasn’t just a stunt. It was the first successful demonstration that <strong>mass vulnerability mitigation via automation</strong> was not only possible — it was practical.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/620/1*MwA43yS2eerZ29SbXeUDMQ.jpeg" /></figure><p>That work led me to become the inaugural <a href="https://www.darkreading.com/cyber-risk/spotlight-on-first-dan-kaminsky-fellow-jonathan-leitschuh">Dan Kaminsky Fellow</a>, which gave me the time and support to turn this idea into a replicable process: one that could scale security research across entire ecosystems.</p><p>The culmination of that work was a talk — actually, <em>many</em> talks:</p><p><strong>“Scaling the Security Researcher to Eliminate OSS Vulnerabilities Once and For All”</strong></p><blockquote><em>Imagine a world where a security researcher becomes aware of a security vulnerability, impacting thousands of Open Source Software (OSS) projects, and is enabled to both identify and fix them all at once. […] Let’s not just talk about vulnerabilities — let’s actually fix them at scale.</em></blockquote><p>This talk was <a href="https://github.com/JLLeitschuh#scaling-the-security-researcher-to-eliminate-oss-vulnerabilities-once-and-for-all">presented at</a>:</p><ul><li>Black Hat USA</li><li>DEF CON 30</li><li>GitHub Universe</li><li>BSides LV</li><li>SEC-T Stockholm</li><li>No Hat Italy</li><li>Code Blue Tokyo</li><li>IWCon</li></ul><p>It told the story not just of fixing vulnerabilities, but of building and demonstrating a <strong>new model</strong> for open source security work:</p><ul><li>Find a vulnerability pattern (via CodeQL, GitHub Search, grep, etc.)</li><li>Automate the search across thousands of repositories</li><li>Automatically generate PRs with real, reviewable fixes</li><li>Submit them respectfully, with clear descriptions and opt-out options</li><li>Contribute those queries upstream to prevent regressions</li></ul><p>And most importantly: do all of this in a way that <em>helps</em> maintainers — not burdens them.</p><h3>📣 Interlude: I’m on the Market</h3><p>Like what you’re reading? I’m currently exploring my next opportunity in software security, open source, or developer tooling. If this kind of work resonates with you, I’d love to connect.</p><p>📧 Email: <a href="/service/mailto:Jonathan.Leitschuh@gmail.com">Jonathan.Leitschuh@gmail.com</a><br> ⛓️ LinkedIn: <a href="https://www.linkedin.com/in/jonathan-leitschuh/">https://www.linkedin.com/in/jonathan-leitschuh/</a><br> 📅 Schedule Time: <a href="https://calendly.com/jlleitschuh">https://calendly.com/jlleitschuh</a></p><h3>Part VI: What It Takes to Eliminate a Vulnerability Class</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*v4ZUbWh2nyX7LLOSv0mJjA.png" /><figcaption>The images that AI can come up with are just absolutely wild</figcaption></figure><p>If there’s one lesson I’ve taken away from this work, it’s this: <strong>eliminating a vulnerability class from an ecosystem requires persistence — and a multipronged strategy.</strong></p><p>You can’t assume that someone else will finish the work. You can’t rely on a single fix, a single flag, or a single PR. You have to:</p><ul><li>Patch the vulnerable consumers</li><li>Fix the defaults in the tools</li><li>Change the behavior at the source</li><li>Coordinate across organizations, vendors, and open source maintainers</li><li>Follow through until the job is actually done</li></ul><p>This wasn’t just a bug to fix — it was a systemic weakness in how the Java ecosystem resolved dependencies. It was an invisible dependency problem hiding in plain sight. And it had to be rooted out on all sides.</p><p>Security is rarely about discovering something new. Often, it’s about fixing what we already knew was broken — but at scale, with care, and with follow-through.</p><p>We didn’t just patch a bug. We made a vulnerability class obsolete.</p><p>And that’s how you burn it with fire.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=12515516fb56" width="1" height="1" alt=""><hr><p><a href="https://infosecwriteups.com/burn-it-with-fire-how-to-eliminate-an-industry-wide-supply-chain-vulnerability-12515516fb56">Burn It With Fire: How to Eliminate an Industry-Wide Supply Chain Vulnerability</a> was originally published in <a href="https://infosecwriteups.com/">InfoSec Write-ups</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[5 Years, 160 Comments, and the Vulnerability That Refused to Die]]></title>
            <link>https://infosecwriteups.com/%EF%B8%8F-inside-the-160-comment-fight-to-fix-snakeyamls-rce-default-1a20c5ca4d4c?source=rss-bbb358f1d950------2</link>
            <guid isPermaLink="false">https://medium.com/p/1a20c5ca4d4c</guid>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[information-security]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[open-source]]></category>
            <dc:creator><![CDATA[Jonathan Leitschuh]]></dc:creator>
            <pubDate>Thu, 05 Jun 2025 14:40:15 GMT</pubDate>
            <atom:updated>2025-06-06T14:06:19.144Z</atom:updated>
            <cc:license>https://creativecommons.org/licenses/by-nc/4.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WPKOKOTrQoT5efaHIMA2KQ.png" /></figure><p>How a 5-year-old deserialization flaw, a vacation phone call, and some persistence led to a safer Java ecosystem</p><h3>“I’ve Seen This Before”: Rediscovering an Old Vulnerability in New Code</h3><p>This whole story starts, as any good story starts, reading CVE’s on <a href="https://github.com/advisories">GitHub’s advisory feed</a>. A few years back I was reading <a href="https://github.com/google/security-research/security/advisories/GHSA-mjmj-j48q-9wg2">CVE-2022–1471</a>, a vulnerability in SnakeYaml reported by Google’s security team. It caught my eye immediately — not because the attack was novel, but because it absolutely wasn’t. The vulnerability allowed remote code execution (RCE) in Java applications using SnakeYAML via unsafe deserialization of YAML input. Sound familiar?</p><p>It should. I’d seen this exact vector before — five years earlier — in Moritz Bechler’s now-classic paper, <a href="https://github.com/mbechler/marshalsec"><em>Java Unmarshaller Security: Turning Your Data Into Code Execution</em></a>. Bechler’s paper had already documented how SnakeYAML, like many Java unmarshalling libraries, allowed attackers to instantiate arbitrary classes just by feeding them crafted YAML documents. SnakeYAML wasn’t just mentioned — it was one of the very first examples in the paper.</p><p>So I wasn’t surprised by the CVE itself — I was actually quite grateful the Google security team had gone back and assigned a CVE to this ancient vulnerability. What surprised me was the reaction from the project maintainer, Andrey Somov, who initially marked the issue as “Won’t Fix.” To him, it wasn’t a bug; it was a “feature” that had been documented for years. If users didn’t want arbitrary classes instantiated from YAML, they should have known to use SafeConstructor—but most didn’t. And they had no reason to.</p><p>Here’s the insecure, default usage found in nearly every tutorial:</p><pre>// Insecure by default (prior to SnakeYAML 2.0)<br>Yaml yaml = new Yaml();<br>Object obj = yaml.load(input);</pre><p>And here’s what they would have had to do to stay safe:</p><pre>// Safer alternative using SafeConstructor<br>Yaml yaml = new Yaml(new SafeConstructor());<br>Object obj = yaml.load(input);</pre><p>Unless a developer already understood the security implications, they’d never know to opt into safety — because the dangerous behavior came baked in, silently, by default.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/524/1*COJ93JQUIKhONLQ-Mb_rMA.jpeg" /></figure><p>But here’s the problem: secure defaults matter. And worse, there were already dozens of CVEs in the wild — real, exploitable security bugs — caused by this exact design flaw. I had also seen them show up in GitHub’s CodeQL scans of the open-source ecosystem, which I’d been helping analyze and triage.</p><p>In fact, at the time I was personally working to improving <a href="https://codeql.github.com/codeql-query-help/java/java-unsafe-deserialization/">CodeQL’s </a><a href="https://codeql.github.com/codeql-query-help/java/java-unsafe-deserialization/">UnsafeDeserialization query</a>. I was going through the documented deserialization classes in that query and adding information on whether each one was secure by default or not. That work sparked some spirited debate in <a href="https://github.com/github/codeql/pull/11700">GitHub’s PR #11700</a>, where I argued that CodeQl&#39;s tooling should not just flag unsafe APIs—but help developers understand what constitutes secure usage, and why that distinction matters.</p><p>So when I joined the <a href="https://bitbucket.org/snakeyaml/snakeyaml/issues/561/cve-2022-1471-vulnerability-in">Bitbucket issue thread for SnakeYAML</a>, I brought that same mindset. This wasn’t just about tooling or compliance — it was about helping maintainers see how real-world developers were misusing their API, and why the burden of secure configuration shouldn’t fall solely on the end user.</p><h3>💰Perverse Incentives in the Vulnerability Economy</h3><p>One of the things I’ve come to appreciate — grudgingly — as a security researcher is just how skewed the incentives are when it comes to fixing vulnerabilities at the root.</p><p>Vendors building static analysis tools — CodeQL, Fortify, Checkmarx, SonarQube — play an incredibly important role in securing the software ecosystem. But from an economic standpoint, their incentives are often misaligned with what actually makes software safer in the long term. Adding a new rule or query that lights up thousands of dashboards? That’s measurable progress. That’s sales collateral. But working with upstream maintainers to fix a bad default that’s causing the vulnerability in the first place? That’s hard. That’s time-consuming. And that doesn’t directly translate into more tool adoption.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*aniaKea944qRZywoYAgYlg.jpeg" /></figure><p>It’s a kind of perverse incentive system. The focus ends up being on <em>detecting</em> badness, not <em>eliminating</em> it at the source.</p><p>And to be clear: I’ve been on both sides of that divide. I’ve helped write CodeQL queries that flag unsafe vulnerability patterns. I’ve watched those alerts show up across thousands of open-source repositories. I’ve also received bounties for several of the queries I contributed as part of the now-defunct <a href="https://github.com/github/securitylab/issues?q=sort%3Aupdated-desc%20is%3Aissue%20state%3Aclosed%20author%3AJLLeitschuh">GitHub Security Lab CodeQL Bug Bounty Program</a>.</p><p>But I’ve also seen the futility of closing the same vulnerability over and over again in downstream projects, when the root cause — a dangerous default, a misused API, a permissive parser — remains unaddressed upstream.</p><p>So when I saw SnakeYAML’s maintainer dismiss the vulnerability as a non-issue — effectively saying, “This isn’t a problem with the library, just with how people use it” — I couldn’t let that go unchallenged. Because I knew from real-world data that people <em>were</em> using it this way. And they were getting burned.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sBCMu_2AdTy8wriaxgrqmA.png" /></figure><h3>⚔️ When “Intended Behavior” Becomes an Attack Surface</h3><p>At that point, I knew what I had to do. If a theoretical argument wasn’t going to move the needle, I’d make it practical.</p><p>I went back to Moritz Bechler’s <a href="https://github.com/mbechler/marshalsec">marshalsec paper</a> and payload generator and pulled out actual deserialization payloads he’d documented five years earlier — payloads that still worked against SnakeYAML’s defaults. These weren’t obscure edge cases. These were minimal, weaponizable YAML snippets that could instantiate dangerous classes already sitting on many applications’ classpaths.</p><p>I after running the payload generator, I dropped all nine of them <a href="https://bitbucket.org/snakeyaml/snakeyaml/issues/561/cve-2022-1471-vulnerability-in#comment-64586004">directly into the Bitbucket thread</a>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9540ab81ee62a072d39b1a2825d6a154/href">https://medium.com/media/9540ab81ee62a072d39b1a2825d6a154/href</a></iframe><p>That first example alone can lead to remote code execution if the right classes are in the classpath — something that’s surprisingly easy even in plain Java environments, without needing Spring, JDBC drivers, or JNDI.</p><p>I also pointed to other documented gadgets: JdbcRowSetImpl, TemplatesImpl, even Spring&#39;s own JNDI-backed bean factories. Every one of them had shown up in either published CVEs or in my own CodeQL scans of the ecosystem.</p><blockquote><em>This wasn’t hypothetical. It was happening, in production, across hundreds of projects.</em></blockquote><p>And yet, the official guidance from the maintainer boiled down to: “Don’t deserialize untrusted YAML,” and “You should have known to use SafeConstructor.”</p><p>That argument misses the forest for the trees. Yes, a knowledgeable engineer could choose SafeConstructor. But most developers aren’t parsing YAML because they want deserialization—they just want a config file. And they’re using libraries the way the README tells them to:</p><pre>new Yaml().load(input);</pre><p>That line of code — the one in nearly every tutorial and StackOverflow post — was unsafe by default. And real people were paying the price.</p><h3>🌊 The Beach, the Spec, and the Breakthrough</h3><p>Somewhere around the 80th comment in the thread, it became clear we weren’t going to resolve this through Bitbucket alone. So I did something I don’t usually do: I offered to hop on a call.</p><p>At the time the offer for a call was accepted, I was on Christmas vacation in Punta Cana, in the Dominican Republic. I took the call from the balcony of my hotel room, listening to waves crash in the background while I talked deserialization edge cases and YAML parsing internals for nearly an hour.</p><p>I’ll admit — I wasn’t optimistic. Up to that point, most of our exchanges had been tense. The maintainer, Andrey, didn’t see this as a vulnerability. I and much of the community of users did. We were stuck.</p><p>But that hour-long conversation ended up being a turning point — not just for the issue, but for me. We dug deep into the YAML spec, particularly how <strong>tags</strong> work. For anyone who hasn’t spent their vacation reading YAML specs: a <em>tag</em> in YAML is a way to annotate a node with type information. SnakeYAML had been parsing these tags — especially what the spec calls <strong>“global tags”</strong> — and treating them as Java class names to instantiate.</p><p>That was the problem. That’s how !!javax.script.ScriptEngineManager became a security issue.</p><p>After a long back and forth, where I was honestly about ready to give up, I asked a question — I can’t remember exactly what it was — but it reframed the conversation. Suddenly, we weren’t arguing over whether this was “intended behavior.” We were talking about what SnakeYAML should actually do by default.</p><p>And then something clicked. I remember Andrey saying something to the effect of, “Yeah, I could probably do that.” And with that, the wheels were in motion for this old vulnerability to finally get fixed.</p><p>That’s what led to this post in that way-too-long BitBucket thread:</p><blockquote><em>To that end, I proposed that the change we make is to modify SnakeYaml so it doesn’t process class names in, what in the YAML spec are called ‘global tags’. By not reading class names and attempting to instantiate classes from these global tags — at least not by default — I believe we will remove the vulnerability from SnakeYaml, allowing it to safely operate on untrusted data without leading to this remote code execution vulnerability.</em></blockquote><p>That proposal became the foundation for what would eventually ship in <strong>SnakeYAML 2.0</strong>.</p><h3>🔒 Secure by Default: A Long Time Coming</h3><p>A few months later, SnakeYAML 2.0 was released. The changelog was modest. But the change itself was anything but.</p><p>By default, SnakeYAML would no longer instantiate Java classes from global YAML tags. The exact same payloads that once led to remote code execution would now safely fail unless a developer explicitly configured the library to allow them. The risk was no longer hidden in plain sight — it was opt-in.</p><p>It wasn’t a huge pull request. But it was a huge shift in philosophy: <strong>Secure by default. Unsafe only with informed consent.</strong></p><p>Looking back, the thing I keep thinking about is how close this change came to never happening. CVE-2022–1471 was initially dismissed. It took a mammoth public thread, real-world exploit payloads, and a vacation phone call to finally align on a fix.</p><p>And even now — years after the fix shipped — I still get surprised by the impact. I’ve had random strangers walk up to me at conferences and thank me for my work on this issue. I’m always a little shocked when it happens. I wasn’t trying to be a hero. I was just doing what I thought was important: helping make open source safer. But it turns out, when you help get a security fix like this over the finish line, it echoes. Maintainers notice. They remember. And sometimes they carry those lessons into their own projects.</p><h3>🔚 Final Thoughts</h3><p>If you’re a security researcher: don’t stop at writing the alert. Help build the fix. If you’re a maintainer: if people are misusing your library in dangerous ways, maybe the problem isn’t the users. And if you’re building tools: detection is important — but the real win is when you make vulnerabilities impossible to write in the first place.</p><p>Secure by default isn’t a luxury. It shouldn’t be the exception. It should be the expectation.</p><h3>📣 I’m on the Market</h3><p>If you found this post insightful, I’m currently looking for my next opportunity in software security, open source, or developer tooling. Always happy to hop on a call to connect.</p><p>📧 Email: <a href="/service/mailto:Jonathan.Leitschuh@gmail.com">Jonathan.Leitschuh@gmail.com</a><br>⛓️ LinkedIn: <a href="https://www.linkedin.com/in/jonathan-leitschuh/">https://www.linkedin.com/in/jonathan-leitschuh/</a><br>📅 Schedule Time: <a href="https://calendly.com/jlleitschuh">https://calendly.com/jlleitschuh</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1a20c5ca4d4c" width="1" height="1" alt=""><hr><p><a href="https://infosecwriteups.com/%EF%B8%8F-inside-the-160-comment-fight-to-fix-snakeyamls-rce-default-1a20c5ca4d4c">5 Years, 160 Comments, and the Vulnerability That Refused to Die</a> was originally published in <a href="https://infosecwriteups.com/">InfoSec Write-ups</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[When Open Source Isn’t: How OpenRewrite Lost Its Way]]></title>
            <link>https://infosecwriteups.com/when-open-source-isnt-how-openrewrite-lost-its-way-642053be287d?source=rss-bbb358f1d950------2</link>
            <guid isPermaLink="false">https://medium.com/p/642053be287d</guid>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[refactoring]]></category>
            <category><![CDATA[openrewrite]]></category>
            <category><![CDATA[open-source]]></category>
            <dc:creator><![CDATA[Jonathan Leitschuh]]></dc:creator>
            <pubDate>Wed, 14 May 2025 18:50:09 GMT</pubDate>
            <atom:updated>2025-06-05T12:29:53.020Z</atom:updated>
            <cc:license>https://creativecommons.org/licenses/by-nc/4.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yXkTgPPJobOtoe4GHnH0dA.png" /></figure><h4>Moderne quietly relicensed community-contributed OpenRewrite code from Apache 2.0 to a proprietary license, abandoning its open source commitments. This decision risks legal exposure, undermines community trust, and sets a dangerous precedent for OSS stewardship.</h4><p>On December 26th 2024, I opened GitHub and discovered that openrewrite/rewrite-java-security — a repository I had spent the better part of two years building recipes for — had been moved, made closed source, relicensed, and made proprietary by <a href="https://www.moderne.ai/">Moderne, Inc</a>. The code I authored, the recipes I wrote, and the security work that had been funded by open source security initiatives was now locked behind the <a href="https://docs.moderne.io/licensing/overview/"><strong>Moderne Proprietary License (MPL)</strong></a>. No heads-up. No contributor outreach. No blog post.</p><p>Just a new license.</p><h3>A Quick Recap</h3><p>OpenRewrite is a code refactoring framework that enables large-scale, automated changes to Java (and other JVM) codebases. At its best, it offers a vision of what developer tooling could be: scalable, modular, and language-aware. It was originally developed by Moderne CEO Jonathan Schneider while at Netflix as an almost entirely Apache 2.0 licensed codebase, until recently.</p><p>I was one of the earliest and most active contributors to the rewrite-java-security project. My work on it began in 2022 under the <a href="https://www.darkreading.com/cyber-risk/spotlight-on-first-dan-kaminsky-fellow-jonathan-leitschuh"><strong>Dan Kaminsky Fellowship</strong></a> at HUMAN Security, and continued in 2023 through a position with the <a href="https://alpha-omega.dev/"><strong>Linux Foundation’s OpenSSF Project Alpha-Omega</strong></a>, funded by Microsoft, Google, and Amazon. I led a small team of interns to author OpenRewrite recipes that automatically fixed common security issues in vulnerable codebases. I used these recipes to generate hundreds of OSS pull requests to fix security vulnerabilities at-scale; then subsequently spoke publicly about this work on <a href="https://github.com/JLLeitschuh#user-content-scaling-the-security-researcher-to-eliminate-oss-vulnerabilities-once-and-for-all">stages like Black Hat and DEFCON</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*laMBI8sGtZ0eXZTrL-ltdg.png" /><figcaption>I’m the primary author of the “Zip Slip Vulnerability” Recipe featured predominantly on the Moderne site</figcaption></figure><p>Combined, these efforts represented <strong>many thousands of hours of community investment</strong> into a resource intended to benefit the entire open source ecosystem.</p><p>Then Moderne changed the license.</p><h3>The License Lockdown</h3><p>In December 2024, Moderne moved rewrite-java-security under the <strong>Moderne Proprietary License (MPL)</strong>. This license is not open source, not OSI-approved, and <strong>requires a signed commercial contract</strong> with Moderne to use or access the code going forward.</p><p>This means:</p><ul><li>Any improvements or changes Moderne makes to the code I originally wrote are no longer publicly available.</li><li>I am no longer able to make changes, improvements, or even contribute bug fixes to that code.</li></ul><p>Despite being one of the primary maintainers of the project, my ability to contribute to it has been fully revoked.</p><p>This licensing shift didn’t just impact rewrite-java-security. It affected a wide swath of the OpenRewrite ecosystem. Moderne applied its new licensing approach across many repositories and modules, including some with longstanding community involvement.</p><p>Here’s how the license breakdown now looks across various OpenRewrite modules: <a href="https://docs.openrewrite.org/reference/latest-versions-of-every-openrewrite-module">Full list available here</a>.</p><p>This happened without a blog post, and without an announcement to the community. It was done silently during, for most projects, a minor version bump.</p><p>When I raised these concerns in the OpenRewrite community Slack channel, I was hoping for a good-faith discussion about community impact. Instead, I was privately criticized and dismissed as being self-centered for speaking up. That kind of response made it clear that this was not a collaborative decision — it was a unilateral one.</p><h3>“Committed to the Principles of Pure Open Source”</h3><p>In April 2024, Moderne announced that OpenRewrite was joining the <a href="https://www.commonhaus.org/"><strong>Commonhaus Foundation</strong></a>, a nonprofit supporting open-source sustainability:</p><p>“Moderne is committed to the principles of pure open source… Commonhaus supports our commitment to keep OpenRewrite community-driven and accessible, ensuring its utility and relevance for years to come.”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1021/0*PBY6K46AfX-jTrk-" /><figcaption>LinkedIn post announcing OpenRewrite is joining the Commonhaus Foundation</figcaption></figure><p>This press release has since been deleted.</p><p>On December 9th, Moderne <a href="https://github.com/commonhaus/foundation/pull/218">formally withdrew OpenRewrite from the foundation</a>. The reasoning included concerns over:</p><ul><li>Trademark policy constraints that would limit Moderne’s creative use of the OpenRewrite brand</li><li>A majoritarian voting structure that could, they felt, pose future risks to Moderne’s commercial interests</li></ul><p>Despite expressing support for Commonhaus’s goals, Moderne concluded that its vision for OpenRewrite couldn’t coexist with the foundation’s governance model.</p><p>The irony here is hard to ignore. A company that professed commitment to community-led governance and “pure open source” walked back that commitment in both practice and policy — first by withdrawing from a nonprofit governance body, then by relicensing community-contributed code as proprietary.</p><h3>“Protecting Ourselves From AWS”</h3><p>When asked why they made this change, Moderne leadership cited concerns about companies like Amazon and VMware using OpenRewrite recipes without contributing back.</p><p>That might be a fair frustration. But here’s the hypocrisy:</p><ul><li><strong>Amazon</strong> didn’t strip your name from your code.</li><li><strong>VMware</strong> didn’t relicense your work without your consent.</li></ul><p>At Moderne’s CodeRemix Summit 2025, several employees explained that this fear crystallized in late 2024 when <strong>several prospective customers</strong> reportedly said they didn’t see value in paying for Moderne. Why? Because they believed that solutions like <strong>Amazon Q Code Transformer</strong>, <strong>Sourcegraph Batch Changes</strong>, or <strong>Broadcom Application Advisor</strong> would suffice.</p><p>In other words, Moderne had built a powerful open source tool — OpenRewrite — and now found itself <strong>competing with its own creation.</strong> Worse, they felt they were <strong>competing against tech giants using their own tooling</strong> without contributing anything back.</p><p>Originally, Moderne leadership viewed the company’s core value in its SaaS infrastructure, not the recipes. The OpenRewrite project — and its growing recipe library — was meant to be the open source foundation, while Moderne’s differentiator would be in the serialization and storage of large-scale abstract syntax trees (LSTs). But when third-party platforms demonstrated they could run OpenRewrite recipes at scale without Moderne, that became an existential threat to the company.</p><p>The fear was real. But the response — locking down code contributed by others — was deeply flawed and has left myself and other members of the community feeling hurt.</p><h3>This Isn’t Just About Me</h3><p>Moderne CEO Jonathan Schneider stated:</p><blockquote>“We looked through every repo, and those repos that either Moderne only contributed to or for which there were only ‘contributions like this’, we felt comfortable making the change… rewrite-java-security was the only really oddball one that needed to have some of its stuff archived and some of its stuff moved.”</blockquote><p>However, this statement does not align with observed contributions. There are <a href="https://github.com/openrewrite/rewrite-testing-frameworks/pull/520">multiple examples</a> of <strong>non-trivial community contributions</strong> that have been swept into Moderne’s proprietary or source available license, including from major enterprise contributors:</p><ul><li><a href="https://github.com/openrewrite/rewrite-spring/pull/291">VMware</a></li><li><a href="https://github.com/openrewrite/rewrite-migrate-java/pull/366">AliBaba</a></li></ul><p>These are clear counterexamples that demonstrate community-written recipes — contributed under Apache 2.0 — have now been relicensed without consent.</p><p>Other contributors have raised similar concerns. Some have seen their Apache-licensed recipes swept under restrictive terms. Others have flagged that attribution and SPDX headers were removed. All of this breaks the unspoken contract that powers open source: <em>contribute in good faith, and your contributions will be respected and remain open.</em></p><p>All of this left many of us asking if this license change was even legal.</p><p>That’s not just a rhetorical question. Under the Apache 2.0 license, relicensing code without permission from each contributor — unless governed by a Contributor License Agreement (CLA) — is a legally murky move. While companies like MongoDB and Elastic have made similar license transitions, those shifts sparked community forks and ongoing debate about their legality. Moderne’s decision follows this controversial pattern, but does so without the scale, communication, or governance that often accompany such major transitions. That raises real questions for downstream adopters and contributors alike.</p><p>Worse still, this sets a dangerous precedent:</p><blockquote><strong>Any company investing in the OpenRewrite ecosystem today risks having their employee-contributed recipes pulled into a proprietary licensing regime tomorrow.</strong></blockquote><p>This mirrors broader industry trends — like the relicensing decisions made by MongoDB and HashiCorp — where companies facing commercial pressure restrict the freedoms of the very communities that helped them grow.</p><p>We can acknowledge that “open source is free, as in free puppy.” Maintaining large-scale projects like OpenRewrite is not free, and Moderne — like any steward of OSS infrastructure — needs a viable business model. But that doesn’t make what they did right.</p><p>After crunching some data, I found that across OpenRewrite non-composite recipes, there are <strong>2,635 unique recipe contributor pairs</strong>. Of those, <strong>~350 are from email addresses that do not end in @moderne.io nor are identifiable personal emails of Moderne employees</strong>. At least some of these are <a href="https://docs.google.com/spreadsheets/d/10KI2EfV4T4bdEvjMcBM1Ns1w_fgC4ydSBVEASlRZegA/edit?gid=1613606561#gid=1613606561">real, non-trivial community contributions</a>.</p><p>We can disagree about business models. We can even disagree about licenses. But we shouldn’t just retroactively rewrite history to consolidate ownership over public, community-authored code.</p><h3>Moderne’s Corrections and Course Adjustments</h3><p>In the weeks following community pushback, Moderne took steps to correct some of the most immediate concerns:</p><ol><li><strong>Apache-licensed repositories were restored and archived</strong>, preserving prior community contributions in a public, accessible form, including <a href="https://github.com/openrewrite/rewrite-java-security">rewrite-java-security</a>.</li><li><strong>Major version bumps</strong> were introduced to properly signal the license changes in affected projects.</li><li><strong>Split namespaces</strong> (e.g., org.openrewrite vs. io.moderne) were introduced to distinguish between fully open and source-available/proprietary modules.</li></ol><p>These changes demonstrate that some of the feedback was heard and acted upon. However, the fact remains: these were not proactive measures discussed openly with the community — they were reactive corrections to a course that was set in motion without our input.</p><h3>A Path Forward</h3><p>What Moderne should do:</p><ol><li><strong>Revert the license changes</strong> on all community-authored recipes. Let what was given freely by the community remain free and open for the community.</li><li><strong>Commit to community discourse:</strong> Changes like this should not be a surprise, and if they need to be, then they should be communicated publicly instead of silently.</li><li><strong>Respect versioning</strong>: Moving forward, license changes should be <strong>major</strong> semver bumps, not slipped into a v2.17.0 update.</li></ol><p><strong>What I’m doing</strong>:</p><p>Despite all of this, I’m still passionate about automated security remediation at scale, especially for OSS projects. I plan to continue leveraging OpenRewrite as a powerful tool to perform security research and fix vulnerabilities at-scale across OSS. If you want to explore how your organization can use OpenRewrite effectively, feel free to <a href="/service/mailto:Jonathan.Leitschuh@gmail.com">get in touch</a> or<a href="https://calendly.com/jonathan-leitschuh"> book some time with me</a>.</p><h3>Final Thoughts</h3><p>Open source doesn’t work without trust. And trust is easy to lose. It only takes a quiet relicense, a removed attribution, and a private dismissal when you raise concerns in good faith. I came to the community expecting collaboration, only to be told I was being self-centered for asking questions about code I helped write.</p><p>This wasn’t just a licensing update. It was a violation of the norms, values, and expectations that hold open source communities together.</p><p>But it doesn’t have to be this way. We can build ecosystems that value contribution, respect consent, and center community over control.</p><p>OpenRewrite showed what’s possible when open source and security come together to empower developers at scale. The ideas behind it still matter. The need still exists. And I still want to help build that future — one that’s grounded in shared ownership, transparency, and trust.</p><p><em>Correction: An earlier version of this article incorrectly stated ~600 contributions were from non-moderne employees, this has been updated to be ~350 after some feedback from Moderne.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=642053be287d" width="1" height="1" alt=""><hr><p><a href="https://infosecwriteups.com/when-open-source-isnt-how-openrewrite-lost-its-way-642053be287d">When Open Source Isn’t: How OpenRewrite Lost Its Way</a> was originally published in <a href="https://infosecwriteups.com/">InfoSec Write-ups</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Falsehoods People Believe about CVE’s]]></title>
            <link>https://medium.com/@jonathan.leitschuh/falsehoods-people-believe-about-cves-85c1d063ffda?source=rss-bbb358f1d950------2</link>
            <guid isPermaLink="false">https://medium.com/p/85c1d063ffda</guid>
            <category><![CDATA[software-security]]></category>
            <category><![CDATA[cve]]></category>
            <category><![CDATA[security]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <dc:creator><![CDATA[Jonathan Leitschuh]]></dc:creator>
            <pubDate>Mon, 14 Apr 2025 15:06:46 GMT</pubDate>
            <atom:updated>2025-04-14T16:05:33.475Z</atom:updated>
            <cc:license>https://creativecommons.org/licenses/by-nc/4.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UhvxwhZTRA2NMipf-J1FPg.png" /></figure><h4>CVE ≠ Vulnerability (And 36 Other Confusions Regarding CVE)</h4><p>Billions of dollars are spent on security tooling, vulnerability scanners light up dashboards in every SOC, and somewhere in the middle of it all is a humble acronym: CVE™. It shows up in reports, tickets, release notes, investor decks, press releases, and breach reports. It is often used interchangeably, often incorrectly, with “vulnerability,” “exploit,” and “security flaw.”</p><p>Despite its ubiquity, there is widespread confusion about what a CVE actually is. Many people — some of them in charge of large enterprises— believe a CVE is the same thing as a software vulnerability. Or that every software vulnerability has a CVE. Or that a CVE always includes technical details, a fix, a CVSS score, and a confession from the developer who introduced the bug.</p><p>Inspired by <a href="https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/">Falsehoods Programmers Believe About Names</a>, this is a list of things people (wrongly) believe about CVEs. Some are naive. Some are overly optimistic. A few are just wishful thinking.</p><p>All of them are false.</p><ol><li>A CVE and a vulnerability are the same thing</li><li>A CVE exists for all publicly disclosed vulnerabilities</li><li>A CVE existing means the vulnerability was disclosed</li><li>A CVE exists</li><li>A CVE being assigned means that a vulnerability must exist</li><li>A CVE is only for big, dramatic bugs — nobody bothers with a CVE for trivial issues</li><li>A CVE has never been assigned for a <a href="https://www.theregister.com/2022/08/18/janet_jackson_video_crashes_laptops/">hardware vulnerability</a></li><li>A CVE is always assigned to a single vulnerability</li><li>A CVE is always assigned to a <a href="https://github.com/advisories/GHSA-qppj-fm5r-hxr3">single product</a></li><li>A CVE is always fixed in a single version of the software</li><li>A CVE’s year (CVE-[YEAR]) the is the year the CVE was published</li><li>A CVE will always be assigned and published on the same day the vulnerability is disclosed</li><li>A CVE will always be assigned and published within the same year that the vulnerability is disclosed</li><li>A vulnerability that has been discussed at a security conference will, of course, have a CVE assigned to it</li><li>Surely someone will have followed up after the conference, right?</li><li>Within a year?</li><li>A CVE has a fix</li><li>A CVE is never a duplicate of another CVE</li><li>A CVE is guaranteed to be exploitable</li><li>The rules governing assigning a CVE in end of life (EOL) software is exactly the same as maintained software</li><li>A CVE contains sufficient information to compute it’s CVSS score</li><li>A CVE contains sufficient information to determine the severity of the vulnerability</li><li>A CVE contains sufficient information to determine what product is affected</li><li>A CVE contains sufficient informa… 🙄</li><li>A CNA would never write a CVE description carefully and specifically to influence NIST to assign a specific CVSS score</li><li>Both the software vendor and the security researcher must agree a vulnerability exists for a CVE to be assigned</li><li>A CVE is never withdrawn or <a href="https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=DISPUTED">disputed</a></li><li>A software product that has lots of CVEs must be less secure</li><li>A software product with no CVEs must be more secure</li><li>A CVE is hard to get assigned for a vulnerability</li><li>A CVE is easy to get assigned for a vulnerability</li><li>CVE is a government program</li><li>CVE is run by the National Vulnerability Database (NVD)</li><li>CVE is run by MITRE</li><li>CVE is exclusive to the USA</li><li>The CVE system is free from politics</li><li>CVEs are assigned by an all-knowing, infallible committee that never makes mistakes</li></ol><p>This list is by no means exhaustive. If you’re skeptical that these misconceptions exist, I invite you to attend one vulnerability disclosure panel, or read through a few dozen CVE entries. Or better yet, try requesting one yourself.</p><p>Feel free to suggest more falsehoods in the comments, and share this post the next time someone insists that every CVE has a fix, a proof-of-concept exploit, a CVSS score, and universal agreement on whether it’s even real.</p><p><em>Thanks: Special thanks to everyone at </em><a href="https://www.first.org/conference/vulncon2025/"><em>Vuln Con 2025</em></a><em> who offered their own falsehoods and helped proofread this blog post.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=85c1d063ffda" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Update: Want to take over the Java ecosystem? All you need is a MITM!]]></title>
            <link>https://infosecwriteups.com/update-want-to-take-over-the-java-ecosystem-all-you-need-is-a-mitm-d069d253fe23?source=rss-bbb358f1d950------2</link>
            <guid isPermaLink="false">https://medium.com/p/d069d253fe23</guid>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[security]]></category>
            <category><![CDATA[supply-chain]]></category>
            <dc:creator><![CDATA[Jonathan Leitschuh]]></dc:creator>
            <pubDate>Wed, 08 Jan 2020 15:49:55 GMT</pubDate>
            <atom:updated>2020-01-16T18:29:49.412Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/587/1*NfH520q6hlfu8eoNnG2CZA.jpeg" /></figure><h4>January 13th-15th, 2020 will break over 21% of the industry’s Java build infrastructure. Six months since my initial article disclosing this industry-wide vulnerability, where are we now and what does the future hold?</h4><p>On June 10th, 2019 I publicly disclosed an industry-wide vulnerability impacting the Java ecosystem in an article titled ‘<a href="https://medium.com/bugbountywriteup/want-to-take-over-the-java-ecosystem-all-you-need-is-a-mitm-1fc329d898fb?source=friends_link&amp;sk=3c99970c55a899ad9ef41f126efcde0e">Want to take over the Java ecosystem? All you need is a MITM!</a>’ In that article, I detailed how many of the most popular JVM based libraries were resolving their dependencies via their build tool over HTTP instead of HTTPS.</p><p>As a part of this research, I reached out to the security teams of several of the Java ecosystem’s most used artifact servers, and on January 15th, 2020 many of these artifact servers will drop support for HTTP in favor of only supporting HTTPS. It’s important to remember that as of June 2019, 25% of Maven Central downloads were still using HTTP. As of December 12th, 2019 21% of Sonatype Maven Central downloads are still using HTTP.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/304/1*yt4QvqJIY1g-1_S6ZGOrDw.jpeg" /></figure><blockquote>21% of Sonatype Maven Central downloads are still using HTTP</blockquote><p>It’s important to stress that this breakage will force a very healthy and important shift in the security of the Java ecosystem’s supply chain.</p><h3>Artifact Server Host Announcements</h3><p>Listed below are the artifact servers I’ve reached out to and their current responses.</p><h4>Maven Central — Sonatype</h4><p>Maven Central will drop support for HTTP on January 15th, 2020.<br>You can read their <a href="https://central.sonatype.org/articles/2019/Apr/30/http-access-to-repo1mavenorg-and-repomavenapacheorg-is-being-deprecated/">full announcement here</a>.</p><h4>JCenter — JFrog</h4><p>JCenter will drop support for HTTP on January 13th, 2020.<br>You can read their <a href="https://jfrog.com/blog/secure-jcenter-with-https/">full announcement here</a>.</p><h4>Bintray — JFrog</h4><p>JFrog has informed me that they will not be decommissioning HTTP for dl.bintray.com as it is used for resolving artifacts for other ecosystems. I have pleaded with them to reconsider this decision, but at this time they are not willing to commit to this breaking change.</p><h4>Gradle Plugin Portal — Gradle</h4><p>The Gradle Plugin Portal will drop support for HTTP on January 15th, 2020.<br>You can read their <a href="https://blog.gradle.org/decommissioning-http">full announcement here</a>.</p><h4>Spring — Pivotal</h4><p>The Spring Artifact Repository will drop support for HTTP on January 15th, 2020.<br>You can read their <a href="https://spring.io/blog/2019/09/16/goodbye-http-repo-spring-use-https">full announcement here</a>.</p><h4>Eclipse — Eclipse Foundation</h4><p>Although I’ve reached out to the Eclipse Foundation <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=550999">here</a> and they were initially receptive, currently there has been no commitment on their part.</p><h4>JetBrains</h4><p>JetBrains is not willing to commit to a timeline at this point for their repositories they use to host artifacts.</p><h4>RedHat</h4><p>I’ve reached out to the RedHat security team on multiple occasions about this initiative and they have been unwilling to commit to a timeline for backing this initiative at this time. They are concerned that such a change will break their paying customers and are therefore unwilling to commit to this change at this time.</p><h4>Twitter</h4><p>Similarly, the Twitter Security team has been unwilling to commit to this initiative.</p><h3>Warnings from the Build Tools</h3><p>Starting in Gradle 6.0 and Scala Build Tool (SBT) 1.3.x, both will begin warning users that they are using HTTP instead of HTTPS to resolve dependencies with the ability to disable the warning on a per-repository basis.<br>Additionally, Google’s Bazel build will now require users to specify an SHA-256 hash for any resources downloaded over HTTP.</p><p>Unfortunately, at this time, no work has been made towards implementing the same warning in Apache Maven.</p><p><a href="https://issues.apache.org/jira/browse/MNG-6673">Deprecate HTTP Download &amp; Upload</a></p><h3>Eliminating this vulnerability in Open Source</h3><figure><img alt="Meme: Image of a squirrel with a flamethrower. The captions read: ‘Open-Source Vulnerabilities; Kill them with Fire!’" src="https://cdn-images-1.medium.com/max/637/1*Ohh3rtSyfxMBt8As0irpJg.jpeg" /><figcaption>With GitHub’s Semmle QL we can do just this for the entire OSS ecosystem</figcaption></figure><h4>GitHub Security Lab: CodeQL</h4><p>GitHub recently acquired <a href="https://semmle.com/">Semmle</a> and with it their query language QL. QL enables security researchers to write an abstract query for a given vulnerability and find all variations of that vulnerability across Open Source Software (OSS). Additionally, GitHub recently announced a new Open Source Bug Bounty Program which rewards researchers for submitting their queries. Semmle’s QL query language is evaluated against every new Open Source project on GitHub. The implications of this are that researchers can now create queries that will eliminate entire classes of vulnerabilities across the OSS ecosystem.</p><p>I recently contributed this simple QL query as a part of the new <a href="https://securitylab.github.com/">GitHub Security Lab Bug Bounty Program</a>. The submission to the Bug Bounty program can be found <a href="https://github.com/github/security-lab/issues/21">here</a>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/811ead26b624bad1f3fe61ab4e2852c5/href">https://medium.com/media/811ead26b624bad1f3fe61ab4e2852c5/href</a></iframe><p>This fairly simple query will detect and flag all POM.xml files that use HTTP or FTP. As soon as this query is merged and deployed, it will begin detecting this vulnerability in all future open source contributions to GitHub.</p><p>I highly recommend that all GitHub Repositories that haven’t applied the LGTM GitHub integration should do so <a href="https://github.com/marketplace/lgtm">here</a>!</p><figure><img alt="LGTM.com by Semmle logo" src="https://cdn-images-1.medium.com/max/1024/1*ChRiKtSB4zBwF00-7vj-Jg.png" /></figure><h4>Bounty!</h4><p>For the above query, the <a href="https://securitylab.github.com/">GitHub Security Lab</a> team was kind enough to award me with a $2,300 reward as a part of the ‘All for one, one for all’ program.</p><p>More information here: <a href="https://securitylab.github.com/bounties">GitHub Security Lab Bug Bounty Program</a>.</p><h3>What do I need to do?</h3><p>As a software developer, security engineer, or operations engineer, please proactively check your Maven, Gradle, SBT, Bazel, Buck, JFrog Artifactory and/or Sonatype Nexus configurations to ensure that your company or project won’t be impacted by this change on January 13th -15th, 2020.</p><p><em>Follow </em><a href="https://medium.com/bugbountywriteup"><em>Infosec Write-ups</em></a><em> for more such awesome write-ups.</em></p><p><a href="https://medium.com/bugbountywriteup">InfoSec Write-ups</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d069d253fe23" width="1" height="1" alt=""><hr><p><a href="https://infosecwriteups.com/update-want-to-take-over-the-java-ecosystem-all-you-need-is-a-mitm-d069d253fe23">Update: Want to take over the Java ecosystem? All you need is a MITM!</a> was originally published in <a href="https://infosecwriteups.com/">InfoSec Write-ups</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Need MDNS? Just Install iTunes]]></title>
            <link>https://medium.com/@jonathan.leitschuh/need-mdns-just-install-itunes-bdd84d7a2b45?source=rss-bbb358f1d950------2</link>
            <guid isPermaLink="false">https://medium.com/p/bdd84d7a2b45</guid>
            <category><![CDATA[funny]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[windows]]></category>
            <category><![CDATA[technology]]></category>
            <dc:creator><![CDATA[Jonathan Leitschuh]]></dc:creator>
            <pubDate>Wed, 09 Oct 2019 16:22:24 GMT</pubDate>
            <atom:updated>2019-10-09T16:22:24.173Z</atom:updated>
            <cc:license>http://creativecommons.org/licenses/by/4.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/259/1*ftRjUbYSopRMn9m_1CFSVA.jpeg" /></figure><p>Over 6 years ago I was working on a project called WPILib. WPILib is a library used by High School FIRST Robotics teams to program their robots. This particular year, the development team decided to use MDNS to resolve the IP address of the robot. When tested, everything worked for the devs so they moved forward with using it.</p><p>I joined the team at the beginning of the summer between my Sophomore and Junior year of college and was using a Mac for development. As the entire development environment only supported Windows I ended up setting up the dev environment in a Parallels VM.</p><p>At some point in the development process, I end up needing to deploy code to the robot. However, for me, it didn’t work.</p><p>After a lot of head-scratching, we finally narrowed it down. I was the only developer who hadn’t installed iTunes on their machine.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*JqAF00e0pMvACGinDZu1ug.png" /></figure><p>Why iTunes you may ask? As we quickly learned Windows doesn’t ship with MDNS support out of the box. Apparently, when you install iTunes, the installer also installed Bonjour printer services into your OS Networking Stack. Bonjour adds support for MDNS.</p><p>Needless to say, it was good that we caught this issue before the software was shipped to 4000 robotics teams.</p><p>Humorously, I suggested that we just document with something like:</p><blockquote>If you have problems uploading code to your robot, try installing iTunes.</blockquote><p>Funnily enough, this was actually the suggestion the team ended up pursuing. This is from the official FIRST Robotics Documentation for MDNS support:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/622/1*ekv4Rx0Ec-YCkgfeptimiA.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bdd84d7a2b45" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Zoom Zero Day: 4+ Million Webcams & maybe an RCE? Just get them to visit your website!]]></title>
            <link>https://infosecwriteups.com/zoom-zero-day-4-million-webcams-maybe-an-rce-just-get-them-to-visit-your-website-ac75c83f4ef5?source=rss-bbb358f1d950------2</link>
            <guid isPermaLink="false">https://medium.com/p/ac75c83f4ef5</guid>
            <category><![CDATA[software-security]]></category>
            <category><![CDATA[security]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[zoom]]></category>
            <dc:creator><![CDATA[Jonathan Leitschuh]]></dc:creator>
            <pubDate>Mon, 08 Jul 2019 19:10:59 GMT</pubDate>
            <atom:updated>2021-02-16T21:13:13.763Z</atom:updated>
            <cc:license>http://creativecommons.org/licenses/by/4.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/762/1*H5TvwgtzyNBvszjq2HG5mQ.png" /></figure><h4>A vulnerability in the Mac Zoom Client allows any malicious website to enable your camera without your permission. The flaw potentially exposes up to 750,000 companies around the world that use Zoom to conduct day-to-day business.</h4><h3>CVE-Numbers</h3><ul><li>DOS Vulnerability — Fixed in Client version 4.4.2 — <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-13449">CVE-2019–13449</a></li><li>Information Disclosure (Webcam) — Unfixed —<a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-13450">CVE-2019–13450</a></li></ul><h3>UPDATE — July 9th (am)</h3><p>As far as I can tell this vulnerability also impacts Ringcentral. Ringcentral for their web conference system is a white labeled Zoom system.</p><h3>UPDATE — July 9th (pm)</h3><p>According to Zoom, they will have a fix shipped by midnight tonight pacific time removing the hidden web server; hopefully this patches the most glaring parts of this vulnerability. The Zoom CEO has also assured us that they will be updating their application to further protect users privacy.</p><h3>UPDATE — July 15th</h3><p>If you have updated Zoom to the latest version, you are now greeted with this new UI confirming you would actually like to join the meeting.</p><h3>Jonathan Leitschuh on Twitter</h3><p>This new @zoom_us feature fully patches the #SecurityVulnerability where users were maliciously joined to a call without their permission. Doing this in a week is an example the kind of fast response times we want to see in a properly executed bug bounty program! Go Update!</p><h3>UPDATE — July 17th</h3><p>It has since <a href="https://blog.assetnote.io/bug-bounty/2019/07/17/rce-on-zoom/">come to light that Zoom and 13 of their white label applications contained a Remote Code Execution (RCE) vulnerability</a>. Zoom, RingCentral, Telus Meetings, BT Cloud Phone Meetings, Office Suite HD Meeting, AT&amp;T Video Meetings, BizConf, Huihui, UMeeting, Zhumu, Zoom CN, EarthLink Meeting Room, Video Conferencia Telmex, &amp; Accession Meeting. Apple has since silently removed these applications from your computer by utilizing MRT.</p><h3>Foreword</h3><p>This vulnerability allows any website to forcibly join a user to a Zoom call, with their video camera activated, without the user&#39;s permission.</p><p>On top of this, this vulnerability would have allowed any webpage to DOS (Denial of Service) a Mac by repeatedly joining a user to an invalid call.</p><p>Additionally, if you’ve ever installed the Zoom client and then uninstalled it, you still have a localhost web server on your machine that will happily re-install the Zoom client for you, without requiring any user interaction on your behalf besides visiting a webpage. This re-install ‘feature’ continues to work to this day.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*NxtGHcyetXURheZlHL6nBg.jpeg" /><figcaption>Yep, no joke.</figcaption></figure><p>This vulnerability leverages the amazingly simple Zoom feature where you can just send anyone a meeting link (for example https://zoom.us/j/492468757) and when they open that link in their browser their Zoom client is magically opened on their local machine. I was curious about how this amazing bit of functionality was implemented and how it had been implemented securely. Come to find out, it really hadn’t been implemented securely. Nor can I figure out a good way to do this that doesn’t require an additional bit of user interaction to be secure.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*8LgXSqGdxXuNvp7CqXtA_A.jpeg" /></figure><p>This vulnerability was originally responsibly disclosed on March 26, 2019. This initial report included a proposed description of a ‘quick fix’ Zoom could have implemented by simply changing their server logic. It took Zoom 10 days to confirm the vulnerability. The first actual meeting about how the vulnerability would be patched occurred on June 11th, 2019, only 18 days before the end of the 90-day public disclosure deadline. During this meeting, the details of the vulnerability were confirmed and Zoom’s planned solution was discussed. However, I was very easily able to spot and describe bypasses in their planned fix. At this point, Zoom was left with 18 days to resolve the vulnerability. On June 24th after 90 days of waiting, the last day before the public disclosure deadline, I discovered that Zoom had only implemented the ‘quick fix’ solution originally suggested.</p><p>Ultimately, Zoom failed at quickly confirming that the reported vulnerability actually existed and they failed at having a fix to the issue delivered to customers in a timely manner. An organization of this profile and with such a large user base should have been more proactive in protecting their users from attack.</p><h3>Timeline</h3><ul><li>Mar 8, 2019 — Requested security contact via Twitter (no response).</li><li>Mar 26, 2019 — Contacted Zoom Inc via email with 90-day public disclosure deadline. Offered a “quick fix” solution.</li><li>Mar 27, 2019<br>- Requested confirmation of reception.<br>- Informed that Zoom Security Engineer was Out of Office.<br>- Offered and declined a financial bounty for the report due to policy on not being able to publicly disclose even after the vulnerability was patched.</li><li>Apr 1, 2019 — Requested confirmation of vulnerability.</li><li>Apr 5, 2019 — Response from Zoom Security Engineer confirming and discussing severity. Settled on <a href="https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator?vector=AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:L">CVSSv3 score of 5.4/10</a>.</li><li>Apr 10, 2019 — Vulnerability disclosed to Chromium security team.</li><li>Apr 18, 2019 — Updated Zoom with the suggestion from Chromium team.</li><li>Apr 19, 2019 — Vulnerability disclosed to Mozilla FireFox security team.</li><li>Apr 26, 2019 — Video call with Mozilla and Zoom Security Teams<br>Disclosed details of impending DNS expiration.</li><li>June 7, 2019 —Email from Zoom about a video call to discuss fix.</li><li>June 11, 2019 — Video call with Zoom Security team about impending disclosure. Discussed how Zoom’s planned patch was incomplete.</li><li>June 20, 2019 — Contacted about having another video call with Zoom Security Team. Declined by me due to calendar conflicts.</li><li>June 21, 2019 — Zoom reports vulnerability was fixed.</li><li>June 24, 2019 — 90-day public disclosure deadline ends. Vulnerability confirmed fixed with ‘quick fix’ solution.</li><li>July 7, 2019 — Regression in the fix causes the video camera vulnerability to work again.</li><li>July 8, 2019<br>- Regression fixed.<br>- Workaround discovered &amp; disclosed.<br>- Public Disclosure.</li></ul><h3>Details</h3><p>On Mac, if you have ever installed Zoom, there is a web server on your local machine running on port 19421. You can confirm this server is present by running lsof -i :19421 in your terminal.</p><p>First off, let me start off by saying having an installed app that is running a web server on my local machine with a totally undocumented API feels incredibly sketchy to me. Secondly, the fact that any website that I visit can interact with this web server running on my machine is a huge red flag for me as a Security Researcher.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*onCQGWFAH40hSlRCYWtNvA.png" /><figcaption>Here’s the code on the Zoom site that tipped me off to this localhost server.</figcaption></figure><p>My original thoughts when I learned that this web server existed was that if there is a buffer overflow anywhere in the parameter handling of this web server, someone could achieve RCE on my machine. That’s not what I’ve found, but that was my original thought process.</p><p>If you look at what’s logged to the web developer console when visiting one of those Zoom ‘join’ links, you should see something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_9YBpfb-SSLJC853rJy_FQ.png" /><figcaption>Browser console logs when visiting <a href="https://zoom.us/j/492468757">https://zoom.us/j/492468757</a></figcaption></figure><p>I also found that, instead of making a regular AJAX request, this page instead loads an image from the Zoom web server that is locally running. The different dimensions of the image dictate the error/status code of the server. You can see that case-switch logic here.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/770/1*WQVa9HEeQvh0yAMxMMy1vg.png" /><figcaption>The two numbers are the pixel dimensions of the image returned by the web server.</figcaption></figure><p>The scary thing is that this enum seemed to indicate that this web server can do far more than just launch a Zoom meeting. What I found out was that this web server can also re-install the Zoom app if a user has uninstalled it, more on that later.</p><p>One question I asked is, why is this web server returning this data encoded in the dimensions of an image file? The reason is, it’s done to bypass <a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing">Cross-Origin Resource Sharing (CORS)</a>. For very intentional reasons, the browser explicitly ignores any CORS policy for servers running on localhost.</p><blockquote>Chrome <a href="http://code.google.com/p/chromium/issues/detail?id=67743">does not support localhost for CORS requests</a> (an open bug since 2010).<br>- <a href="https://stackoverflow.com/questions/10883211/deadly-cors-when-http-localhost-is-the-origin">https://stackoverflow.com/questions/10883211/deadly-cors-when-http-localhost-is-the-origin</a></blockquote><p>I’m guessing that this is intentionally done for security reasons. Regardless, it seems that Zoom is abusing a hack to bypass CORS protection. More on that later.</p><h4>The Video Call Vulnerability</h4><p>I created a personal meeting with a different account and cracked open <a href="https://www.getpostman.com/">Postman</a> and started to remove parameters to see what the minimal GET request was that was required to launch a Zoom meeting.</p><p>There are a lot of random parameters that are sent to the localhost web server but the only ones that seem to matter are the following.</p><ul><li>action=join</li><li>confno=[whatever the conference number is]</li></ul><p>Using the following GET request from Postman I was successfully able to get my computer to join the Zoom call that the other account had created.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/00fb45946c1011778fcaa93c36c9e07d/href">https://medium.com/media/00fb45946c1011778fcaa93c36c9e07d/href</a></iframe><p>Once I had this, I started tinkering with what other “action” parameters I might be able to pass to get the client to do other things. I wasn’t able to find anything even after searching through the various public documents and the public ProtoBuff schema for hints about what hidden functionality may exist. Again, this webserver’s API is completely undocumented as far as I can tell and I’ve spent several hours searching for any mention of this Desktop web server in the official and unofficial documentation.</p><p>So now I had a minimal POC that I could use to maliciously get any user into a call, however, the default setting for the “New Meeting” is to allow the user to choose whether to join their Audio/Video. <strong>I would consider this alone a security vulnerability.</strong></p><blockquote>The above-described behavior continues to work to this day! You can still use this exploit to launch someone into a call without their permission.</blockquote><p>I read about the <a href="https://www.tenable.com/blog/tenable-research-advisory-zoom-unauthorized-command-execution-cve-2018-15715">Tenable Remote Code Execution in Zoom security vulnerability</a> which was only patched within the last 6 months. Had the Tenable vulnerability been combined with this vulnerability it would have allowed RCE against any computer with the Zoom Mac client installed. If a similar future vulnerability were to be found, it would allow any website on the internet to achieve RCE on the user’s machine.</p><p>I advised Zoom that if they have any users that are still using Zoom 4.1.33259.0925 versions or lower, this would be a very potent attack.</p><p>So far, I could only achieve getting a user into a call without their permission. Although this has hypothetical security implications, I didn’t have a true exploit. I started tinkering with figuring out how to get someone’s camera activated. When setting up a meeting for work I was greeted with this screen.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3v6fVs6FM39EDWQUBK2s4w.png" /><figcaption>You can choose to enable a participant’s video camera when they join the call.</figcaption></figure><p>Enabling “Participants: On” when setting up a meeting, I discovered that anyone joining my meeting automatically had their video connected.</p><p>When I got back to my personal machine, I tried this same functionality and found that it worked exactly the same.</p><p>This prompted me to create the Proof Of Concept below.</p><p><strong>Proof Of Concept</strong></p><p>The local client Zoom web server is running as a background process, so to exploit this, a user doesn’t even need to be “running” (in the traditional sense) the Zoom app to be vulnerable.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8b574480eb7c4f7ec15dd9d3e8856561/href">https://medium.com/media/8b574480eb7c4f7ec15dd9d3e8856561/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/edad74c3b0f4cdce82c1f35e845ff7da/href">https://medium.com/media/edad74c3b0f4cdce82c1f35e845ff7da/href</a></iframe><p>All a website would need to do is embed the above in their website and any Zoom user will be instantly connected with their video running. <strong>This is still true today!</strong></p><p>This could be embedded in malicious ads, or it could be used as a part of a phishing campaign. If I were actually an attacker, I’d probably invest some time to also include the incrementing port logic that the code in the Javascript running on Zoom’s site.</p><p>A fully working POC that you can test out yourself can be found at the link below. <strong>Warning:</strong> Clicking this link on Mac will launch you into a Zoom call!<br><a href="https://jlleitschuh.org/zoom_vulnerability_poc/">https://jlleitschuh.org/zoom_vulnerability_poc/</a></p><p>A fully working POC that will launch you into a call <strong>with your video camera</strong> active can be found here. <strong>Warning:</strong> Clicking this link on Mac will launch you into a Zoom call with your camera activated!<br><a href="https://jlleitschuh.org/zoom_vulnerability_poc/zoompwn_iframe.html">https://jlleitschuh.org/zoom_vulnerability_poc/zoompwn_iframe.html</a></p><p><strong>Quick Fix</strong></p><p>To fix the “auto join with video” part of the vulnerability, I advised Zoom on their backend server they immediately disable a meeting creator’s ability to automatically enable a participants video by default. I advised that this was 100%, not a complete fix. However, it could serve as a quick way to protect users from the invasion of privacy component of this attack.</p><p>I also advised that if there is hidden functionality where a meeting host can forcibly join computer audio (perhaps something I’m not seeing because I don’t have a Pro account), this should also be disabled.</p><p>I commented that allowing a host to choose whether or not a participant will automatically join with video should be considered it’s own standalone security vulnerability.</p><p>To this advisement, I received the following response:</p><blockquote>Zoom believes in giving our customers the power to choose how they want to Zoom. This includes whether they want a seamless experience in joining a meeting with microphone and video automatically enabled, or if they want to manually enable these input devices after joining a meeting. Such configuration options are available in the Zoom Meeting client audio and video settings.</blockquote><blockquote>However, we also recognize the desire by some customers to have a confirmation dialog before joining a meeting. Based on your recommendations and feature requests from other customers, the Zoomteam [sic] is evaluating options for such a feature, as well as additional account level controls over user input device settings. We will be sure to keep you informed of our plans in this regard.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/327/1*tddZfct2aM81-INpdhuKKw.jpeg" /><figcaption>When responding to responsible disclosure, don’t go into PR spin mode. It’s counterproductive.</figcaption></figure><p>It’s important to note that the default configuration for Zoom is to allow a host to choose whether or not your camera is enabled or not by default.</p><p>Zoom did end up patching this vulnerability, but all they did was prevent the attacker from turning on the user’s video camera. They did not disable the ability for an attacker to forcibly join to a call anyone visiting a malicious site.</p><p>UPDATE: July 7th, 2019: There has been a regression in the fix implemented by Zoom thus allowing this vulnerability to be exploited with the video camera activated.</p><h4>The Denial Of Service (DOS) Vulnerability</h4><p>This same vulnerability also allowed the attacker to DOS any user’s machine. By simply sending repeated GET requests for a bad number, Zoom app would constantly request ‘focus’ from the OS. The following simple POC demonstrated this vulnerability.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/91aa7abdf6638c58365ca8db6c2a3541/href">https://medium.com/media/91aa7abdf6638c58365ca8db6c2a3541/href</a></iframe><p>This DOS vulnerability was patched in version 4.4.2 of the Zoom client.</p><h4>The Install Vulnerability</h4><p>If you have ever installed Zoom on your computer, this web server is installed. It continues to run if you uninstall Zoom from your computer.</p><p>This server also supports updating and installing a new version of Zoom in addition to launching a call. I did some additional decompilation of the Zoom web server to see the code path that these endpoints seemed to call.</p><p>Using Hopper Disassembler to disassemble the Objective-C bytecode of the web server I found the following method.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*V8lYFZILR9vRMnqhoVcqXA.png" /><figcaption>Takes arguments from some API request and uses it to craft a download URL used to upgrade the version of Zoom installed?</figcaption></figure><p>This method is gated by the following logic.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SlvQLTUQWSTq2UC9QcYgjA.png" /><figcaption>Ensures the download URL is only under ‘trusted’ subdomains.</figcaption></figure><p>One of the API’s inside of this web server running on all Macs with Zoom installed is an endpoint that allows the current version of Zoom that’s installed to be updated or re-installed by this server.</p><p>You can confirm that this logic does indeed exist by doing the following:</p><ol><li>Install the Zoom client on your computer if you don’t already have it installed.</li><li>Open the Zoom client, then shut it down.</li><li>Uninstall the Zoom client from your computer by dragging the Applications/zoom.us.app file to the trash.</li><li>Open any Zoom join link and Zoom will ‘helpfully’ be re-installed for you in the Applications folder and will be launched by this web server.</li></ol><p>Using the list of domains listed inside of the application that could be used to download updates for the Zoom app, I decided to check and see what each of the sites returned when visited. For example, here’s the result of visiting <a href="https://zipow.com/upgrade?os=mac">https://zipow.com/upgrade?os=mac</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xqa1K1tcmLgMArM_xq8IDw.png" /><figcaption>You can clearly see the URL to be used to download the zoom installer if Zoom needs to be re-installed.</figcaption></figure><p>Doing a whois lookup on all of the domains listed in the source code returned some interesting results. For example, the domain zoomgov.com was scheduled to expire on May 1st, 2019. Had this domain registration been allowed to lapse, the takeover of this domain would have allowed an attacker to host an infected version of the Zoom installer from this site and infected users who had uninstalled Zoom from their computers. Essentially, this would have made this vulnerability a Remote Code Execution (RCE) vulnerability. I disclosed this bit of information to the Zoom team during my call with the Mozilla security team on April 26th, 2019. Within 5 hours of the end of that call that domain had been registered out to May 1st, 2024.</p><h4>Fundamental Security Vulnerability</h4><p>In my opinion, websites should not be talking to Desktop applications like this. There is a fundamental sandbox that browsers are supposed to enforce to prevent malicious code from being executed on users machines.</p><p>Having every Zoom user have a web server that accepts HTTP GET requests that trigger code outside of the browser sandbox is painting a huge target on the back of Zoom. It’s important to note that if you try to pull off the same exploit directly with a Javascript AJAX request, you are greeted with the following exception.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2d-_-FY6CANFap6hBOCIlQ.png" /><figcaption>All localhost request from Javascript are forbidden by browsers.</figcaption></figure><p><strong>CORS-RFC1918</strong></p><p>In discussing this vulnerability with both the Chromium and Mozilla Firefox security team they both said that they couldn’t do anything about this vulnerability. The Chromium team pointed me to <a href="https://wicg.github.io/cors-rfc1918/">CORS-RFC1918</a> which is a proposal that will require browser vendors to query users for permission before allowing sites to make requests against local resources like localhost and the 192.168.1.* address space.</p><p>Linked in that RFC is a wonderful and fun to read bug report where Tavis Ormandy of Google’s Project Zero found a similar vulnerability in TrendMicro’s Password Manager allowing remote code execution via the browser and the exfiltration of a user’s passwords from a password vault. <a href="https://bugs.chromium.org/p/project-zero/issues/detail?id=693&amp;redir=1">That story is well worth the read</a>.</p><p>When this same vulnerability was reported to the Mozilla Firefox team, they closed it as it wasn’t considered a vulnerability against Firefox. However, they soon reopened the report as a vulnerability against their internal infrastructure. As a result, I was invited into a call with the Zoom and Mozilla Firefox team to discuss the vulnerability on April 26th, 2019. During this call, they promised Mozilla and me that this vulnerability would be patched well before the end of the 90-day disclosure deadline. This turned out to be false.</p><h3>Zoom’s Proposed Fixes</h3><p>The fix proposed by the Zoom team was to digitally ‘sign’ the request made to the client. However, this simply means that an attacker would have to have a backend server that makes requests to the Zoom site first to gain a valid signature before forwarding the signature on to the client.</p><p>They also proposed locking the signature to the IP that made the request. This would mean that as long as the attacker’s server was behind the same NAT router as the victim, the attack would still work.</p><p>I described to the Zoom team how both of these solutions were not enough to fully protect their users. Unfortunately, this left the Zoom team with only 18 days before public disclosure to come up with some better solution.</p><p>Unfortunately, even after my warning, this was the solution they chose to go with. This new signature or token is embedded in a new parameter called confid. The simplest way to bypass this new confid check was to simply use the iframe workaround described above. Alternatively, if you and the victim are behind the same NAT router, you can make a request for the join page, extract the #lhs_launch_parames field from the HTML document and embed it in the HTML response from the malicious page.</p><h3>Conclusion</h3><p>As of 2015 <a href="https://www.globenewswire.com/news-release/2015/02/04/1130354/0/en/Zoom-Raises-30M-in-Series-C-Funding-Led-by-Emergence-Capital.html">Zoom had over 40 million users</a>. Given that Macs are 10% of the PC market and Zoom has had significant growth since 2015 we can assume that at least 4 million of Zoom’s users are on Mac. Tools like Zoom, Google Meet or Skype for Business is a staple of today&#39;s modern office.</p><p>Any vulnerability in an application with this many users must be considered a serious threat to all those users. All of the vulnerabilities described in this report can be exploited via <a href="https://attack.mitre.org/techniques/T1189/">“drive-by attack” methodologies</a>. Many times during my conversation with the Zoom security team they seemed to argue that the seriousness of this vulnerability was limited because it would require “user interaction” to exploit these. My response to this was finally “I would highly suggest that you not hang your hat on ‘user interaction required’ for protecting your users given that this ‘user interaction’ is simply clicking a link or visiting a webpage.”</p><p>I believe that in order to fully protect users, I truly believe that this localhost web server solution needs to be removed. Alternative methodologies like registering custom URI handlers (for example, a zoom:// URI handler) with the browsers is a more secure solution. When these URI handlers are triggered, the browser explicitly prompts the user for confirmation about opening the app. According to the Zoom team, the only reason this localhost server continues to exist is that Apple’s Safari doesn’t support URI handlers.</p><h3>Consequences</h3><p>This is essentially a Zero Day. Unfortunately, Zoom has not fixed this vulnerability in the allotted 90-day disclosure window I gave them, as is the industry standard. As such, the 4+ million users of Zoom on Mac are now vulnerable to an invasion of their privacy by using this service.</p><p>Additionally, due to a lack of sufficient auto-update capabilities, many users continue to run outdated versions of Zoom for months after new releases are shipped leaving them vulnerable to exploits like these.</p><h3>Patch Yourself</h3><p>If you want to patch this vulnerability for yourself you can do the following.<br>Disable the ability for Zoom to turn on your webcam when joining a meeting.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mRgy9JoJKkjSRp-xjSYomw.png" /></figure><p>Alternatively, use this terminal command.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0a2bb0e99024f64d8686b2faaf84e2ba/href">https://medium.com/media/0a2bb0e99024f64d8686b2faaf84e2ba/href</a></iframe><p>To shut down the web server, run lsof -i :19421 to get the PID of the process, then do kill -9 [process number]. Then you can delete the ~/.zoomus directory to remove the web server application files.</p><p>To prevent this server from being restored after updates you can execute the following in your terminal:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b827a7dcf0c5567fc5623987eb94c539/href">https://medium.com/media/b827a7dcf0c5567fc5623987eb94c539/href</a></iframe><p>If you want a full description of how to resolve this on Windows and Mac see the Gist below.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4ebe95952cf77ce6ada76e45c0a8ea60/href">https://medium.com/media/4ebe95952cf77ce6ada76e45c0a8ea60/href</a></iframe><h3>Notes For Researchers</h3><p>Given the massive install base for Zoom, I highly recommend that other researchers take the time to explore this Zoom web server to see what other vulnerabilities exist. This being said, I also recommend that any researcher that finds a vulnerability in Zoom’s software <strong>does not directly report the vulnerability to Zoom</strong>. Instead, I recommend that researchers report these vulnerabilities via the <a href="https://www.zerodayinitiative.com/">Zero Day Initiative (ZDI)</a>. The ZDI disclosure program gives vendors 120 days to resolve the vulnerability, the ZDI will pay researchers for their work, and researchers have the ability to publicly disclose their findings.</p><p>If you want to decompile the Zoom client application for yourself, it’s located in the ~/.zoomus directory on your computer.</p><p>The source code repository for my POC examples <a href="https://github.com/JLLeitschuh/zoom_vulnerability_poc">can be found on GitHub</a>.</p><h4>If you enjoyed this story, please click the 👏 button and share to help others find it. Feel free to leave a comment!</h4><p>Did this research &amp; writeup help you or your company? Consider sponsoring me by donating to my <a href="https://paypal.me/JLLeitschuh">college loan repayment fund</a>. Every bit helps.</p><p><em>Follow </em><a href="https://medium.com/bugbountywriteup"><em>Infosec Write-ups </em></a><em>for more such awesome write-ups.</em></p><p><a href="https://medium.com/bugbountywriteup">InfoSec Write-ups</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ac75c83f4ef5" width="1" height="1" alt=""><hr><p><a href="https://infosecwriteups.com/zoom-zero-day-4-million-webcams-maybe-an-rce-just-get-them-to-visit-your-website-ac75c83f4ef5">Zoom Zero Day: 4+ Million Webcams &amp; maybe an RCE? Just get them to visit your website!</a> was originally published in <a href="https://infosecwriteups.com/">InfoSec Write-ups</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>