← Back
JetBrains TV October 15, 2026 40m

Building a Supply Chain Attack With .NET and NuGet | Maarten Balliauw | .NET Day 2026

Read full transcript 34 segments
  1. How are you, Matthias? Um , how is your day, are you , how is your day, are you , how is your day, are you okay so far? okay so far? okay so far? So far so good. So far so good. So far so good. For now, well, right now For now, well, right now For now, well, right now I'm really interested in I'm really interested in I'm really interested in hearing hearing hearing Martin's performance. I have to say Martin's performance. I have to say . . . I was just about to I was just about to I was just about to say that the day is say that the day is say that the day is going well. So going well. So going well. So let's invite let's invite let's invite Martin and see Martin and see Martin and see what he can what he can what he can do about it. Our friend, do about it. Our friend, do about it. Our friend, Martin, hello. How are you Martin, hello. How are you Martin, hello. How are you ? ? ? Greetings. Hello, I'm Greetings. Hello, I'm Greetings. Hello, I'm fine, thank you. Hmm, fine, thank you. Hmm, fine, thank you. Hmm, everything is fine. How are you everything is fine. How are you everything is fine. How are you ? ? ? Hello, Mr. Robert. Hello, Mr. Robert. Hello, Mr. Robert. We are all well. We are all well. We are all well. Always happy to see Always happy to see Always happy to see you, Martin. We are glad you, Martin. We are glad that you are with us again. And it that you are with us again. And it that you are with us again. And it seems like today you're going to seems like today you're going to seems like today you're going to tell us about NuGet tell us about NuGet tell us about NuGet and supply chain attacks and supply chain attacks and supply chain attacks . Evil . Evil . Evil Martin. Martin. Martin. Yes, I really Yes, I really Yes, I really hope to hope to hope to scare everyone with this scare everyone with this scare everyone with this performance. performance. performance. Fantasy. Well, we're Fantasy. Well, we're Fantasy. Well, we're seeing your slides, and, seeing your slides, and, seeing your slides, and, um, there's no better time than um, there's no better time than um, there's no better time than now. So, now. So, now. So, go ahead, Martin. go ahead, Martin. Good. Greetings to everyone. Good. Greetings to everyone. Welcome to the Welcome to the .NET Day online conference. We'll .NET Day online conference. We'll .NET Day online conference. We'll talk about talk about talk about creating a creating a creating a supply chain attack supply chain attack supply chain attack using .NET and NuGet. I am using .NET and NuGet. I am using .NET and NuGet. I am Martin. I work at Duende Martin. I work at Duende Martin. I work at Duende Software, the guys also Software, the guys also Software, the guys also develop IdentityServer. develop IdentityServer.

  2. develop IdentityServer. My day My day My day job is not about job is not about job is not about creating creating creating supply chain attacks supply chain attacks supply chain attacks or security. But at or security. But at or security. But at some point, and we'll some point, and we'll some point, and we'll touch on this touch on this touch on this during the talk, I during the talk, I during the talk, I was looking at NuGet and .NET and I was looking at NuGet and .NET and I was looking at NuGet and .NET and I thought, "What's thought, "What's thought, "What's happening in NPM with happening in NPM with happening in NPM with the frequency and type of the frequency and type of the frequency and type of attacks could happen in attacks could happen in attacks could happen in .NET." And as a curious .NET." And as a curious .NET." And as a curious developer, I started developer, I started developer, I started looking and actually looking and actually looking and actually found some very found some very found some very interesting things. So, interesting things. So, interesting things. So, let's dive into let's dive into let's dive into it. Before we it. Before we it. Before we begin, let's begin, let's begin, let's quickly make sure quickly make sure we all have the same we all have the same we all have the same understanding of what a understanding of what a software supply chain attack is. A software supply chain attack is. A supply chain attack supply chain attack is when an attacker is when an attacker is when an attacker attacks elements in the attacks elements in the software supply chain. This could software supply chain. This could be someone be someone be someone trying to trying to trying to infiltrate the infiltrate the infiltrate the dependencies you dependencies you dependencies you use or the use or the use or the tools you tools you tools you use to use to use to inject malicious inject malicious inject malicious code into a product you code into a product you may be delivering to may be delivering to may be delivering to your customers. This your customers. This your customers. This could be related to could be related to could be related to data theft, data theft, ransomware, system control, system control, anything. There are enough anything. There are enough anything. There are enough examples of what is examples of what is examples of what is happening there.

  3. happening there. happening there. So the idea is not So the idea is not So the idea is not to directly attack to directly attack to directly attack customers or to customers or to customers or to target target target anyone directly anyone directly , but to , but to , but to infiltrate the infiltrate the infiltrate the supply chain, supply chain, supply chain, into software into software into software tools and all tools and all tools and all that, and that, and that, and make sure that you make sure that you make sure that you can can can infiltrate the infiltrate the infiltrate the end-user systems that way. end-user systems that way. end-user systems that way. Very often this is Very often this is Very often this is called or called or called or done done done using a " using a " sleeper agent" approach, sleeper agent" approach, sleeper agent" approach, where someone where someone where someone introduces something introduces something introduces something somewhere. They have a lot of somewhere. They have a lot of somewhere. They have a lot of patience, and it may not be until a patience, and it may not be until a patience, and it may not be until a year after the year after the year after the initial attack that the initial attack that the attack itself begins. This is usually what attack itself begins. This is usually what you see during a you see during a supply chain attack. A very supply chain attack. A very good example of a good example of a good example of a sophisticated and successful sophisticated and successful supply chain attack was the supply chain attack was the Shah Hoolut attack on NPM. Shah Hoolut attack on NPM. The idea was The idea was that an attacker that an attacker that an attacker compromised compromised compromised several packages on NPM, the several packages on NPM, the several packages on NPM, the package manager package manager package manager for the Node.js world. Several for the Node.js world. Several for the Node.js world. Several packages, over 500 packages, over 500 packages, over 500 infected packages, infected packages, infected packages, and the idea was to and the idea was to run a script in these infected packages run a script in these infected packages every time someone every time someone every time someone installed the package. So installed the package. So installed the package. So "bun environment.js" was "bun environment.js" was "bun environment.js" was part of that. These part of that. These part of that. These packages packages packages were installed on were installed on developer computers and on CI runners. What happened: runners. What happened: runners. What happened: The developers secretly The developers secretly The developers secretly embedded this “bun embedded this “bun embedded this “bun environment.js,” a malicious environment.js,” a malicious environment.js,” a malicious payload, into payload, into payload, into their dependencies as well. At the their dependencies as well. At the their dependencies as well. At the same time, it same time, it same time, it configured the CI configured the CI runner on your runner on your runner on your system so that system so that system so that an attacker could an attacker could an attacker could post something on the post something on the GitHub discussion forum to then GitHub discussion forum to then run CI builds on run CI builds on run CI builds on your system and your system and your system and force it to force it to force it to execute any

  4. execute any execute any command. A few other command. A few other command. A few other things, like a "wiper" ( things, like a "wiper" ( data eraser): if data eraser): if data eraser): if you detected this you detected this you detected this component, it wiped component, it wiped component, it wiped your system. There was your system. There was your system. There was also spread also spread also spread through publishing through publishing through publishing new NPM packages if new NPM packages if new NPM packages if it found it found it found credentials on credentials on credentials on your machine. The idea of your machine. The idea of your machine. The idea of this attack was to this attack was to this attack was to steal steal steal secrets like secrets like secrets like AWS passwords, Azure passwords, AWS passwords, Azure passwords, AWS passwords, Azure passwords, tokens and all that kind of stuff tokens and all that kind of stuff to gain access to gain access to gain access and do even more and do even more and do even more interesting things as an interesting things as an interesting things as an attacker. If attacker. If attacker. If you look at this you look at this you look at this slide and this attack, slide and this attack, slide and this attack, you can see that you can see that supply chain attacks and supply chain attacks and similar malware similar malware similar malware usually have usually have usually have multiple components. multiple components. multiple components. First of all, it is a dropper First of all, it is a dropper — the initial code — the initial code — the initial code that is executed on the that is executed on the that is executed on the victim's machine. It victim's machine. It victim's machine. It should be as should be as should be as hidden as possible and, in essence, hidden as possible and, in essence, hidden as possible and, in essence, provide a springboard provide a springboard provide a springboard for further actions. for further actions. for further actions. Next is the Next is the Next is the payload, when payload, when payload, when the dropper launches it the dropper launches it the dropper launches it and performs actions, which are and performs actions, which are and performs actions, which are very often very often very often received through the received through the received through the command center (C2). command center (C2). command center (C2). This is a This is a This is a command and command and command and control infrastructure where the C2 control infrastructure where the C2 infrastructure can infrastructure can infrastructure can give instructions, give instructions, give instructions, say, to collect say, to collect say, to collect environment variables, environment variables, environment variables, view certain view certain view certain files, perhaps files, perhaps files, perhaps perform a network perform a network perform a network scan, scan, scan, invoke commands, invoke commands, invoke commands, etc. And of course, as etc. And of course, as etc. And of course, as an attacker, you an attacker, you an attacker, you need a C2 need a C2 infrastructure where you infrastructure where you infrastructure where you can, well, can, well, can, well, place place place the instructions and the instructions and the instructions and payloads payloads that that your malware will use.

  5. There are many different There are many different vectors, as we vectors, as we vectors, as we will see later. will see later. will see later. You can usually You can usually You can usually access the access the access the source code of the source code of the source code of the project you project you project you want to infect, want to infect, want to infect, their CI system, their their CI system, their their CI system, their build system, etc. build system, etc. build system, etc. Very often this Very often this Very often this happens through happens through happens through social engineering, social engineering, social engineering, pull pull pull requests, or stealing the requests, or stealing the maintainer's account details maintainer's account details so we can just so we can just so we can just insert the code and be insert the code and be insert the code and be done with it. There are a done with it. There are a done with it. There are a few other vectors, few other vectors, few other vectors, such as such as such as dependency dependency dependency confusion, when you confusion, when you confusion, when you publish packages publish packages publish packages that should be that should be that should be private to a private to a private to a public registry. We'll public registry. We'll public registry. We'll see how this see how this see how this works in NuGet, but it's a works in NuGet, but it's a works in NuGet, but it's a very successful very successful very successful attack vector or attack vector or attack vector or infection vector. There is infection vector. There is infection vector. There is also typosquatting also typosquatting . Imagine that you . Imagine that you . Imagine that you publish Newtonsoft.Json publish Newtonsoft.Json publish Newtonsoft.Json or Microsoft.EntityFrameworkCore, or Microsoft.EntityFrameworkCore, or Microsoft.EntityFrameworkCore, where the letter "I" is not a where the letter "I" is not a where the letter "I" is not a real "I", but a real "I", but a real "I", but a Ukrainian "i" with a Ukrainian "i" with a Ukrainian "i" with a dot, which should not be dot, which should not be dot, which should not be confused with the usual one. confused with the usual one. confused with the usual one. So, there are several So, there are several So, there are several ways you can ways you can ways you can trick people into trick people into trick people into installing installing installing certain packages in NuGet. certain packages in NuGet. certain packages in NuGet. Now let's begin. Now let's begin. Now let's begin. Dependency swapping, Dependency swapping, Dependency swapping, typosquatting—.NET typosquatting—.NET typosquatting—.NET is protected against this, is protected against this, is protected against this, right? Well, I'll right? Well, I'll right? Well, I'll show you that's not show you that's not show you that's not true. Let's start by true. Let's start by true. Let's start by swapping dependencies.

  6. swapping dependencies. swapping dependencies. Typically, when you Typically, when you Typically, when you install a package install a package install a package or restore or restore or restore packages in NuGet, you packages in NuGet, you packages in NuGet, you see that NuGet see that NuGet see that NuGet checks all the checks all the checks all the package sources that are package sources that are package sources that are configured on your configured on your configured on your system. This is not system. This is not system. This is not deterministic. deterministic. deterministic. Essentially, Essentially, Essentially, whoever answers whoever answers whoever answers first wins. And since first wins. And since first wins. And since nuget.org is a very nuget.org is a very nuget.org is a very fast CDN-based NuGet server fast CDN-based NuGet server fast CDN-based NuGet server , very often the , very often the , very often the package package package will be downloaded from it will be downloaded from it will be downloaded from it first. So, as first. So, as first. So, as good developers, we good developers, we good developers, we all have the all have the all have the companyname.theframework package in a companyname.theframework package in a companyname.theframework package in a private feed. If private feed. If private feed. If I know your company, I know your company, I know your company, there's a good chance there's a good chance there's a good chance I can I can I can publish such a publish such a publish such a package to nuget.org, and there's package to nuget.org, and there's package to nuget.org, and there's a good chance a good chance a good chance people in your people in your people in your organization organization organization will download my will download my will download my version from nuget.org simply version from nuget.org simply version from nuget.org simply because it's faster because it's faster because it's faster than your internal NuGet than your internal NuGet server. So, that's a server. So, that's a server. So, that's a good way to good way to good way to work with it. To work with it. To work with it. To protect yourself from protect yourself from protect yourself from this, you can this, you can this, you can use use package source package source mapping. So the idea mapping. So the idea mapping. So the idea is that in is that in is that in your nuget.config you your nuget.config you your nuget.config you can add different can add different can add different package sources, package sources, package sources, such as internal, such as internal, such as internal, public, etc. But you public, etc. But you public, etc. But you can configure can configure can configure NuGet to NuGet to NuGet to always always always use nuget.org use nuget.org use nuget.org for all packages for all packages for all packages except internal ones that except internal ones that except internal ones that start with a start with a start with a specific pattern, such as specific pattern, such as " " company_name.whatever company_name.whatever ". You can ". You can ". You can point them to your point them to your point them to your internal NuGet server internal NuGet server internal NuGet server and always and always and always download from there download from there , ignoring nuget.org for , ignoring nuget.org for , ignoring nuget.org for those specific those specific those specific packages. Another packages. Another packages. Another approach to overcome approach to overcome approach to overcome this dependency confusion is this dependency confusion is to use to use package signing and package signing and package signing and verification. Typically,

  7. verification. Typically, verification. Typically, when you publish a when you publish a when you publish a package, you can package, you can package, you can sign it sign it sign it with a timestamp with a timestamp with a timestamp and certificates and certificates and certificates that you own. And that you own. And that you own. And as a NuGet user, you as a NuGet user, you as a NuGet user, you can tell or can tell or can tell or instruct NuGet how exactly instruct NuGet how exactly instruct NuGet how exactly you want to trust you want to trust you want to trust existing packages. existing packages. existing packages. So you can say, So you can say, "Okay, I trust "Okay, I trust "Okay, I trust all the packages that all the packages that all the packages that are in a are in a are in a particular NuGet channel." " particular NuGet channel." " I trust all I trust all I trust all packages from a specific packages from a specific packages from a specific author or owner." author or owner." author or owner." And that's all. And that's all. By setting this up, you By setting this up, you ensure that if ensure that if ensure that if someone else someone else someone else publishes acmecorp.framework publishes acmecorp.framework publishes acmecorp.framework and doesn't have the and doesn't have the and doesn't have the same signature, NuGet will same signature, NuGet will same signature, NuGet will simply throw simply throw simply throw an error because the an error because the an error because the signature doesn't match what you signature doesn't match what you signature doesn't match what you expected, since you expected, since you expected, since you specified that a specific signature specified that a specific signature specified that a specific signature must be present for that author must be present for that author . Another thing . Another thing you can do you can do to avoid to avoid to avoid confusion with confusion with confusion with dependencies, dependencies, dependencies, especially with especially with especially with internal internal internal company packages, is to company packages, is to company packages, is to register register register your your your private package ID prefix on private package ID prefix on private package ID prefix on nuget.org. Even if you nuget.org. Even if you nuget.org. Even if you don't plan to don't plan to don't plan to use use use nuget.org to nuget.org to nuget.org to download download download your company's packages, you your company's packages, you your company's packages, you can still go can still go can still go to nuget.org and to nuget.org and to nuget.org and register " register " company_name.whatever company_name.whatever " as a package prefix " as a package prefix " as a package prefix so that no one else so that no one else so that no one else can download can download can download packages with that packages with that packages with that prefix. So be prefix. So be prefix. So be sure to pay sure to pay sure to pay attention to this. So, we attention to this. So, we attention to this. So, we have considered these have considered these have considered these protection methods: protection methods: package source mapping, package source mapping, package signing, and package signing, and package ID prefix registration. There's another package ID prefix registration. There's another way, similar to NPM way, similar to NPM : you can create a : you can create a : you can create a lock file lock file lock file in NuGet, where you say, in NuGet, where you say, in NuGet, where you say, "I'm going to create a file "I'm going to create a file "I'm going to create a file that says: for

  8. that says: for that says: for this dependency, I'm this dependency, I'm this dependency, I'm using this using this using this package from this package from this package from this source with this hash source with this hash source with this hash and everything else." And then and everything else." And then and everything else." And then tell NuGet to always tell NuGet to always tell NuGet to always check this check this check this lock file lock file lock file when restoring when restoring when restoring packages. And if there's a packages. And if there's a packages. And if there's a package there that doesn't package there that doesn't package there that doesn't match what match what match what was was was previously installed, you can previously installed, you can previously installed, you can configure NuGet configure NuGet configure NuGet to reject to reject to reject restoring the package at restoring the package at restoring the package at that point. Okay, that point. Okay, that point. Okay, one more. This is the most interesting one more. This is the most interesting . Sometime in early . Sometime in early 2025, I was playing around and 2025, I was playing around and 2025, I was playing around and saw a tweet from Nick saw a tweet from Nick saw a tweet from Nick Chapsas, and yes, I'll Chapsas, and yes, I'll Chapsas, and yes, I'll say "tweet" because say "tweet" because say "tweet" because I refuse to I refuse to I refuse to use any other use any other use any other words. He wrote something words. He wrote something words. He wrote something about publishing about publishing about publishing Microsoft.Extensions.AutoMapper in Microsoft.Extensions.AutoMapper in Microsoft.Extensions.AutoMapper in response to response to response to Jimmy Bogard's actions with AutoMapper Jimmy Bogard's actions with AutoMapper Jimmy Bogard's actions with AutoMapper and so on. I was and so on. I was and so on. I was bored, and I thought: bored, and I thought: bored, and I thought: what if I download a what if I download a what if I download a package with this package with this package with this Ukrainian letter Ukrainian letter Ukrainian letter "i" in the name? So I "i" in the name? So I "i" in the name? So I found a list of found a list of found a list of all sorts of all sorts of all sorts of Unicode characters to compare them Unicode characters to compare them Unicode characters to compare them to the regular font to the regular font to the regular font on the system. There are a lot of them there on the system. There are a lot of them there on the system. There are a lot of them there . And I . And I . And I downloaded a package called downloaded a package called Microsoft.Extensions.AutoMapper. As Microsoft.Extensions.AutoMapper. As you can see, this "i" you can see, this "i" you can see, this "i" looks a bit looks a bit looks a bit suspicious. So it does suspicious. So it does suspicious. So it does n't turn out very n't turn out very n't turn out very well. This is very well. This is very well. This is very noticeable with certain noticeable with certain noticeable with certain fonts, etc. But fonts, etc. But fonts, etc. But I managed to I managed to I managed to publish a package on NuGet publish a package on NuGet publish a package on NuGet that supposedly that supposedly that supposedly belonged to Microsoft. As a belonged to Microsoft. As a belonged to Microsoft. As a decent developer, I decent developer, I of course published of course published of course published it, but also it, but also it, but also contacted the contacted the NuGet support page. I contacted NuGet support page. I contacted the team and said, " the team and said, " Look, I do Look, I do Look, I do n't need anything, but this

  9. n't need anything, but this n't need anything, but this shouldn't happen." shouldn't happen." shouldn't happen." They improved They improved They improved their typosquatting protection service their typosquatting protection service and removed my package . So, great. . So, great. . So, great. I didn't get any money, but the I didn't get any money, but the I didn't get any money, but the world became world became world became safer. Or not? safer. Or not? It turned out that it wasn't. While preparing for this While preparing for this talk, I was talk, I was talk, I was wondering: is it wondering: is it wondering: is it possible to publish possible to publish possible to publish something like something like something like Microsoft.EntityFrameworkCore on Microsoft.EntityFrameworkCore on Microsoft.EntityFrameworkCore on NuGet by simply NuGet by simply NuGet by simply replacing a few replacing a few replacing a few characters, not one, but characters, not one, but characters, not one, but several? It turned out several? It turned out several? It turned out that this was impossible. I that this was impossible. I that this was impossible. I changed the "i" to changed the "i" to changed the "i" to Ukrainian or Ukrainian or Ukrainian or Turkish, I don't Turkish, I don't Turkish, I don't remember, but when remember, but when remember, but when downloading NuGet downloading NuGet downloading NuGet found that the package was found that the package was found that the package was invalid. What a mess. invalid. What a mess. Then I thought: what about Then I thought: what about applying applying applying typosquatting typosquatting typosquatting based on fonts? I based on fonts? I based on fonts? I downloaded downloaded downloaded Microsoft.EntityFrameworkCore where the Microsoft.EntityFrameworkCore where the Microsoft.EntityFrameworkCore where the combination of "rn" combination of "rn" combination of "rn" looks like "m" and it looks like "m" and it looks like "m" and it worked. Not worked. Not worked. Not ideal, because ideal, because ideal, because you can still you can still you can still see the substitution in the font, but see the substitution in the font, but see the substitution in the font, but if you squint, if you squint, if you squint, it looks like an "m." I'm it looks like an "m." I'm it looks like an "m." I'm not easily stopped not easily stopped , so I decided , so I decided , so I decided to add even more Unicode, to add even more Unicode, to add even more Unicode, and I managed to and I managed to and I managed to download download download Microsoft.EntityFrameworkCore on Microsoft.EntityFrameworkCore on Microsoft.EntityFrameworkCore on NuGet. Well, if you NuGet. Well, if you NuGet. Well, if you go to that go to that go to that package, it's still package, it's still package, it's still on nuget.org, if you can on nuget.org, if you can on nuget.org, if you can find it, well, you'll find it, well, you'll find it, well, you'll see that there are see that there are see that there are a lot of Unicode characters, a lot of Unicode characters, a lot of Unicode characters, but I was able to but I was able to but I was able to download the download the duplicate package on nuget.org.

  10. duplicate package on nuget.org. Now you may Now you may ask, "Why would you ask, "Why would you ask, "Why would you do this?" Um, no one do this?" Um, no one do this?" Um, no one in their right mind in their right mind in their right mind would search for all these would search for all these would search for all these Unicode characters and such. But Unicode characters and such. But Unicode characters and such. But I'm patient as an attacker I'm patient as an attacker I'm patient as an attacker , so I , so I , so I thought, well, if I thought, well, if I thought, well, if I could just go to could just go to could just go to GitHub, find a few GitHub, find a few GitHub, find a few popular projects, popular projects, popular projects, and I started, of course, with and I started, of course, with and I started, of course, with our internal our internal our internal IdentityServer, and submitted a IdentityServer, and submitted a IdentityServer, and submitted a request (PR), just to request (PR), just to request (PR), just to see what would happen. By see what would happen. By see what would happen. By the way, it was never the way, it was never the way, it was never merged with the main merged with the main merged with the main branch. But I noticed branch. But I noticed branch. But I noticed that in the that in the that in the diff viewer on GitHub, when diff viewer on GitHub, when diff viewer on GitHub, when upgrading packages from upgrading packages from upgrading packages from version 8 to 10, as a version 8 to 10, as a version 8 to 10, as a good person in the good person in the good person in the community, I community, I community, I help a lot of help a lot of help a lot of open source projects, open source projects, open source projects, right? Well, you may right? Well, you may right? Well, you may notice that the letter "N" notice that the letter "N" notice that the letter "N" there is slightly there is slightly there is slightly different from what different from what different from what was in was in was in the original, but the original, but the original, but there is no clear indication in this diff there is no clear indication in this diff there is no clear indication in this diff that the package ID that the package ID has actually changed. So if I has actually changed. So if I did this to, say, did this to, say, did this to, say, 500 popular open source 500 popular open source 500 popular open source projects in the .NET space, projects in the .NET space, projects in the .NET space, there's a good chance that there's a good chance that there's a good chance that at least some of them would at least some of them would at least some of them would just accept the just accept the just accept the change without change without change without question, install question, install question, install my package, and add my package, and add my package, and add it as a dependency in the it as a dependency in the it as a dependency in the supply chain of supply chain of supply chain of others. Well, I hope others. Well, I hope others. Well, I hope everyone is everyone is everyone is scared enough by now.

  11. scared enough by now. scared enough by now. I liked this I liked this I liked this case, um, and case, um, and case, um, and Microsoft security, Microsoft security, after much after much after much discussion, essentially said that discussion, essentially said that discussion, essentially said that it didn't meet it didn't meet it didn't meet Microsoft's security requirements Microsoft's security requirements Microsoft's security requirements for vulnerabilities. for vulnerabilities. for vulnerabilities. So I started So I started So I started to push and said, " to push and said, " Well, that's not good." I Well, that's not good." I Well, that's not good." I also showed them also showed them also showed them a screenshot from GitHub and they a screenshot from GitHub and they a screenshot from GitHub and they said, "Okay, this is said, "Okay, this is said, "Okay, this is really medium really medium really medium severity." severity." severity." No No No bug bounty, no bug bounty, no bug bounty, no money, but money, but money, but they eventually fixed it. I they eventually fixed it. I they eventually fixed it. I did the same thing from the did the same thing from the did the same thing from the GitHub side, with a bunch of requests GitHub side, with a bunch of requests GitHub side, with a bunch of requests like "are there any like "are there any like "are there any updates here updates here updates here please", "are there any please", "are there any please", "are there any updates here updates here updates here please" and many others. please" and many others. please" and many others. And eventually GitHub And eventually GitHub And eventually GitHub said, "Well, that's not said, "Well, that's not said, "Well, that's not eligible for eligible for eligible for bounty." We are bounty." We are bounty." We are aware of various aware of various aware of various ways in which Unicode can be used ways in which Unicode can be used ways in which Unicode can be used to to to display display display misleading information misleading information , and this does not pose a significant , and this does not pose a significant , and this does not pose a significant security risk. security risk. security risk. So, having this knowledge, So, having this knowledge, So, having this knowledge, please do not please do not please do not abuse it. I did abuse it. I did abuse it. I did n't tell you this, n't tell you this, n't tell you this, but now you but now you but now you have this have this have this information. Um, I'll information. Um, I'll information. Um, I'll give GitHub credit for give GitHub credit for give GitHub credit for letting letting letting Copilot review the Copilot review the Copilot review the same PR we had same PR we had same PR we had there. This would actually there. This would actually there. This would actually indicate indicate indicate the presence of the presence of the presence of ASCII-like characters, ASCII-like characters, ASCII-like characters, homoglyphs, in the homoglyphs, in the homoglyphs, in the package name. So, the package name. So, the package name. So, the important conclusion: important conclusion: important conclusion: code review through code review through code review through Copilot is really Copilot is really Copilot is really quite useful here. I quite useful here. I quite useful here. I saw that NuGet had fixed saw that NuGet had fixed saw that NuGet had fixed this issue and I was this issue and I was this issue and I was no longer able to no longer able to no longer able to download packages download packages download packages with a lot of with a lot of with a lot of unicode characters and unicode characters and unicode characters and homoglyphs in the package ID homoglyphs in the package ID . So that's good. However, . So that's good. However, . So that's good. However, this problem still exists on GitHub this problem still exists on GitHub this problem still exists on GitHub . So . So . So be careful be careful be careful when checking your when checking your when checking your merge requests (PRs),

  12. merge requests (PRs), merge requests (PRs), check incoming changes check incoming changes check incoming changes , and , and use Copilot whenever possible. use Copilot whenever possible. Also use Also use package source mapping and package source mapping and package signing. If you package signing. If you package signing. If you are using Microsoft are using Microsoft are using Microsoft Entity Framework Core and someone Entity Framework Core and someone Entity Framework Core and someone sends a random sends a random sends a random PR with a different package ID, these PR with a different package ID, these PR with a different package ID, these two tools two tools two tools will also detect the will also detect the will also detect the problem. problem. problem. Lock files are Lock files are Lock files are also important, and I would also important, and I would also important, and I would also recommend some also recommend some software build object model (SBOM) packages and tools that software build object model (SBOM) packages and tools that provide a clear provide a clear provide a clear list of all your list of all your list of all your dependencies, dependencies, dependencies, show what they show what they show what they do, and do, and do, and signal if signal if signal if something is wrong. OK. something is wrong. OK. something is wrong. OK. We looked at the vector We looked at the vector We looked at the vector of infection, and I of infection, and I of infection, and I showed you a few showed you a few showed you a few places where it can be places where it can be places where it can be done. Let's move on to the done. Let's move on to the done. Let's move on to the next part, which is about what next part, which is about what your your malware and malware and malware and supply chain attack will look like. supply chain attack will look like. supply chain attack will look like. You want to execute You want to execute You want to execute some code on a some code on a some code on a developer device, developer device, developer device, in a CI system, or elsewhere. in a CI system, or elsewhere. The idea behind this dropper is The idea behind this dropper is that that that once it gets into the once it gets into the once it gets into the supply chain, you supply chain, you supply chain, you want to install want to install want to install this malicious code or this malicious code or this malicious code or payload payload . Ideally, . Ideally, . Ideally, as close as close as close to the time the to the time the to the time the NuGet package is installed as possible NuGet package is installed as possible , so that as soon as , so that as soon as , so that as soon as someone installs it, someone installs it, someone installs it, they are already they are already they are already infected, which would be infected, which would be infected, which would be great because great because great because they wouldn't have time they wouldn't have time they wouldn't have time to react. And to react. And to react. And ideally, all this should ideally, all this should ideally, all this should happen happen happen imperceptibly. So imperceptibly. So imperceptibly. So let's look let's look let's look at a few things you at a few things you at a few things you can do in .NET.

  13. can do in .NET. can do in .NET. I have two projects and I have two projects and I have two projects and I will switch I will switch I will switch between them in the next between them in the next between them in the next demos. I have a demos. I have a supply chain consumer, and this is where supply chain consumer, and this is where I will build I will build I will build my my my software that software that software that will be infected. So will be infected. So , , , module initializers. I'll quickly module initializers. I'll quickly module initializers. I'll quickly show you what they show you what they show you what they can do. When can do. When can do. When you have a regular you have a regular you have a regular web application, web application, web application, for example, and you add a for example, and you add a for example, and you add a static class with static class with static class with static methods static methods static methods by annotating it with the by annotating it with the initialization module attribute, you initialization module attribute, you can run the code can run the code can run the code before before before your application even starts. your application even starts. your application even starts. So, if you So, if you So, if you start this start this start this web server, you web server, you web server, you will see a will see a "hello" greeting in the console before my my host boots. This is a great host boots. This is a great host boots. This is a great technique, in my opinion. technique, in my opinion. technique, in my opinion. So let's So let's So let's see if see if see if we can add this we can add this we can add this to the dependency. So in to the dependency. So in to the dependency. So in my code I my code I my code I will remove that again. And now I'm going to will remove that again. And now I'm going to will remove that again. And now I'm going to try to write try to write try to write some kind of some kind of some kind of supply chain or supply chain or supply chain or dependency that I can dependency that I can dependency that I can use in this use in this use in this project for the same project for the same project for the same purpose. So, in my purpose. So, in my supply chain package, there is a class supply chain package, there is a class called policy discovery manager called policy discovery manager called policy discovery manager in the in the in the Microsoft.EntityFrameworkCore namespace, etc., Microsoft.EntityFrameworkCore namespace, etc., Microsoft.EntityFrameworkCore namespace, etc., which does the same thing.

  14. which does the same thing. which does the same thing. It has a It has a It has a module initializer module initializer . It writes something to the . It writes something to the . It writes something to the console. I also console. I also console. I also want a little want a little want a little invisibility. If invisibility. If invisibility. If something fails there, something fails there, something fails there, I just want I just want I just want to catch to catch to catch the exception and the exception and the exception and ignore it. I ignore it. I ignore it. I also make sure that also make sure that also make sure that this code is marked as this code is marked as compiler generated. compiler generated. The debugger The debugger The debugger doesn't actually see this doesn't actually see this doesn't actually see this unless it wants unless it wants unless it wants to see it. Not to see it. Not to see it. Not viewable in viewable in viewable in the editor, and the editor, and the editor, and a few other a few other a few other ways to make it ways to make it ways to make it less obvious. So, less obvious. So, less obvious. So, I'll package this as I'll package this as I'll package this as version 10.0.50 because version 10.0.50 because version 10.0.50 because otherwise my otherwise my otherwise my NuGet package cache will be NuGet package cache will be NuGet package cache will be clogged. clogged. I go back to my I go back to my consumer and add consumer and add consumer and add this dependency there. this dependency there. this dependency there. So, in my CS So, in my CS So, in my CS proj file, I make sure that proj file, I make sure that proj file, I make sure that this package reference is this package reference is this package reference is enabled. If I enabled. If I enabled. If I compile this and run compile this and run compile this and run this code, you'll see this code, you'll see nothing. Very nothing. Very creepy. This is creepy. This is creepy. This is actually a different actually a different actually a different demonstration. So demonstration. So demonstration. So ignore this one. This is ignore this one. This is ignore this one. This is not here now. To not here now. To not here now. To see what I'm doing in see what I'm doing in see what I'm doing in that that that module initializer of another module initializer of another module initializer of another project, I project, I project, I actually need to actually need to actually need to use a type from use a type from use a type from that project. So, I that project. So, I that project. So, I have to make sure have to make sure have to make sure I use this policy I use this policy I use this policy discovery manager from my Microsoft discovery manager from my Microsoft discovery manager from my Microsoft Entity Framework Core and do Entity Framework Core and do Entity Framework Core and do something with it. This could something with it. This could something with it. This could be a use, a be a use, a be a use, a new var, or new var, or new var, or whatever. You whatever. You whatever. You need to need to need to use the type use the type use the type so that the module so that the module so that the module loads and loads and loads and the message the message the message is displayed. So, is displayed. So, is displayed. So, my "creepy" code my "creepy" code my "creepy" code here comes from my here comes from my here comes from my addiction. Perfectly. I addiction. Perfectly. I addiction. Perfectly. I can inject can inject can inject some code and do some code and do some code and do something at

  15. something at something at runtime in my runtime in my runtime in my consumer. Let's move on consumer. Let's move on consumer. Let's move on to the next one. to the next one. to the next one. Source Source Source code generators. Code generators are code generators. Code generators are code generators. Code generators are great because they great because they great because they allow me to allow me to allow me to inject code into inject code into inject code into your application without your application without your application without having to explicitly having to explicitly having to explicitly call, for example, call, for example, call, for example, policy discovery manager.manage. So policy discovery manager.manage. So policy discovery manager.manage. So I can delete I can delete I can delete this again. I'll go back to this again. I'll go back to this again. I'll go back to my my my supply chain project supply chain project supply chain project and go to one and go to one and go to one of my of my of my code generators. This one essentially code generators. This one essentially code generators. This one essentially does the same thing. In does the same thing. In does the same thing. In your project, I your project, I your project, I write this policy discovery write this policy discovery write this policy discovery manager with console.writeline etc., manager with console.writeline etc., manager with console.writeline etc., but this time it but this time it but this time it will become part of will become part of will become part of your code. So, my your code. So, my your code. So, my code generator code generator code generator will simply add this will simply add this will simply add this class to your class to your class to your build results. I'll build results. I'll build results. I'll also check also check also check a few a few a few environment variables to environment variables to environment variables to make sure we're make sure we're make sure we're not running in CI, or for not running in CI, or for not running in CI, or for example, that we are example, that we are example, that we are running in CI. So, it running in CI. So, it running in CI. So, it won't show up won't show up won't show up on your, say, on your, say, on your, say, development machine. development machine. development machine. Just for Just for Just for demonstration, I'll demonstration, I'll demonstration, I'll remove this to remove this to remove this to make sure we make sure we make sure we actually register actually register actually register and compile this.

  16. and compile this. and compile this. The announcement of this The announcement of this The announcement of this will be very creepy. will be very creepy. will be very creepy. So, I'm compiling this. So, I'm compiling this. So, I'm compiling this. And, actually, I'll have to And, actually, I'll have to And, actually, I'll have to change change change my package ID or version again my package ID or version again my package ID or version again to to to make sure make sure make sure I have the new version I have the new version I have the new version to use. to use. I return to I return to the consumer, select the consumer, select the consumer, select version 51. I may version 51. I may version 51. I may have to have to have to rebuild and rebuild and rebuild and restore, and run restore, and run restore, and run the project. And now, without the project. And now, without the project. And now, without adding any code, adding any code, adding any code, I'll see this very I'll see this very I'll see this very creepy creepy creepy message. So, the message. So, the message. So, the code generator code generator code generator has actually added code to has actually added code to has actually added code to your project, even your project, even your project, even if you didn't if you didn't if you didn't notice it. There are several notice it. There are several notice it. There are several ways to solve ways to solve ways to solve this problem. Rider, this problem. Rider, this problem. Rider, for example, is pretty for example, is pretty for example, is pretty good here because good here because it it will show you in your dependency chain that there are will show you in your dependency chain that there are will show you in your dependency chain that there are code generators that code generators that code generators that come from Entity Framework. come from Entity Framework. come from Entity Framework. So I did a little So I did a little So I did a little work to make it work to make it work to make it look more look more look more legitimate than it legitimate than it legitimate than it actually is. But you actually is. But you actually is. But you can still see can still see can still see that there was something that there was something that there was something written there. So my written there. So my written there. So my advice would be: when you advice would be: when you advice would be: when you install a new install a new install a new dependency or a new dependency or a new dependency or a new version, just version, just version, just review everything to review everything to review everything to make sure there's make sure there's make sure there's nothing nothing nothing suspicious there. This is suspicious there. This is suspicious there. This is good practice, I would good practice, I would good practice, I would say. Other approaches say. Other approaches say. Other approaches may be to may be to may be to use the use the use the " " emits compiler generated files " build property. This will emits compiler generated files " build property. This will emits compiler generated files " build property. This will actually write the actually write the actually write the raw data to your raw data to your raw data to your disk so you can disk so you can disk so you can check what's check what's check what's going on there. This is not going on there. This is not going on there. This is not a guarantee, the code generators a guarantee, the code generators will still run and will still run and add code, but add code, but add code, but at least you will have at least you will have at least you will have a chance to check what is a chance to check what is a chance to check what is going on there and going on there and going on there and maybe figure out maybe figure out maybe figure out if something is wrong. Yes, one more if something is wrong. Yes, one more if something is wrong. Yes, one more point—MSBuild.

  17. point—MSBuild. point—MSBuild. This is actually the reason This is actually the reason This is actually the reason why another why another why another message message message appears in the output. appears in the output. In my In my supply chain projects, supply chain projects, supply chain projects, if you if you if you distribute a NuGet distribute a NuGet package, you package, you package, you can actually add can actually add can actually add package.targets. And in this package.targets. And in this package.targets. And in this package.targets, which is an package.targets, which is an package.targets, which is an MSBuild file, you can MSBuild file, you can MSBuild file, you can say, "Okay, I'm say, "Okay, I'm say, "Okay, I'm going to..." add the going to..." add the going to..." add the generated file. generated file. generated file. This file will be this one This file will be this one This file will be this one . It will be added . It will be added . It will be added somewhere in the output of my somewhere in the output of my somewhere in the output of my build, following the path of the build, following the path of the build, following the path of the generated file, generated file, generated file, wherever it is. And wherever it is. And wherever it is. And then it will become part of then it will become part of then it will become part of your build kit your build kit your build kit that you have now. that you have now. that you have now. So if in my So if in my So if in my package I don't ship a package I don't ship a package I don't ship a code generator or code generator or code generator or something like that, I something like that, I something like that, I can still ship can still ship can still ship certain MSBuild targets, and as certain MSBuild targets, and as certain MSBuild targets, and as part of my part of my part of my MSBuild targets, let's MSBuild targets, let's MSBuild targets, let's create a new package create a new package create a new package to make sure to make sure to make sure we have the latest we have the latest we have the latest version. You'll see version. You'll see version. You'll see that my consumer, when that my consumer, when that my consumer, when I update the dependency, I update the dependency, I update the dependency, um, goes there and um, goes there and um, goes there and changes the changes the changes the dependency version, uh, to 52. dependency version, uh, to 52. You'll see when I You'll see when I compile this, it'll compile this, it'll compile this, it'll actually write this actually write this actually write this very creepy, very very creepy, very very creepy, very [text] to the output as well.

  18. [text] to the output as well. [text] to the output as well. So, this comes from So, this comes from So, this comes from MSBuild. Perfectly. Ahem. Here's MSBuild. Perfectly. Ahem. Here's MSBuild. Perfectly. Ahem. Here's how to do it if you how to do it if you how to do it if you want to build want to build want to build something similar something similar something similar yourself. But as a yourself. But as a yourself. But as a mitigation, mitigation, mitigation, one thing you one thing you one thing you should do is should do is should do is also review the also review the also review the imported targets and imported targets and imported targets and properties in your properties in your properties in your IDE. There is no real IDE. There is no real IDE. There is no real way to block way to block way to block this. Uh, you'll disable this. Uh, you'll disable this. Uh, you'll disable a lot of core a lot of core a lot of core .NET functionality by locking down .NET functionality by locking down targets and props. For example , if you're doing , if you're doing , if you're doing web development, your web development, your web development, your Razor pages, your Razor pages, your Razor pages, your Blazer views— Blazer views— they'll all they'll all they'll all include targets and include targets and include targets and properties to properties to properties to ensure they ensure they ensure they work properly. So verification work properly. So verification is the only way to, uh is the only way to, uh , get around this , get around this , get around this particular, uh, particular, uh, particular, uh, potential potential potential vulnerability. Okay, vulnerability. Okay, vulnerability. Okay, last example. last example. last example. I actually I actually I actually borrowed some code borrowed some code borrowed some code from a JetBrains employee from a JetBrains employee from a JetBrains employee for this. What you for this. What you for this. What you can do, can do, can do, using that using that using that dropper that we had dropper that we had dropper that we had for for for source code generators or source code generators or source code generators or MSBuild, is make sure MSBuild, is make sure MSBuild, is make sure you have a launch hook you have a launch hook you have a launch hook somewhere on your somewhere on your , uh, consumer's system. And this , uh, consumer's system. And this , uh, consumer's system. And this startup hook is what startup hook is what startup hook is what will run, um, will run, um, will run, um, at least when you at least when you at least when you set the, uh, set the, uh, set the, uh, environment variable, environment variable, environment variable, it will run it will run it will run every time you every time you every time you execute a .NET command.

  19. execute a .NET command. execute a .NET command. So, let's say you So, let's say you So, let's say you want to create something want to create something want to create something that runs for that runs for that runs for every compilation of every compilation of every compilation of any project on any project on any project on your, um, your, um, your, um, intermediate victim's machine, you intermediate victim's machine, you intermediate victim's machine, you can do that. You can do that. You can do that. You can take can take can take this approach and essentially this approach and essentially this approach and essentially make sure that you make sure that you make sure that you run, uh, at the run, uh, at the run, uh, at the beginning of any beginning of any beginning of any .NET commands, and that .NET, .NET commands, and that .NET, .NET commands, and that .NET, or at least that or at least that or at least that launch hook, will deploy launch hook, will deploy launch hook, will deploy all your output to the all your output to the all your output to the console. Thank you, console. Thank you, console. Thank you, Kevin, for Kevin, for Kevin, for writing this. Uh, but writing this. Uh, but writing this. Uh, but it writes "hello from it writes "hello from it writes "hello from injected code", injected code", injected code", even for even for even for regular .NET, and regular .NET, and regular .NET, and then just then just then just unwraps all the unwraps all the unwraps all the .NET output in this case. .NET output in this case. .NET output in this case. So, um, it's really interesting So, um, it's really interesting So, um, it's really interesting if you want to do if you want to do if you want to do things that just things that just things that just work on the system work on the system work on the system when .NET is running. Uh, there are a when .NET is running. Uh, there are a when .NET is running. Uh, there are a few other things few other things you could you could you could do, but, um, yeah, do, but, um, yeah, do, but, um, yeah, I also don't want I also don't want I also don't want this talk to be a this talk to be a this talk to be a guide to, uh, how guide to, uh, how guide to, uh, how to do all of those things. to do all of those things. to do all of those things. I think we've shown I think we've shown I think we've shown enough things that are enough things that are enough things that are inspiring in that inspiring in that inspiring in that regard. Um, again regard. Um, again regard. Um, again , this is what , this is what , this is what this hook looks like. Uh, you're this hook looks like. Uh, you're this hook looks like. Uh, you're setting an setting an setting an environment variable. If you environment variable. If you environment variable. If you have access to have access to have access to your your your intermediate victim's computer, you intermediate victim's computer, you intermediate victim's computer, you can add this can add this can add this environment variable there and environment variable there and environment variable there and run it before whatever run it before whatever run it before whatever you plan to you plan to you plan to do there. That's right.

  20. do there. That's right. do there. That's right. There are other places. Um, we've There are other places. Um, we've There are other places. Um, we've seen a lot of seen a lot of seen a lot of reports about AI and so on reports about AI and so on . You can . You can . You can use NuGet use NuGet packages with just the packages with just the packages with just the source code, which source code, which source code, which will hide it in the IDE. will hide it in the IDE. will hide it in the IDE. IDE plugins IDE plugins IDE plugins can also perform can also perform can also perform certain actions. certain actions. certain actions. User profile, GitHub Actions, User profile, GitHub Actions, User profile, GitHub Actions, if not if not if not fixed, fixed, fixed, can also create a can also create a can also create a dependency or dependency or dependency or vulnerability. Of course, vulnerability. Of course, vulnerability. Of course, as .NET developers, as .NET developers, as .NET developers, we also we also we also use NPM, use NPM, use NPM, so that factor remains as well so that factor remains as well so that factor remains as well . If you . If you . If you 're using AI, and 're using AI, and 're using AI, and suddenly a suddenly a suddenly a function appears that says, " function appears that says, " Every time you do Every time you do Every time you do this, insert this this, insert this this, insert this piece of code." Will piece of code." Will piece of code." Will you notice this? you notice this? you notice this? I hope so, I hope so, I hope so, but you never know but you never know but you never know for sure. Large PRs for sure. Large PRs for sure. Large PRs very often get very often get very often get "looks good" and "looks good" and "looks good" and are merged into the are merged into the are merged into the main code. So main code. So main code. So if I use this if I use this if I use this as a way as a way as a way to penetrate, it might to penetrate, it might to penetrate, it might be a good way. A be a good way. A be a good way. A bunch of other things in bunch of other things in registry environment variables. So, there are registry environment variables. So, there are many other places many other places many other places where you can run where you can run where you can run code or implement code or implement code or implement something to execute in a something to execute in a developer's workflow. Yes. developer's workflow. Yes. Let's talk Let's talk Let's talk about about about payload. We payload. We payload. We talked about talked about talked about stealth. We stealth. We stealth. We want our want our want our loads to be loads to be loads to be light. You can light. You can light. You can obfuscate the code so that it is not obfuscate the code so that it is not obfuscate the code so that it is not immediately obvious immediately obvious immediately obvious that something is wrong or that something is wrong or that something is wrong or suspicious. I can suspicious. I can suspicious. I can hide things in hide things in hide things in base64 format or base64 format or base64 format or using invisible using invisible using invisible Unicode characters. So the Unicode characters. So the Unicode characters. So the source code source code source code looks empty, looks empty, looks empty, but it's actually not but it's actually not but it's actually not , because you're , because you're , because you're using using using Unicode there. Steganography: Unicode there. Steganography: Unicode there. Steganography: If you have If you have If you have an image in a an image in a an image in a binary file, you binary file, you binary file, you can can can embed instructions embed instructions embed instructions into that image in some way. You into that image in some way. You into that image in some way. You could do it. You could do it. You could do it. You could turn off could turn off could turn off antivirus scanners.

  21. antivirus scanners. antivirus scanners. All this is possible. There are All this is possible. There are All this is possible. There are different ways to be different ways to be different ways to be invisible. I think invisible. I think invisible. I think you can find all of this on the you can find all of this on the you can find all of this on the internet if internet if internet if you want, I'm just you want, I'm just you want, I'm just saying there are a lot of saying there are a lot of saying there are a lot of things you can things you can things you can do. Regarding do. Regarding payload, I payload, I think what you think what you think what you want to build want to build want to build depends on your depends on your depends on your goal. If you want to goal. If you want to goal. If you want to steal steal steal credentials—do it. If you credentials—do it. If you credentials—do it. If you want to empty your want to empty your want to empty your crypto wallets, you crypto wallets, you crypto wallets, you can do that too. If can do that too. If can do that too. If you are desperate you are desperate you are desperate for AI tokens, for AI tokens, for AI tokens, perhaps you can perhaps you can perhaps you can simply simply simply use the use the cloud code executable on the cloud code executable on the victim's computer. victim's computer. victim's computer. So, there are many things So, there are many things So, there are many things you can you can you can do there. Creative do there. Creative do there. Creative combinations, yes. There are combinations, yes. There are combinations, yes. There are many of them too. many of them too. The next thing we The next thing we want from our want from our supply chain attack is to supply chain attack is to ideally implement ideally implement ideally implement command control command control command control to be able to to be able to to be able to control and control and control and send new send new send new execution paths, new execution paths, new execution paths, new commands to your commands to your commands to your malware on the malware on the malware on the victim's system. You victim's system. You victim's system. You need a place need a place need a place you can " you can " call call call home." Essentially, if home." Essentially, if home." Essentially, if you're in the business of collecting you're in the business of collecting you're in the business of collecting credentials, you credentials, you credentials, you need to steal them need to steal them need to steal them and transfer them somewhere.

  22. and transfer them somewhere. and transfer them somewhere. Ideally, this should be as Ideally, this should be as unnoticeable as possible. Therefore, HTTP is a good option to is a good option to use. Your own use. Your own server, maybe server, maybe server, maybe posting to posting to posting to GitHub discussions, GitHub discussions, GitHub discussions, using a using a using a public public public GitHub calendar, OneDrive, whatever. All of GitHub calendar, OneDrive, whatever. All of GitHub calendar, OneDrive, whatever. All of these methods have these methods have these methods have been used been used been used before in various before in various before in various ecosystems. So, ecosystems. So, ecosystems. So, all of these methods all of these methods all of these methods have been used have been used have been used before, and you can before, and you can before, and you can use ICMP in the use ICMP in the use ICMP in the ping fields and the ping fields and the ping fields and the messages that messages that messages that are there. There was malware are there. There was malware are there. There was malware that simply added that simply added that simply added notes to the notes to the notes to the Solana blockchain, essentially saying, " Solana blockchain, essentially saying, " Okay, these are your new Okay, these are your new Okay, these are your new commands." They will never commands." They will never commands." They will never disappear as they disappear as they disappear as they become part of become part of become part of the public blockchain the public blockchain , so anything that , so anything that , so anything that tracks it can tracks it can tracks it can receive new receive new receive new commands. That's a lot of commands. That's a lot of commands. That's a lot of work, isn't it? work, isn't it? work, isn't it? Creating Creating Creating C2 infrastructure. You might want to C2 infrastructure. You might want to C2 infrastructure. You might want to look into look into look into something like something like something like Covenant. Covenant is a Covenant. Covenant is a Covenant. Covenant is a .NET .NET .NET command-and-control framework command-and-control framework command-and-control framework that aims to that aims to that aims to illuminate the illuminate the illuminate the .NET attack surface. In other .NET attack surface. In other .NET attack surface. In other words, it is a Docker words, it is a Docker container that can be container that can be container that can be run on run on any host, and it will be any host, and it will be any host, and it will be your ready-made your ready-made your ready-made C2 infrastructure. This is C2 infrastructure. This is C2 infrastructure. This is not advertising. I just not advertising. I just not advertising. I just want to show you that want to show you that want to show you that all of these things exist, all of these things exist, all of these things exist, they're available, and it's they're available, and it's actually actually relatively easy to carry out such an attack. Covenant relatively easy to carry out such an attack. Covenant relatively easy to carry out such an attack. Covenant provides a nice provides a nice provides a nice dashboard dashboard dashboard where you can configure where you can configure where you can configure listeners for listeners for listeners for incoming traffic, be it an incoming traffic, be it an incoming traffic, be it an IP address, a IP address, a IP address, a virtual host, or virtual host, or virtual host, or anything else. You anything else. You anything else. You essentially deploy essentially deploy essentially deploy multiple multiple multiple endpoints around the world endpoints around the world endpoints around the world and get and get and get input to those endpoints. You input to those endpoints. You input to those endpoints. You can add

  23. can add can add launchers, they launchers, they launchers, they come with come with come with multiple droppers multiple droppers multiple droppers and everything that can be and everything that can be and everything that can be reused reused reused in your in your in your supply chain attack. supply chain attack. supply chain attack. If you want to If you want to If you want to make something of your own, make something of your own, make something of your own, that is of course also that is of course also that is of course also possible. When you possible. When you possible. When you deploy this and deploy this and deploy this and have, for example, two have, for example, two have, for example, two infected systems—I infected systems—I infected systems—I did this on my did this on my did this on my local network—you local network—you local network—you can see a can see a can see a nice graph of the nice graph of the nice graph of the number of your number of your number of your nodes. You can nodes. You can nodes. You can click on a node, click on a node, click on a node, connect to connect to connect to it remotely, it remotely, it remotely, see what's there, see what's there, see what's there, so from a technical point of so from a technical point of so from a technical point of view it's quite convenient view it's quite convenient . But of course, you . But of course, you . But of course, you see, you don't have to see, you don't have to see, you don't have to build build build all of this yourself. It is all of this yourself. It is all of this yourself. It is actually quite actually quite actually quite easy to implement easy to implement easy to implement all the components of a all the components of a all the components of a supply chain attack supply chain attack supply chain attack in .NET. So, what can be in .NET. So, what can be in .NET. So, what can be done to done to done to minimize the risks? minimize the risks? minimize the risks? First, I would recommend First, I would recommend First, I would recommend exploring the different exploring the different exploring the different tools and tools and tools and practices on NuGet and GitHub. practices on NuGet and GitHub. practices on NuGet and GitHub. There's a lot of advice there that There's a lot of advice there that There's a lot of advice there that I know most of I know most of I know most of us ignore, willingly us ignore, willingly us ignore, willingly ignore, but it ignore, but it ignore, but it contains useful contains useful contains useful information. When you information. When you information. When you get get get pull requests, pull requests, pull requests, I know the I know the I know the volume has increased with AI, but volume has increased with AI, but volume has increased with AI, but make sure make sure make sure to do a thorough to do a thorough to do a thorough review review review with Copilot, with Copilot, with Copilot, manually, whatever manually, whatever manually, whatever you have. Make sure you have. Make sure you have. Make sure you know exactly what you know exactly what you know exactly what goes into your goes into your software. There are software. There are many tools many tools many tools such as Trivy, Aikido Security, such as Trivy, Aikido Security, such as Trivy, Aikido Security, Snyk. We saw Striker and a Snyk. We saw Striker and a Snyk. We saw Striker and a few other things.

  24. few other things. few other things. So, there are certainly So, there are certainly So, there are certainly other actions that can be other actions that can be other actions that can be taken. Detecting taken. Detecting taken. Detecting threats on threats on threats on endpoints, i.e. on endpoints, i.e. on endpoints, i.e. on your your your developer machines. I know developer machines. I know developer machines. I know all developers all developers all developers hate this, but this is something hate this, but this is something hate this, but this is something that really helps. that really helps. that really helps. Things like changing Things like changing Things like changing environment variables, environment variables, environment variables, DNS interception, and DNS interception, and DNS interception, and everything in that vein. And everything in that vein. And everything in that vein. And if you see something if you see something if you see something suspicious, suspicious, investigate. It's better investigate. It's better investigate. It's better to be safe to be safe to be safe than sorry. than sorry. than sorry. I think the best I think the best I think the best example here is from example here is from example here is from Andres Freund, who Andres Freund, who Andres Freund, who works at Microsoft. He was works at Microsoft. He was works at Microsoft. He was contributing to a contributing to a contributing to a Linux library, but Linux library, but Linux library, but noticed that logging into an SSH noticed that logging into an SSH shell was taking 500 shell was taking 500 shell was taking 500 ms longer than ms longer than ms longer than usual. He began usual. He began usual. He began investigating this and investigating this and investigating this and actually prevented actually prevented actually prevented one of the one of the one of the most catastrophic most catastrophic most catastrophic attacks on the attacks on the attacks on the supply chain, if it had been supply chain, if it had been supply chain, if it had been carried out to carried out to carried out to completion. So this completion. So this completion. So this guy definitely guy definitely guy definitely deserves a deserves a deserves a monument. But if monument. But if monument. But if you see something you see something you see something suspicious, even suspicious, even suspicious, even if it's a 500ms delay if it's a 500ms delay if it's a 500ms delay where there where there where there wasn't one before, pay wasn't one before, pay wasn't one before, pay attention to it. This is good attention to it. This is good attention to it. This is good practice. And, as in practice. And, as in practice. And, as in many other many other many other cases, cases, cases, use the use the use the Swiss Swiss Swiss cheese model. Each product cheese model. Each product cheese model. Each product has a has a has a supply chain and supply chain and supply chain and quality control at quality control at quality control at many stages.

  25. many stages. many stages. For example, if it's For example, if it's For example, if it's breakfast cereals, the breakfast cereals, the breakfast cereals, the farm conducts farm conducts farm conducts quality control, quality control, quality control, the factory conducts the factory conducts the factory conducts quality control, and quality control, and quality control, and perhaps the perhaps the perhaps the supermarkets do too. Different supermarkets do too. Different supermarkets do too. Different stages where you stages where you stages where you do do do quality control in different quality control in different quality control in different ways, but ways, but ways, but in the end, ideally, you in the end, ideally, you in the end, ideally, you get a safe get a safe get a safe and good box of and good box of and good box of cereal on your cereal on your cereal on your desk in the morning. It's the same with your desk in the morning. It's the same with your desk in the morning. It's the same with your software software : have different : have different points of inspection of the points of inspection of the points of inspection of the supply chain supply chain supply chain and the quality of everything that goes and the quality of everything that goes and the quality of everything that goes there. Your there. Your there. Your supply chain supply chain supply chain already has a number of already has a number of already has a number of checks in place. NuGet has a checks in place. NuGet has a CVE vulnerability warning. GitHub CVE vulnerability warning. GitHub has has has security scans, there's Dependabot for security scans, there's Dependabot for security scans, there's Dependabot for updates, and all that stuff updates, and all that stuff updates, and all that stuff . NuGet has . NuGet has package signing, package signing, assembly signing, log files, so assembly signing, log files, so assembly signing, log files, so use that use that use that too. And of course, as a too. And of course, as a too. And of course, as a developer, developer, developer, use your use your use your intelligence, imagination, and intelligence, imagination, and intelligence, imagination, and curiosity to also curiosity to also curiosity to also investigate investigate any security issues any security issues any security issues you may you may you may encounter. encounter. encounter. Thank you for that. This QR code Thank you for that. This QR code Thank you for that. This QR code leads to a leads to a leads to a blog post about this report blog post about this report , where everything is described in , where everything is described in , where everything is described in much more detail. much more detail. much more detail. I think Matt will also I think Matt will also I think Matt will also post this post this post this link in the chat. And I'm link in the chat. And I'm link in the chat. And I'm opening up time for opening up time for opening up time for questions.

  26. questions. Thank you, Martin. Although I Thank you, Martin. Although I feel, yes, a great feel, yes, a great feel, yes, a great report. I feel I report. I feel I report. I feel I should make a should make a should make a disclaimer that we in no disclaimer that we in no disclaimer that we in no way way way condone hacking condone hacking condone hacking in any form. It in any form. It in any form. It was like a list of was like a list of was like a list of all the questionable things all the questionable things all the questionable things you you you use. use. use. This is not a manual. Do not This is not a manual. Do not This is not a manual. Do not take this as a take this as a take this as a guide or guide or guide or instruction. Yes. instruction. Yes. Yeah, it's pretty amazing Yeah, it's pretty amazing to see how many to see how many to see how many different ways there are to different ways there are to sneak in and stuff sneak in and stuff . We had a . We had a . We had a question from the chat about question from the chat about question from the chat about how you worked with how you worked with how you worked with packages and packages and packages and switched between switched between switched between different different different package versions. And this is a simple package versions. And this is a simple package versions. And this is a simple question: is there a question: is there a question: is there a difference in how the difference in how the package itself is built, is it CS proj to package itself is built, is it CS proj to package, or nuspec NuGet, or package, or nuspec NuGet, or package, or nuspec NuGet, or something else? Are there any something else? Are there any something else? Are there any differences in the differences in the differences in the process itself? process itself? This is a good question, This is a good question, but NuGet essentially but NuGet essentially but NuGet essentially normalizes all of this to what normalizes all of this to what normalizes all of this to what NuGet NuGet NuGet will do when will do when will do when installing or installing or installing or rebuilding your rebuilding your rebuilding your package. So, there is no package. So, there is no package. So, there is no real difference in real difference in real difference in how you created how you created how you created the package, as long as all the package, as long as all the package, as long as all the components are in it.

  27. the components are in it. the components are in it. M-hm. And I was M-hm. And I was M-hm. And I was wondering, as you wondering, as you wondering, as you looked at some of looked at some of looked at some of these vectors, these vectors, these vectors, how how how practical are some of practical are some of practical are some of these attacks? Some of them these attacks? Some of them these attacks? Some of them seem a bit seem a bit seem a bit theoretical, theoretical, theoretical, like like like typosquatting, typosquatting, typosquatting, how how how dangerous are they in dangerous are they in dangerous are they in real life? real life? We don't know. Very We don't know. Very often, attacks are often, attacks are often, attacks are a little more covert, a little more covert, a little more covert, and people are not in a hurry and people are not in a hurry and people are not in a hurry to implement them. to implement them. to implement them. So I think if you So I think if you So I think if you go to NuGet, go to NuGet, go to NuGet, download all the download all the download all the packages and see packages and see packages and see how much Unicode and so on is there, how much Unicode and so on is there, how much Unicode and so on is there, I think you'll find a I think you'll find a I think you'll find a ton of them. Not all of them ton of them. Not all of them ton of them. Not all of them may be may be may be malicious, but I malicious, but I malicious, but I assume there are assume there are assume there are packages out there that are just packages out there that are just packages out there that are just waiting for waiting for waiting for someone to make 500 someone to make 500 someone to make 500 random PRs and random PRs and random PRs and quietly implement quietly implement quietly implement changes to AutoMapper, MVC, or changes to AutoMapper, MVC, or changes to AutoMapper, MVC, or whatever. The whatever. The PR example PR example probably scared me probably scared me probably scared me the most, because someone the most, because someone the most, because someone can do something that can do something that can do something that looks completely looks completely looks completely innocent, but in reality innocent, but in reality innocent, but in reality it introduces a completely it introduces a completely it introduces a completely different dependency than different dependency than different dependency than the one you're the one you're the one you're using.

  28. using. Yes. I think we also Yes. I think we also notice, as notice, as notice, as open source maintainers, open source maintainers, open source maintainers, that often there that often there that often there are people in the community who are people in the community who are people in the community who try to try to try to help and do help and do help and do random PR, like, random PR, like, random PR, like, "Okay, I updated Entity "Okay, I updated Entity "Okay, I updated Entity Framework for you because a Framework for you because a Framework for you because a new version of .NET came out new version of .NET came out ." This is often very ." This is often very ." This is often very useful, but if you useful, but if you useful, but if you don't watch what you're don't watch what you're don't watch what you're receiving and you receiving and you receiving and you 're, 're, 're, for example, on the train in the morning for example, on the train in the morning for example, on the train in the morning and you just and you just and you just think, "Yeah, it think, "Yeah, it think, "Yeah, it looks good. I looks good. I looks good. I trust this guy trust this guy ." Then you really ." Then you really ." Then you really added something to the added something to the added something to the supply chain supply chain supply chain that shouldn't be there that shouldn't be there that shouldn't be there . . . This is especially This is especially This is especially true in the time before the true in the time before the true in the time before the advent of AI. Now you advent of AI. Now you advent of AI. Now you mentioned that AI mentioned that AI agents are good at agents are good at agents are good at checking such PRs, checking such PRs, checking such PRs, but it makes me but it makes me but it makes me shudder when I shudder when I shudder when I think about how many PRs I've think about how many PRs I've think about how many PRs I've accepted that accepted that accepted that seemed logical seemed logical seemed logical and correct, but and correct, but and correct, but may not have may not have may not have been. Yes. been. Yes. That's right. So I That's right. So I hope this hope this hope this report is not an report is not an report is not an instruction, but rather a instruction, but rather a instruction, but rather a warning to warning to warning to be, let's say, be, let's say, be, let's say, a little more vigilant. a little more vigilant. a little more vigilant. I think this is a good I think this is a good I think this is a good start.

  29. start. We have another We have another question: is there a question: is there a question: is there a way to disable way to disable way to disable imported imported imported source source source generators? generators? I haven't encountered this, I haven't encountered this, and in fact .NET and in fact .NET and in fact .NET actively uses actively uses actively uses code generation in code generation in code generation in its work. its work. its work. For example, if you For example, if you For example, if you use use use System.Text.Json, you will see System.Text.Json, you will see that there are generated that there are generated that there are generated classes for JSON and classes for JSON and classes for JSON and deserialization. If deserialization. If deserialization. If you use you use you use regular expressions in regular expressions in regular expressions in modern .NET, you modern .NET, you modern .NET, you will see will see will see compiled regular expressions compiled regular expressions compiled regular expressions from the from the from the code generator. code generator. code generator. We just saw a bunch of We just saw a bunch of We just saw a bunch of that in your Blazer. that in your Blazer. that in your Blazer. Yes. Yes. Yes. Yes, we just saw Yes, we just saw Yes, we just saw a lot of that in a lot of that in a lot of that in Stefan's report. And Stefan's report. And Stefan's report. And you know, code generators you know, code generators are used in are used in many places. I had many places. I had many places. I had no idea there were no idea there were no idea there were so many of them. There are so many of them. There are so many of them. There are really a really a really a lot of them. And you usually lot of them. And you usually lot of them. And you usually shouldn't turn them off shouldn't turn them off shouldn't turn them off because you'll break because you'll break because you'll break everything you're doing everything you're doing everything you're doing legitimately. legitimately. Um, another question Um, another question for those who for those who for those who use, well, use, well, use, well, let's say, open source let's say, open source let's say, open source projects that could have projects that could have projects that could have been compromised been compromised . What can I do as a . What can I do as a . What can I do as a user of these user of these user of these dependencies if dependencies if dependencies if they may be they may be they may be infected? This is some kind of infected? This is some kind of , uh, I think it , uh, I think it , uh, I think it was here too, yes, a list of was here too, yes, a list of was here too, yes, a list of materials (SBOM). Sorry materials (SBOM). Sorry , Matt, I'm stealing , Matt, I'm stealing , Matt, I'm stealing your question. Or your question. Or your question. Or maybe a sandbox, maybe a sandbox, maybe a sandbox, something like that?

  30. something like that? something like that? Uh, that would work. Uh Uh, that would work. Uh , I think so. Barry , I think so. Barry , I think so. Barry Dorrance, one of the Dorrance, one of the Dorrance, one of the security specialists on the security specialists on the security specialists on the .NET team at Microsoft, .NET team at Microsoft, .NET team at Microsoft, has a package that has a package that has a package that generates a list of generates a list of generates a list of software software software materials materials materials every time you build your every time you build your every time you build your projects. Ideally you projects. Ideally you projects. Ideally you use this, use this, use this, maybe store it in a maybe store it in a maybe store it in a database or somewhere, database or somewhere, database or somewhere, and when you see and when you see and when you see some dependency in the some dependency in the some dependency in the chain changing chain changing chain changing and looking suspicious, it's and looking suspicious, it's and looking suspicious, it's time to check time to check time to check it out. But really it out. But really it out. But really watch out for watch out for watch out for dependencies and, more dependencies and, more dependencies and, more importantly, importantly, importantly, transitive transitive transitive dependencies in dependencies in dependencies in your project. your project. your project. Can this also be Can this also be Can this also be automated in CI? automated in CI? automated in CI? You can do it, You can do it, You can do it, yes. So, the SBOM package yes. So, the SBOM package yes. So, the SBOM package will generate an XML file, it will generate an XML file, it will generate an XML file, it seems, or seems, or seems, or at least some at least some at least some standardized standardized standardized format that can be format that can be format that can be created during created during created during each build and each build and each build and then uploaded then uploaded then uploaded to the system for to the system for to the system for comparison. comparison. comparison. I think we need to I think we need to I think we need to find a link to find a link to find a link to this package and this package and this package and share it in the chat share it in the chat . . . I will share it in the chat I will share it in the chat I will share it in the chat after my speech. after my speech. after my speech. Of course. Of course. Of course. Perfectly. By the way, Perfectly. By the way, Perfectly. By the way, Stefan just posted Stefan just posted Stefan just posted some tips in the chat some tips in the chat some tips in the chat on on on how to disable how to disable how to disable analyzers. So this analyzers. So this analyzers. So this might be something might be something might be something worth digging into and doing worth digging into and doing worth digging into and doing a little research.

  31. a little research. a little research. This is a good option. This is a good option. This is a good option. Thank you, Stefan. This is a Thank you, Stefan. This is a Thank you, Stefan. This is a good option. good option. Matthias, do we have any more Matthias, do we have any more questions? questions? questions? I, I have one I, I have one I, I have one last question, I last question, I last question, I hope I didn't hope I didn't hope I didn't miss it when miss it when miss it when you were talking. Hmm, but you were talking. Hmm, but you were talking. Hmm, but even just even just even just opening a project opening a project is bad enough, right? is bad enough, right? is bad enough, right? So just So just So just Yes. Um, yes. Yes. Um, yes. Yes. Um, yes. Yes. Yes. Yes. So, I mentioned that you So, I mentioned that you So, I mentioned that you want to run the want to run the want to run the payload payload payload as close to the time the as close to the time the package is installed as possible, and package is installed as possible, and using using using source source source generators, for example, is a generators, for example, is a great way to do great way to do great way to do that. Because you that. Because you that. Because you will have a build during will have a build during will have a build during development that development that development that ensures that you ensures that you ensures that you can can can build and work build and work build and work with the project normally, get with the project normally, get with the project normally, get IntelliSense and all other IntelliSense and all other IntelliSense and all other features. So, if you features. So, if you features. So, if you use the use the code generator approach, it will be a very code generator approach, it will be a very straightforward method that straightforward method that straightforward method that runs every time runs every time runs every time you install a you install a you install a package. package. package. Ugh. Um, and, and. Ugh. Um, and, and. Ugh. Um, and, and. And you, by the way, I have And you, by the way, I have And you, by the way, I have n't really n't really n't really gone into this, gone into this, gone into this, but a code generator doesn't but a code generator doesn't but a code generator doesn't necessarily have to necessarily have to necessarily have to produce source produce source produce source code. It can also, code. It can also, code. It can also, for example, add an for example, add an for example, add an environment variable environment variable environment variable or something to your or something to your or something to your profile, like in macOS. So the profile, like in macOS. So the profile, like in macOS. So the next time next time next time you start or you start or you start or reboot reboot reboot the system, that's when the the system, that's when the the system, that's when the payload will run payload will run payload will run . So you . So you . So you don't have to, um, don't have to, um, don't have to, um, yeah. This doesn't necessarily yeah. This doesn't necessarily yeah. This doesn't necessarily have to be in the source have to be in the source have to be in the source code you code you code you compile. That's what I'm compile. That's what I'm compile. That's what I'm trying to say.

  32. trying to say. trying to say. Yes. This, this is all a little Yes. This, this is all a little Yes. This, this is all a little scary. Um, I think scary. Um, I think scary. Um, I think if I'm not mistaken, if I'm not mistaken, if I'm not mistaken, NPM added what is or is not a NPM added what is or is not a NPM added what is or is not a waiting period for a new waiting period for a new waiting period for a new package to be a certain age package to be a certain age package to be a certain age before it before it before it can be can be can be installed, so that someone installed, so that someone installed, so that someone doesn't publish a doesn't publish a doesn't publish a vulnerable package that vulnerable package that vulnerable package that everyone immediately everyone immediately everyone immediately upgrades to. You have to upgrades to. You have to upgrades to. You have to wait a day or two wait a day or two so people so people so people can just see it. Is there can just see it. Is there can just see it. Is there anything similar to this in NuGet anything similar to this in NuGet anything similar to this in NuGet ? ? ? Oh, they don't have any. So Oh, they don't have any. So Oh, they don't have any. So they have a they have a they have a typosquatting check when typosquatting check when typosquatting check when you download a you download a you download a new package. It's new package. It's new package. It's actually not bad, actually not bad, actually not bad, but other than that, there's but other than that, there's but other than that, there's nothing like what nothing like what nothing like what NPM does. No. NPM does. No. NPM does. No. Yeah, I don't know, I wonder Yeah, I don't know, I wonder Yeah, I don't know, I wonder if this idea will come with a if this idea will come with a if this idea will come with a waiting period. waiting period. waiting period. It only It only It only recently appeared in recently appeared in recently appeared in NPM, if I NPM, if I NPM, if I understand correctly. understand correctly. understand correctly. NPM is also now NPM is also now NPM is also now owned by Microsoft, so I owned by Microsoft, so I owned by Microsoft, so I can only imagine that can only imagine that can only imagine that these teams these teams these teams are communicating and something are communicating and something are communicating and something will take over at some point, will take over at some point, will take over at some point, but let's but let's but let's hope that hope that hope that happens. happens. happens. Yes. Yes. Yes. It always seemed to It always seemed to It always seemed to me like such a, you know, me like such a, you know, me like such a, you know, strange option.

  33. strange option. So, yes, for someone So, yes, for someone who wants to avoid who wants to avoid malware getting into their malware getting into their code, that's good, but code, that's good, but code, that's good, but otherwise it's otherwise it's otherwise it's just "let someone just "let someone just "let someone else get it else get it else get it first before first before first before I do." I do." Yes, it suits me. Yes, it suits me. That means it works too. That means it works too. That means it works too. Just a little Just a little Just a little slower to update slower to update , but on the other hand, , but on the other hand, , but on the other hand, if there's a real if there's a real if there's a real vulnerability, vulnerability, vulnerability, for example, maybe for example, maybe for example, maybe you want to be, yes. you want to be, yes. you want to be, yes. It is at that moment that It is at that moment that It is at that moment that this happens that this this happens that this this happens that this renewal must renewal must renewal must occur occur occur transitively. So transitively. So transitively. So there is no one there is no one there is no one right answer here right answer here . . Yes, I'm also Yes, I'm also checking the comments checking the comments checking the comments in the chat now. They say that there in the chat now. They say that there in the chat now. They say that there are command line commands on the NPM side are command line commands on the NPM side are command line commands on the NPM side that that that can be run to can be run to can be run to prevent prevent prevent commands or a command commands or a command commands or a command shell from executing during a shell from executing during a shell from executing during a restore. Which would also be restore. Which would also be restore. Which would also be quite useful quite useful . . NuGet used to have something NuGet used to have something similar where you could similar where you could similar where you could run a PowerShell run a PowerShell script when script when script when installing a package, installing a package, installing a package, but that was but that was but that was removed a long time ago, so it's removed a long time ago, so it's removed a long time ago, so it's no longer possible, but no longer possible, but as we've seen, there are as we've seen, there are as we've seen, there are other options.

  34. other options. I remember someone I remember someone created a package that, created a package that, created a package that, when installed, " when installed, " cracked" you. cracked" you. Um, yes, maybe it Um, yes, maybe it was one of those was one of those speaking here today. speaking here today. You have experience, You have experience, You have experience, Martin, that's what we Martin, that's what we Martin, that's what we want to say. want to say. want to say. You have experience. You have experience. You have experience. Yes. Yes. Yes. Okay, Martin, Okay, Martin, Okay, Martin, thank you very much for a very thank you very much for a very thank you very much for a very interesting report. I'm interesting report. I'm interesting report. I'm a little nervous and a little nervous and a little nervous and scared to update scared to update scared to update any of my packages any of my packages any of my packages right now, but other than that, right now, but other than that, right now, but other than that, thank you very much, it's always thank you very much, it's always thank you very much, it's always nice to see you, nice to see you, nice to see you, and I hope and I hope and I hope to see you again soon. to see you again soon. Again, thank you for Again, thank you for inviting me.

No summary available yet.

View original episode ↗