<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="andreiepure.ro/feed.xml" rel="self" type="application/atom+xml" /><link href="andreiepure.ro/" rel="alternate" type="text/html" /><updated>2025-04-06T15:17:31+00:00</updated><id>andreiepure.ro/feed.xml</id><title type="html">Andrei Epure</title><subtitle>Welcome to my blog.</subtitle><entry><title type="html">Plugușor pentru 2025</title><link href="andreiepure.ro/2024/12/31/plugusor-2025.html" rel="alternate" type="text/html" title="Plugușor pentru 2025" /><published>2024-12-31T00:00:00+00:00</published><updated>2024-12-31T00:00:00+00:00</updated><id>andreiepure.ro/2024/12/31/plugusor-2025</id><content type="html" xml:base="andreiepure.ro/2024/12/31/plugusor-2025.html"><![CDATA[<p>Aho, aho, copii și frați,<br />
Stați puțin și nu mânați,<br />
Lângă plug v-adunați<br />
Și cuvântul ascultați!</p>

<p>Din Carpați și până-n mare,<br />
Plugul nostru dă strigare:<br />
România, fii deșteaptă,<br />
Nu cădea în cursa lată!</p>

<p>Nici cu ruși, nici cu extreme,<br />
Nici cu falsele dileme.<br />
Ortodoxia-adevărată<br />
E lumină ne-ncetată!</p>

<p>Sincretismul de Valhală?<br />
Nu-i cărare, e doar boală.<br />
Fii român blând și-nțelept,<br />
Să discerni strâmbul de drept.</p>

<p>NATO, Schengen și Uniunea,<br />
Sunt pe bune, nu minciuna!<br />
Să păstrăm ce-i câștigat,<br />
Să schimbăm ce-i de schimbat.</p>

<p>Între frați, fie iubire,<br />
Nu dispreț și despărțire.<br />
Suveranist / mondialist,<br />
Tot român ești: altruist!</p>

<p>Așa-i plugul de povață,<br />
Să ne fie țara-n față,<br />
Demnă, bună și curată,<br />
Să ne fie viața toată.</p>

<p>Ia mai mânați, măi, flăcăi,<br />
Pace-n țară și în văi!</p>

<p>La anul și la mulți ani!</p>

<p><i>Am compus un plugușor (cu un pic de ajutor*)</i><br />
<i>*de la chatul gipiti</i></p>]]></content><author><name></name></author><summary type="html"><![CDATA[Aho, aho, copii și frați, Stați puțin și nu mânați, Lângă plug v-adunați Și cuvântul ascultați!]]></summary></entry><entry><title type="html">How to analyze JS/TS, HTML and CSS files with the Sonar Scanner for .NET</title><link href="andreiepure.ro/2023/08/20/analyze-web-files-with-s4net.html" rel="alternate" type="text/html" title="How to analyze JS/TS, HTML and CSS files with the Sonar Scanner for .NET" /><published>2023-08-20T00:00:00+00:00</published><updated>2023-08-20T00:00:00+00:00</updated><id>andreiepure.ro/2023/08/20/analyze-web-files-with-s4net</id><content type="html" xml:base="andreiepure.ro/2023/08/20/analyze-web-files-with-s4net.html"><![CDATA[<p>Imagine you have a .NET web project, where the backend is written in .NET and the frontend in JS/TS with HTML and CSS, for historical reasons (because now we’d all use <a href="https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor">Blazor</a> for the frontend, right?).</p>

<p>Let’s say the layout of your project is something like:</p>

<table>
  <thead>
    <tr>
      <th>Folder</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>/src</td>
      <td>all the .NET code is here, with the SLN file in the root</td>
    </tr>
    <tr>
      <td>/frontend</td>
      <td>all the web code is here: JS/TS, CSS, HTML</td>
    </tr>
    <tr>
      <td>/frontend/build</td>
      <td>some scripts</td>
    </tr>
    <tr>
      <td>/frontend/src</td>
      <td>the actual JS/TS, CSS and HTML files</td>
    </tr>
  </tbody>
</table>

<p>And you want to analyze this .NET project with Sonar (SonarQube or SonarCloud). When setting up your CI analysis with the <a href="http://redirect.sonarsource.com/doc/msbuild-sq-runner.html">Sonar Scanner for .NET</a>, for example with GitHub Actions, your <code class="language-plaintext highlighter-rouge">build.yml</code> would contain the following task for the analysis (I skip code coverage generation in this example):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>      - name: Build and analyze
        env:
          GITHUB_TOKEN: \$
          SONAR_TOKEN: \$
        shell: powershell
        run: |
          .\.sonar\scanner\dotnet-sonarscanner begin /k:"&lt;NAME&gt;" /o:"&lt;ORG&gt;" /d:sonar.token="\$" /d:sonar.host.url="https://sonarcloud.io"
          dotnet build .\src\NAME.sln
         .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.token="\$"
</code></pre></div></div>

<p>This is because you need to run the build (with MSBuild behind the scenes) in order to trigger the Sonar Roslyn analysis for C# or VB .NET. Unfortunately, all your frontend code is in a different folder and, even if it were in the same folder with the solution file <code class="language-plaintext highlighter-rouge">NAME.sln</code>, the frontend files would not be referenced (in this example) in any MSBuild project file.</p>

<p>There is a small inexpensive trick to include all the frontend files in the Sonar analysis with the Scanner for .NET. You need to create a dummy CSPROJ file which references all the frontend files. For example, if you create a file <code class="language-plaintext highlighter-rouge">src/sonar/frontend.csproj</code>, it should have the following content:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;Project Sdk="Microsoft.NET.Sdk"&gt;
  &lt;PropertyGroup&gt;
    &lt;TargetFrameworks&gt;net6.0&lt;/TargetFrameworks&gt;
  &lt;/PropertyGroup&gt;
  &lt;ItemGroup&gt;
    &lt;!-- Import all frontend files for the Sonar analysis --&gt;
    &lt;Resource Include="../../frontend/src/**" /&gt;
  &lt;/ItemGroup&gt;
&lt;/Project&gt;
</code></pre></div></div>

<p>Make sure that you include the newly created <code class="language-plaintext highlighter-rouge">frontend.csproj</code> in the <code class="language-plaintext highlighter-rouge">NAME.sln</code> MSBuild solution. This trick will tell MSBuild - <em>“Hey, please take these web files as Resources”</em>. The Scanner for .NET includes special target files which, during the <code class="language-plaintext highlighter-rouge">dotnet build</code> process, examine the build environment and include all items picked up by MSBuild from <code class="language-plaintext highlighter-rouge">ItemGroup</code>. Afterwards, the Scanner for .NET tells SonarCloud / SonarQube later on that those files need to be analyzed (in other words, the scanner “indexes” the files for later analysis during the END step).</p>

<p>If you don’t want to use <code class="language-plaintext highlighter-rouge">Resource</code> which may include the file in the project output, you can use <code class="language-plaintext highlighter-rouge">None</code> (<a href="https://learn.microsoft.com/en-us/visualstudio/msbuild/common-msbuild-project-items?view=vs-2022#none">docs</a>).</p>

<p>However, we are not done. If you run the analysis now, you may see in the logs of the END step entries like the following:</p>

<blockquote>
  <p>WARNING: File ‘<WORKSPACE>\frontend\src\a\b\file.js' is not located under the base directory '<WORKSPACE>\src' and will not be analyzed.</WORKSPACE></WORKSPACE></p>
</blockquote>

<p>The good news is that now the Sonar analysis is aware of these files. The bad news is that the Scanner for .NET considers, by default, the base directory of the analysis the directory where the solution file is present. And all indexed files need to be inside the base directory.</p>

<p>To fix this problem, you need to explicitly define the base directory during the BEGIN step, by defining the <code class="language-plaintext highlighter-rouge">sonar.projectBaseDir</code> analysis property (for example, to <code class="language-plaintext highlighter-rouge">$</code>).</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.\.sonar\scanner\dotnet-sonarscanner begin /k:"&lt;NAME&gt;" /o:"&lt;ORG&gt;" /d:sonar.token="\$" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.projectBaseDir="\$"
</code></pre></div></div>

<p>Bingo. You should see in the logs of the END step something like:</p>

<blockquote>
  <p>INFO: Sensor JavaScript/TypeScript analysis [javascript]
INFO: 1071 source files to be analyzed</p>
</blockquote>

<p>At the time of this writing, there is a limitation: the file paths will be a bit ugly in the Sonar UI, because they will be relative to the root folder which contains both the <code class="language-plaintext highlighter-rouge">frontend</code> folder with web code and the <code class="language-plaintext highlighter-rouge">src</code> folder with .NET code. But hey, you now have them all in one place.</p>

<table>
  <thead>
    <tr>
      <th>Version Date</th>
      <th style="text-align: center">Change</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>2023-08-20</td>
      <td style="text-align: center">Initial version</td>
    </tr>
    <tr>
      <td>2023-10-04</td>
      <td style="text-align: center">Mention “None”</td>
    </tr>
  </tbody>
</table>]]></content><author><name></name></author><summary type="html"><![CDATA[Imagine you have a .NET web project, where the backend is written in .NET and the frontend in JS/TS with HTML and CSS, for historical reasons (because now we’d all use Blazor for the frontend, right?).]]></summary></entry><entry><title type="html">2022: my first year as a public speaker</title><link href="andreiepure.ro/2022/12/30/memories-from-2022-talks.html" rel="alternate" type="text/html" title="2022: my first year as a public speaker" /><published>2022-12-30T00:00:00+00:00</published><updated>2022-12-30T00:00:00+00:00</updated><id>andreiepure.ro/2022/12/30/memories-from-2022-talks</id><content type="html" xml:base="andreiepure.ro/2022/12/30/memories-from-2022-talks.html"><![CDATA[<blockquote>
  <p>The mind cannot continue in one and the same condition, I mean without receiving addition to or diminution of its good qualities. For to fail to gain new ones, is to lose them, because when the desire of making progress ceases, there the danger of going back is present. (Abbot Theodore in “The Conferences of Desert Fathers” by St. John Cassian)</p>
</blockquote>

<p>It’s the end of December, a great time for doing a retrospective of my first year as a public speaker.</p>

<p>I wanted to speak at a conference for a long time. I had already done “Brown Bag Lunch” (BBL) presentations inside Sonar, demystifying technical topics to a mixed technical and non-technical audience (for example, on Object Oriented Thinking). My talks had been appreciated and this feedback encouraged me to think about widening the audience and speaking at a developer conference. Also, I once gave a talk about C# 8 at the local .NET user group in 2019 (<a href="https://youtu.be/x-Jz7nWqZGo">recording</a>), so I had the “user group” experience, too.</p>

<h1 id="dotnetday-switzerland-2022">DotNetDay Switzerland 2022</h1>

<p><a href="https://dotnetday.ch/">.NET Day Switzerland</a> was the first time I spoke on a stage. It was awesome and, thank God, I nailed it. In this blog post I will explain how I prepared for it.</p>

<h2 id="choosing-a-topic">Choosing a topic</h2>

<p>After I read Alex Bîrsan’s <a href="https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610">Dependency Confusion: How I Hacked Into Apple, Microsoft, and Dozens of Other Companies</a> article in early 2021, I did a one-week investigation sprint at Sonar to make sure we were safe. Afterwards, around June 2021, I did a small technical presentation to the Languages Team, explaining how the attack works and what were the possible defense mechanisms at that time. Alex, one of our Product Managers, suggested that I do a BBL for the entire company. In the following months I gathered some ideas on how I could present this to a non-technical audience, but did not invest a lot of time in making the presentation.</p>

<h2 id="the-opportunity">The opportunity</h2>

<p>At the end of March 2022, I found out that the Call for Speakers of .NET Day Switzerland 2022 was still open. Our VP of Products asked me whether the .NET Bubble wants to present something. I asked my team mates, it did not spark a lot of interest, so I wrote down three ideas that came to my mind. One was about “Dependency Confusion” (I already had a sketch for the talk), the second about “Improving the performance for Roslyn analyzers” (we had invested some time in this topic in the previous 18 months for our .NET analyzers) and another one about how “Symbolic Execution” works (a geeky topic, and we had an in-house Control Flow Graph and Symbolic Execution Engine implementation).</p>

<p>Unfortunately, I didn’t have time to prepare the titles and the abstracts, so I sent an email to the organizers for a deadline extension, and Manuel Meyer replied that I could apply until April the 10th.</p>

<p>I applied with the “dependency confusion” and “improving the performance” talks, and the first one got accepted on April the 12th.</p>

<h2 id="preparing">Preparing</h2>

<p>I knew from my previous BBL experience that preparing a good talk is not easy. And this time it wasn’t a 15 or 20 minutes talk as before, but a 50-minute one.</p>

<p>I didn’t have a lot of time - it was already mid-April and I had to have it ready by the end of August, and I had nothing yet, except two sheets of paper with a sketch. I needed a plan. So I set myself some intermediate checkpoints:</p>
<ul>
  <li>do a BBL explaining how the attack works to a non-technical audience by the end of May</li>
  <li>prepare the presentation and demo for a technical audience</li>
  <li>present the talk at two user groups before going on the big stage - forcing myself to have an almost-ready version that I could get feedback on from .NET developers who could expose my ignorance on the topic. Initially, I wanted to do one session by the end of June and one in August.</li>
</ul>

<h2 id="the-bbl">The BBL</h2>

<p>I planned the BBL inside the company on the 2nd of June. It was good because I prepared the slides to explain in a visual manner what a package manager does and how the dependency confusion attack works. For this BBL, I created the Mr. Evil Hacker persona to explain the attacks.</p>

<p>I gave the talk from my desk, with almost 200 persons online, some of which gave feedback on the hallways and via Slack, giving kudos for how well I helped non-technical people understand the concepts. Some of my technical colleagues gave kudos for raising awareness. Everyone loved “Mr. Evil Hacker”, they even screenshot me and created a slack :hacker: emoji out of it.</p>

<h2 id="net-iasi-virtual-talk">.NET Iasi virtual talk</h2>

<p>I wanted to give a virtual talk at the <a href="https://www.meetup.com/dotnetiasi/">DotNet Iasi meetup</a>, and an in-person one at the <a href="https://genevadnug.ch/">Geneva .NET User Group</a>. Unfortunately, the Geneva organisers asked me for the slides before, and I didn’t have them (I was using the meetups to motivate myself to reach intermediate checkpoints).</p>

<p>I got a slot on August the 10th for DotNet Iasi. I had to prepare quite a lot, and it took a couple of weekends to do it: change or improve the existing slides to fit a .NET technical audience, add new slides to explain how to defend against the attack and create demos for the attack, as well for the defense. Moreover, I also added Typosquatting to the presentation (which meant: more demos, more slides).</p>

<p>The talk was fine, although I hadn’t had time to prepare my speech properly. It took a little bit more than one hour - I preferred to have more material that I could remove from for the 50-minute presentation. I didn’t get many questions as I wished at the end. Unfortunately, there was no tricky question and no constructive feedback.</p>

<p>You can watch the <a href="https://youtu.be/ghKAGy-NrSI">recording on youtube</a> - it was an ok talk, but my slides and speech were not polished and in my opinion I did not have a very good energy and vibe throughout the talk. I really needed to change this before going on stage.</p>

<h2 id="dry-runs-in-my-company">Dry-runs in my company</h2>

<p>The week before D-Day (the 30th of August 2022), I did three dry runs inside the company - the full show, the “final” slides, the demos, the Evil Hacker change of persona in the middle of the talk. By this time, I improved the presentation, reduced the content and prepared a speech.</p>

<p>The first dry-run was during the .NET Guild Coffee Break (a cross-team meeting for the .NET developers in Sonar), on a Tuesday, hybrid. Most of the feedback I got was related to the content (as expected, because they were the NuGet and MSBuild subject matter experts in the company).</p>

<p>Then on Thursday I did an in-person dry-run with around six people and on Friday I did another one remote-only with four colleagues from various teams. I got plenty of useful feedback on the format of the presentation (slides, speech, story). Not that much on the content itself. And my colleague Andrea pointed me to <a href="https://youtu.be/Unzc731iCUY">Patrick Winston’s “How to Speak”</a> MIT lecture, which I watched over the weekend.</p>

<h2 id="the-weekend-before">The weekend before</h2>

<p>The weekend before I initially wanted to chill. However, I went to the local library and I borrowed some books about public speaking. While I was waiting on Saturday evening at a barber’s shop, I was polishing my slides on the phone (greatly simplifying them and making them prettier) according to Prof. Winston’s advice. I considered some hints from the books I skimmed through, although I must admit the “How to Speak” lecture was far superior to what I found at the local library. Even more, the books told me what (not) to eat and drink before the day, and I became stressed by this, too.</p>

<p>On Sunday evening I was still changing the demos a bit. The presentation was due on Tuesday morning.</p>

<h2 id="the-d-day">The D-Day</h2>

<p>Initially, I thought I wouldn’t be nervous, why would I? I had previously spoken in front of large audiences at my company. However, I got an upset stomach the day before the talk, probably due to stress. Thank God, the problem of eating got solved - for breakfast, I only ate toast with a little bit of feta cheese, and drank some tea.</p>

<p>In the morning, I joined my colleagues at the Sonar booth (after my talk got accepted, Sonar decided to sponsor the conference). Then I went to the opening key note (a brilliant talk by Mr. Richard Campbell on the History of .NET - very well delivered, I must say). I stayed at the Sonar booth for an hour after, to calm my thoughts and allow my colleagues to go and watch some talks in the first batch. There wasn’t much activity at the booth, so I could calm down.</p>

<p>Fortunately, my talk was scheduled at 10h45, in the second batch, so I did not have to wait a lot. I went there 15 minutes before the talk, as instructed by the organizers. I met the volunteers from the local Swiss .NET community. I plugged in the laptop, verified the contrast of the console and the IDE, changed it from dark to bright at their advice. Attached the microphone, prepared the “Evil Hacker” outfit for later in the talk when I would need it, and I was ready.</p>

<p>I did not have any stage fright. On the contrary, I felt like a fish in the water. My colleague Mary told me there were 50-60 people in the cinema room, less that a normal “Sonar” BBL audience. I had great fun, I did not have any irreparable demo effects, the audience laughed at the “funny” moments. I managed to deliver the talk on time, finishing a couple of minutes earlier.</p>

<p>Furthermore, I got great feedback from people later during the conference. The “Evil Hacker” persona was very well received. And I also got nine pieces of feedback via the feedback form I put on my website. Most of it positive.</p>

<p>Thank God, I accomplished my mission. The session was not recorded, but the slides I used are public on <a href="https://speakerdeck.com/dotnetday/dot-net-day-22-dependency-confusion-and-its-cure-a-nuget-story-by-andrei-epure">speakerdeck</a>.</p>

<p>There were other cool stuff like the speakers dinner (I got to talk with Richard Campbell for two hours on a variety of topics) and having breakfast at the hotel the second day with renowned speakers. Maybe I’ll write about that at a later date.</p>

<h1 id="visugxl-belgium-2022">VisugXL Belgium 2022</h1>

<p>In September I had applied to another .NET community conference (<a href="https://www.visug.be/Events/80">VisugXL</a>) at the end of October, this time in Belgium, and got accepted. I changed the title from “Dependency confusion and its cure. A NuGet story.” to “How to attack a .NET software supply chain”, because one of the feedback I got was that the title was very confusing and mysterious. I also changed the description on Sessionize and included verbatim excerpts from the .NET Day Switzerland feedbacks in the “note to the organizers” section, to “sell” myself.</p>

<p>Before leaving to Belgium I did another dry run - two months had passed since my talk in Zurich, I had to rehearse my talk and the demos. This time, I did it alone, as I was confident on the quality of my presentation. Also, I had modified the slides a little, improving them and adding more content, as this time I had a 60 minutes slot. I removed some slides from the beginning which I considered not so important and I added a “use a lock file” section in the presentation.</p>

<p>Because Sonar paid for the plane and hotel, the organizers gave us a sponsor table at the conference (VisugXL is a small one-day conference, on a tight budget). I went there alone, as a one-man team - I stayed at the booth from morning ‘till I entered the conference room at 15h45. It was a great opportunity to talk with various people, both who knew our products and had various questions or remarks, as well as people who never heard of SonarQube or SonarLint before.</p>

<p>This time I had 26 people in the room, as opposed to the experience in Zurich, here the audience was much more interactive - they were asking questions on the go, which was quite nice. And at the end, we spent roughly 15 minutes discussing various topics. I went over the timebox, but it was the last presentation so that was ok (I planned 50 minutes of presentation and 10 minutes of Q&amp;A, but all in all there were around 20-25 minutes of Q&amp;A instead, hence the spillover). That was a great learning experience, because some of the folks in the room were quite senior and knew many topics better than me! Exposing my own ignorance and learning is one of the reasons started to speak at conferences.</p>

<p>At the end of the day, one of the organizers who watched my talk told me that I could also apply for Techorama. For me, this small interaction was very rewarding.</p>

<h1 id="geneva-net-user-group">Geneva .NET User Group</h1>

<p>The last session I gave was at my local .NET User Group in Geneva. Like before, I did a dry run before, to make sure the demos still work and that I have a nice flow of ideas. It was on Thursday the 10th of December. Unfortunately, there were only five people in the room, but each of them appreciated the talk, said they learned new things they can apply in their day to day work, and this is a great reward for me as a speaker. The audience was again interactive, asking questions as I was speaking. From some of the interactions I got ideas of hobby projects I could do and I started to think about my next public speaking subjects.</p>

<h1 id="the-rejections">The rejections</h1>

<p>This year was my first year as a public speaker. If you aspire to become a speaker at developer conferences, bear in mind that I applied to six conferences in 2022 and only got accepted at two of them. I have a better acceptance ratio at user groups :) (two out of two), so it might be better to start with user groups before applying to developer conferences.</p>

<h1 id="2023">2023</h1>

<p>2022 was a great year, I worked a lot for my public speaking debut, I learned a lot from the process, I met a lot of interesting people, I got a plethora of positive feedback and good vibes from the two conferences I participated at.</p>

<p>Last, but not least, one of the .NET Day volunteers told me after my session: “I understood that this was the first time you spoke on a stage. You did very well, you really should continue doing this.”</p>

<p>I don’t plan to stop here, I have some ideas for other talks and I will try to get accepted at bigger developer conferences next year.</p>

<p>However, it will be a lot of work to get there, as I am doing this mostly in my spare time.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[The mind cannot continue in one and the same condition, I mean without receiving addition to or diminution of its good qualities. For to fail to gain new ones, is to lose them, because when the desire of making progress ceases, there the danger of going back is present. (Abbot Theodore in “The Conferences of Desert Fathers” by St. John Cassian)]]></summary></entry><entry><title type="html">Write a target file to execute arbitrary code</title><link href="andreiepure.ro/2022/11/08/write-a-target-file-to-execute-arbitrary-code.html" rel="alternate" type="text/html" title="Write a target file to execute arbitrary code" /><published>2022-11-08T00:00:00+00:00</published><updated>2022-11-08T00:00:00+00:00</updated><id>andreiepure.ro/2022/11/08/write-a-target-file-to-execute-arbitrary-code</id><content type="html" xml:base="andreiepure.ro/2022/11/08/write-a-target-file-to-execute-arbitrary-code.html"><![CDATA[<p>You can read an <a href="https://andreiepure.ro/2022/11/01/msbuild-vocabulary.html">introduction about the MSBuild scripting language</a>.</p>

<p>Let’s write a target file that opens a browser when being executed.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;Project&gt;
	&lt;UsingTask
	  TaskName="OpenRemoteImage"
	  TaskFactory="RoslynCodeTaskFactory"
	  AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" &gt;
		&lt;ParameterGroup /&gt;
		&lt;Task&gt;
			&lt;Using Namespace="System.Diagnostics"/&gt;
			&lt;Code Type="Fragment" Language="cs"&gt;
&lt;![CDATA[
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.FileName = "https://raw.githubusercontent.com/andreiepure/andreiepure.github.io/master/assets/Evil_Hacker.jpg";
            startInfo.UseShellExecute = true;
            Process process = new Process();
            process.StartInfo = startInfo;
            process.Start();
]]&gt;
			&lt;/Code&gt;
		&lt;/Task&gt;
	&lt;/UsingTask&gt;
	&lt;Target Name="ExecuteArbitraryCode" AfterTargets="CoreBuild"&gt;
		&lt;Warning Text="Arbitrary code executed from this task."/&gt;
		&lt;OpenRemoteImage/&gt;
	&lt;/Target&gt;
&lt;/Project&gt;
</code></pre></div></div>

<p>This target file:</p>
<ul>
  <li>defines a Task inside of it (<code class="language-plaintext highlighter-rouge">UsingTask</code>) and opens an URL with the default browser. This is a plain C# program, so you can write anything inside (whatever allows the build process to execute).
    <ul>
      <li>“RoslynCodeTaskFactory” allows creating inline tasks (otherwise, an “AssemblyFile” attribute pointing to the task DLL should be used instead the “TaskFactory attribute)</li>
    </ul>
  </li>
  <li>defines a target which writes an warning message to the build output and invokes the defined task</li>
</ul>

<p>Save the above inside a “foo.target” and then execute</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dotnet msbuild foo.target
</code></pre></div></div>

<p>and you will see the warning in the build output an the browser window being opened.</p>

<h1 id="whats-next">What’s next?</h1>

<p>You can insert this malicious target file in a NuGet file and distribute to the entire world. I will write more about that in a future article.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[You can read an introduction about the MSBuild scripting language.]]></summary></entry><entry><title type="html">MSBuild vocabulary</title><link href="andreiepure.ro/2022/11/01/msbuild-vocabulary.html" rel="alternate" type="text/html" title="MSBuild vocabulary" /><published>2022-11-01T00:00:00+00:00</published><updated>2022-11-01T00:00:00+00:00</updated><id>andreiepure.ro/2022/11/01/msbuild-vocabulary</id><content type="html" xml:base="andreiepure.ro/2022/11/01/msbuild-vocabulary.html"><![CDATA[<h1 id="the-msbuild-scripting-language">The MSBuild scripting language</h1>

<p>MSBuild is the Microsoft Build Engine. What might be less known is that it offers a scripting language. An MSBuild file is usually a script, orchestrating what happens during the build process.</p>

<h2 id="concepts">Concepts</h2>

<p>The MSBuild scripting language concepts:</p>
<ul>
  <li><em>properties</em> are variables; some <a href="https://learn.microsoft.com/en-us/visualstudio/msbuild/common-msbuild-project-properties">are reserved</a>; some are <a href="https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-reserved-and-well-known-properties">predefined by MSBuild</a> during the build process; others are environment variables; and others are customized in MSBuild projects and props files</li>
  <li><em>items</em> are <a href="https://learn.microsoft.com/en-us/visualstudio/msbuild/common-msbuild-project-items">inputs in the build system</a>, usually files - these are used to include or exclude files from the build process; each item has <a href="https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-well-known-item-metadata">some metadata</a> attached to it</li>
  <li><em>tasks</em> are atomic build operations, like “compile” or “copy file”; there are plenty <a href="https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-task-reference">built-in tasks</a>, and you can define your own by extending <a href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.build.utilities.task"><code class="language-plaintext highlighter-rouge">Microsoft.Build.Utilities.Task</code></a>; a task must be present inside a target in order to be executed</li>
  <li><em>targets</em> are groups of tasks to be executed together; they enable sections of the build process to be called from the command line with the <code class="language-plaintext highlighter-rouge">-target:</code> <a href="https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-command-line-reference">switch</a>
    <ul>
      <li>targets can have attributes that specify the order of operations (<code class="language-plaintext highlighter-rouge">InitialTargets</code>; <code class="language-plaintext highlighter-rouge">DependsOnTarget</code>; <code class="language-plaintext highlighter-rouge">BeforeTarget</code>) - MSBuild uses this information to build a Direct Acyclic Graph of targets to execute</li>
      <li>each target runs <strong>only once</strong> in a single build</li>
    </ul>
  </li>
</ul>

<h2 id="convention">Convention</h2>

<p>MSBuild offers an XML scripting language. By convention, MSBuild files have a limited set of extensions. However, it is only a convention - any of the below files (or a simple <code class="language-plaintext highlighter-rouge">.xml</code> file) can hold the definition of MSBuild properties, tasks and targets. That being said, by convention there are three types of files:</p>
<ul>
  <li>project files (<code class="language-plaintext highlighter-rouge">.csproj</code>, <code class="language-plaintext highlighter-rouge">.vbproj</code>, <code class="language-plaintext highlighter-rouge">.esproj</code> etc)</li>
  <li>target files (<code class="language-plaintext highlighter-rouge">.target</code>)
    <ul>
      <li>The <code class="language-plaintext highlighter-rouge">Microsoft.NET.Sdk</code> target file is referenced in .NET csproj files (<code class="language-plaintext highlighter-rouge">&lt;Project Sdk="Microsoft.NET.Sdk"&gt;</code>)</li>
      <li>The <code class="language-plaintext highlighter-rouge">Directory.Build.target</code> file is picked up by MSBuild as a customization file in the folder structure of your project</li>
    </ul>
  </li>
  <li>property files (<code class="language-plaintext highlighter-rouge">.props</code>)
    <ul>
      <li>The <code class="language-plaintext highlighter-rouge">Directory.Build.props</code> file can hold build config and is picked up by MSBuild</li>
    </ul>
  </li>
</ul>

<p>Tasks are normally kept in libraries (DLLs) which are referenced by other files.
MSBuild files can import other MSBuild files. Usually <em>target</em> files reference other <em>target</em> files.</p>

<p>Microsoft offers very good documentation each of these <a href="https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-concepts">MSBuild concepts</a>.</p>

<h1 id="hello-world-script">Hello World script</h1>

<p>Create a file, name it “hello.txt” and paste the content below.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;Project&gt;
	&lt;Target Name="ExecuteArbitraryCode" AfterTargets="CoreBuild"&gt;
		&lt;Warning Text="Hello, World!"/&gt;
	&lt;/Target&gt;
&lt;/Project&gt;
</code></pre></div></div>

<p>To execute it, run</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dotnet msbuild hello.txt --verbosity:quiet
</code></pre></div></div>
<p>It will output</p>

<blockquote>
  <p>MSBuild version 17.4.0+18d5aef85 for .NET
C:\blog\playground\hello.txt(4,3): warning : Hello, World!</p>
</blockquote>

<p>Congratulations! You wrote your first MSBuild script.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[The MSBuild scripting language]]></summary></entry><entry><title type="html">How to secure your NuGet supply chain</title><link href="andreiepure.ro/2022/10/26/visugxl-resources.html" rel="alternate" type="text/html" title="How to secure your NuGet supply chain" /><published>2022-10-26T00:00:00+00:00</published><updated>2022-10-26T00:00:00+00:00</updated><id>andreiepure.ro/2022/10/26/visugxl-resources</id><content type="html" xml:base="andreiepure.ro/2022/10/26/visugxl-resources.html"><![CDATA[<p>You’ve probably arrived on this page after watching my talk <em>“How to attack a .NET software supply chain”</em> at the <a href="https://www.visug.be/Events/80">VisugXL</a> conference (October 2022 in Hasselt, Belgium), also presented under the name “How your .NET software supply chain is open to attack : and how to fix it” at Techorama Belgium (May 2023), Techorama Netherlands (October 2023) and WeAreDevelopers Berlin (July 2024). The source code for my demos <a href="https://github.com/andreiepure/DependencyConfusionDemo">is on GitHub</a>, feel free to use it when explaining these problems to your colleagues. In the <a href="https://github.com/andreiepure/DependencyConfusionDemo/tree/main/slides">“slides” folder</a> you can find the Techorama and WeAreDevelopers slides.</p>

<p>As a reminder, these are the easy steps to do in order to secure you NuGet supply chain against typosquatting and dependency confusion supply chain attacks:</p>

<ol>
  <li>Use <code class="language-plaintext highlighter-rouge">&lt;clear /&gt;</code> to avoid inheriting the system configuration (because of <a href="https://learn.microsoft.com/en-us/nuget/consume-packages/configuring-nuget-behavior#how-settings-are-applied">how settings are applied in NuGet</a>). By using <code class="language-plaintext highlighter-rouge">&lt;clear /&gt;</code>, you ensure the NuGet resolution of your builds are fully deterministic and repeatable.</li>
  <li>Use <a href="https://docs.microsoft.com/en-us/nuget/consume-packages/package-source-mapping">Package Source Mapping</a> if you have a hybrid (private and public) configuration, to be protected against dependency confusion attacks. You can use the <a href="https://www.nuget.org/packages/NuGet.PackageSourceMapper#readme-body-tab">NuGet.PackageSourceMapper</a> tool to help you generate the configuration for your repository. Alternatively, instead of using multiple package sources, configure only a single package source and control which packages you mirror from the public source in your private source.</li>
  <li>Use <code class="language-plaintext highlighter-rouge">&lt;trusted signers&gt;</code>: see <a href="https://docs.microsoft.com/en-us/nuget/consume-packages/installing-signed-packages">Manage package trust boundaries</a>. You can use trusted signers for both signed packages (when you will provide the certificate hash), and for unsigned packages (by simply providing the name of the account that published the package you trust). This will help defend your project against unwanted typosquatting attacks.</li>
  <li>Reserve prefixes for both your public and private packages on nuget.org: <a href="https://docs.microsoft.com/en-us/nuget/nuget-org/id-prefix-reservation">Package ID prefix reservation</a>. It is important to reserve the prefixes for your private packages so that malicious users won’t publish public packages with those names, to attempt dependency confusion attacks. Reserving prefixes for public packages also reduces the surface attack of typosquatting attacks.</li>
</ol>

<p>These are my top recommendations. You can find more on Microsoft’s <a href="https://learn.microsoft.com/en-us/nuget/concepts/security-best-practices">NuGet Security Best Practices</a>.</p>

<p>In addition, to have the overview of all your direct and transitive dependencies and be aware of changes in your dependency graph <a href="https://devblogs.microsoft.com/nuget/enable-repeatable-package-restores-using-a-lock-file/">use a NuGet lock file</a>.</p>

<p>Moreover, a general good practice is to use fixed (pinned) versions for your dependencies, to limit the surface of a dependency confusion attack.</p>

<p>Last but not least, if you sign the packages you publish (both public and private ones), you enable your consumers to use <code class="language-plaintext highlighter-rouge">&lt;trusted signers&gt;</code> in the best way possible, by also verifying the signature of the owner (not only the signature of the repository).</p>

<p>Some real life NuGet configurations:</p>
<ul>
  <li><a href="https://github.com/SonarSource/sonar-dotnet/blob/8.47.0.55603/analyzers/NuGet.Config">sonar .NET analyzers</a> (and check also one of the <a href="https://github.com/SonarSource/sonar-dotnet/blob/8.47.0.55603/analyzers/src/SonarAnalyzer.CSharp/packages.lock.json">lock files</a>)</li>
  <li><a href="https://github.com/SonarSource/sonar-scanner-msbuild/blob/5.8.0.52797/NuGet.Config">Sonar Scanner for .NET</a></li>
  <li><a href="https://github.com/NuGet/NuGetGallery/blob/v2022.10.19/NuGet.config">NuGetGallery</a></li>
</ul>

<p>For more docs from Microsoft and more resources on software supply chain attacks, read the second part of <a href="https://andreiepure.ro/2022/08/28/dotnetday-resources.html">this post</a>.</p>

<p>Last, but not least: <a href="https://www.sonarsource.com/company/careers/">we’re hiring at Sonar</a>!</p>

<table>
  <thead>
    <tr>
      <th>Version Date</th>
      <th style="text-align: center">Change</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>2022-10-26</td>
      <td style="text-align: center">Initial version</td>
    </tr>
    <tr>
      <td>2024-07-15</td>
      <td style="text-align: center">Update title, mention other talks, remove 2022 feedback form. Add reference to the NuGet.PackageSourceMapper tool. Mention <code class="language-plaintext highlighter-rouge">&lt;clear /&gt;</code>. Add more details. Mention using fixed versions. Move link to github at the beginning of the article.</td>
    </tr>
  </tbody>
</table>]]></content><author><name></name></author><summary type="html"><![CDATA[You’ve probably arrived on this page after watching my talk “How to attack a .NET software supply chain” at the VisugXL conference (October 2022 in Hasselt, Belgium), also presented under the name “How your .NET software supply chain is open to attack : and how to fix it” at Techorama Belgium (May 2023), Techorama Netherlands (October 2023) and WeAreDevelopers Berlin (July 2024). The source code for my demos is on GitHub, feel free to use it when explaining these problems to your colleagues. In the “slides” folder you can find the Techorama and WeAreDevelopers slides.]]></summary></entry><entry><title type="html">.NET Day Switzerland 2022 Resources (Dependency Confusion)</title><link href="andreiepure.ro/2022/08/28/dotnetday-resources.html" rel="alternate" type="text/html" title=".NET Day Switzerland 2022 Resources (Dependency Confusion)" /><published>2022-08-28T00:00:00+00:00</published><updated>2022-08-28T00:00:00+00:00</updated><id>andreiepure.ro/2022/08/28/dotnetday-resources</id><content type="html" xml:base="andreiepure.ro/2022/08/28/dotnetday-resources.html"><![CDATA[<p>You probably arrived on this page after watching <a href="https://dotnetday.ch/speakers/andrei-epure.html">my talk about Dependency Confusion</a> at .NET Day Switzerland on the 30th of August 2022.</p>

<p>As a reminder, these are the three easy steps to do in order to secure you NuGet supply chain against dependency confusion attacks (links to Microsoft docs):</p>

<ol>
  <li>Use <a href="https://docs.microsoft.com/en-us/nuget/consume-packages/package-source-mapping">Package Source Mapping</a></li>
  <li>Use <code class="language-plaintext highlighter-rouge">&lt;trusted signers&gt;</code>: <a href="https://docs.microsoft.com/en-us/nuget/consume-packages/installing-signed-packages">Manage package trust boundaries</a></li>
  <li>Reserve prefixes for both your public and private packages on nuget.org: <a href="https://docs.microsoft.com/en-us/nuget/nuget-org/id-prefix-reservation">Package ID prefix reservation</a></li>
</ol>

<p>The source code for my demos <a href="https://github.com/andreiepure/DependencyConfusionDemo">is on GitHub</a>, feel free to use it when explaining the problem to your colleagues.</p>

<p>More docs from Microsoft:</p>
<ul>
  <li><a href="https://docs.microsoft.com/en-us/nuget/concepts/security-best-practices">NuGet Best practices for a secure software supply chain</a></li>
  <li>For Maven, Gradle, NuGet, npm, Pip, Yarn: <a href="https://azure.microsoft.com/en-us/resources/3-ways-to-mitigate-risk-using-private-package-feeds/">3 Ways to Mitigate Risk When Using Private Package Feeds</a></li>
  <li><a href="https://docs.microsoft.com/en-us/nuget/concepts/msbuild-props-and-targets">MSBuild .props and .targets in a NuGet package</a></li>
  <li><a href="https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-inline-tasks?view=vs-2022">MSBuild inline tasks</a></li>
</ul>

<p>You can read about the NuGet historical design decision of having a non-deterministic package resolution behavior for hybrid configurations (fetching packages from all configured sources in parallel): <a href="https://github.com/NuGet/Home/issues/5611">NuGet/Home#5611</a>.</p>

<p>About substitution attacks - the original article by security researcher Alex Bîrsan from Romania: <a href="https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610">Dependency Confusion: How I Hacked Into Apple, Microsoft, and Dozens of Other Companies</a>.</p>

<p>About typosquatting:</p>
<ul>
  <li><a href="https://incolumitas.com/2016/06/08/typosquatting-package-managers/">Typosquatting programming language package managers (2016)</a> in the NPM, PyPi and rubygems ecosystems</li>
  <li><a href="https://blog.reversinglabs.com/blog/iconburst-npm-software-supply-chain-attack-grabs-data-from-apps-websites">IconBurst NPM software supply chain attack grabs data from apps and websites (2022)</a> in the NPM ecosystem</li>
</ul>

<p>About the SolarWinds breach:</p>
<ul>
  <li>overview, timeline: <a href="https://orangematter.solarwinds.com/2021/01/11/new-findings-from-our-investigation-of-sunburst/">New Findings From Our Investigation of SUNBURST</a></li>
  <li>technical explanation of SUNSPOT, the malicious tool that was deployed into the SolarWinds build environment: <a href="https://www.crowdstrike.com/blog/sunspot-malware-technical-analysis/">SUNSPOT: An Implant in the Build Process.</a></li>
  <li>technical explanation of SUNBURST, the trojan shipped inside Orion: <a href="https://www.mandiant.com/resources/blog/evasive-attacker-leverages-solarwinds-supply-chain-compromises-with-sunburst-backdoor">Highly Evasive Attacker Leverages SolarWinds Supply Chain to Compromise Multiple Global Victims With SUNBURST Backdoor</a></li>
  <li><a href="https://www.mandiant.com/resources/blog/sunburst-additional-technical-details">SUNBURST Additional Technical Details</a></li>
  <li>list of victims: <a href="https://www.datacenterknowledge.com/security/list-known-solarwinds-breach-victims-grows-do-attack-vectors">The List of Known SolarWinds Breach Victims Grows, as Do Attack Vectors</a></li>
</ul>

<p>C. Augusto Proiete demonstrated that NuGet packages can execute arbitrary code in 2019 -  <a href="https://github.com/augustoproiete/i-am-root-nuget-package">i-am-root-nuget-package</a>.</p>

<p>Whether you enjoyed or not my talk, please fill in this <a href="https://forms.gle/t5JVPzQLUWQGy1vF9">Feedback form (Google Form, anonymous)</a>.</p>

<p>Last, but not least: <a href="https://www.sonarsource.com/company/careers/">we’re hiring at Sonar</a>!</p>]]></content><author><name></name></author><summary type="html"><![CDATA[You probably arrived on this page after watching my talk about Dependency Confusion at .NET Day Switzerland on the 30th of August 2022.]]></summary></entry><entry><title type="html">Replaceable developer manifesto</title><link href="andreiepure.ro/2022/06/07/replaceable-developer-manifesto.html" rel="alternate" type="text/html" title="Replaceable developer manifesto" /><published>2022-06-07T00:00:00+00:00</published><updated>2022-06-07T00:00:00+00:00</updated><id>andreiepure.ro/2022/06/07/replaceable-developer-manifesto</id><content type="html" xml:base="andreiepure.ro/2022/06/07/replaceable-developer-manifesto.html"><![CDATA[<blockquote>
  <p>And whatsoever you do, do it heartily, as to the Lord, and not unto men (Colossians 3:23)</p>
</blockquote>

<p>I believe that we developers should strive to be replaceable.</p>

<p>What is a “replaceable developer,” in my opinion? One that:</p>

<ol>
  <li>puts team cohesion and goals over own goals</li>
  <li>continuously hands over knowledge to his team (organically)</li>
  <li>continuously learns from their peers (through code reviews, discussions, pair coding, etc.)</li>
  <li>helps colleagues grow towards becoming replaceable developers (for example, through feedback and guidance)</li>
</ol>

<p>Consequently, a “replaceable developer” continuously increases the team’s bus factor, avoiding “knowledge silos.”</p>

<p>And from an individual contributor’s point of view, a replaceable developer:</p>

<ol type="a">
  <li>writes clean code</li>
  <li>ensure his code has high code coverage and high scenario coverage in test automation
</li>
  <li>writes minimal, essential documentation when needed</li>
</ol>

<p>Points a-c are necessary for any sane developer, for their own sake, not only their team’s.</p>

<p>Thus a replaceable developer brings high value to any team and company. If a “replaceable developer” is sick, takes a sabbatical, or leaves the company, there would be no delivery problem for the team. Consequently, everyone should want and keep “replaceable developers” in their group.</p>

<p>I am aware that agile methodologies are supposed to ensure by design that <em>“nobody on the team is indispensable.”</em> And the desire to be replaceable fits very well within the agile mindset. However, replaceability is more than applying a methodology; it is a working principle.</p>

<p>Becoming a replaceable developer takes time, effort, perseverance, and a healthy work environment. And I believe it is worth it!</p>

<hr />

<p><em>Thanks to Liviu, Ghennadi, and Paul for reading drafts of this.</em></p>]]></content><author><name></name></author><summary type="html"><![CDATA[And whatsoever you do, do it heartily, as to the Lord, and not unto men (Colossians 3:23)]]></summary></entry><entry><title type="html">Roborock privacy policy</title><link href="andreiepure.ro/2020/12/28/roborock-privacy-policy.html" rel="alternate" type="text/html" title="Roborock privacy policy" /><published>2020-12-28T00:00:00+00:00</published><updated>2020-12-28T00:00:00+00:00</updated><id>andreiepure.ro/2020/12/28/roborock-privacy-policy</id><content type="html" xml:base="andreiepure.ro/2020/12/28/roborock-privacy-policy.html"><![CDATA[<p>My wife and I decided to buy a robot vacuum cleaner to improve the comfort of our home. After asking my work colleagues on one of our informal slack channels about their experience, we’ve spend a couple of hours reading reviews on digitec.ch of Roomba and Roborock vacuum cleaners. The Roborock S5 Max had lots of positive reviews and an entry-level price, so we ordered one. We’ve unpacked it on the 27th of December, and after setting it up, I had to install the Roborock Android app on my phone.</p>

<h1 id="the-privacy-policy">The Privacy Policy</h1>

<p>As I like to read the Terms and Conditions and the Privacy Policies before agreeing with them, I spent around 1 hour doing so. And I found some interesting stuff. Note that the following quotes are from the Roborock Privacy Policy which was available inside their Android app on the 27th of December 2020. By the time you read this, things may have changed.</p>

<blockquote>
  <p>“Your personal information will be retained for as long as necessary to fulfill the purpose for which it was collected, or as required or permitted by applicable laws. […] Roborock will continue to retain any data which will be further processed solely for achieving purposes in the public interest, scientific or historical research purposes, or statistical purposes, even if the further processing of such data has nothing to do with the purpose for which it was collected.”</p>
</blockquote>

<p>My problem is that they didn’t mention anonymity here… Basically, they collect data for purpose X and then can use it indefinitely for any purpose, as the categories they mention are vague. Of course, being a Romanian citizen, I am also a European Union citizen and can ask for data deletion, by sending an email to privacy <em>at</em> roborock-eu <em>dot</em> com. Long live the GDPR!</p>

<blockquote>
  <p>“If you are a European Union user under the GDPR, your personal information will be stored on the server in Germany.” ✌️</p>
</blockquote>

<p>Another advantage of the EU.</p>

<blockquote>
  <p>“Our Privacy Policy does not apply to products or services offered by any third party. […] we strongly recommend that you read the third party’s privacy policy, just as you have taken time to read ours.”</p>
</blockquote>

<p>Initially after reading this, I had the impression they were breaching GDPR, because they didn’t mention which 3rd party providers they use. So I sent an email to dpo <em>at</em> roborock <em>dot</em> com and asked them to clarify. They replied within 12 hours, mentioning:</p>

<blockquote>
  <p>“[…] the third party mentioned in the privacy policy refers to the services provided by other companies that can be used in Roborock app, such as Amazon’s Alexa speakers. Because when you choose the service provided by a third party, you will learn about its data processing through the app, and the data will only be transmitted to the third party after you explicitly agree. Third-party services do not belong to the basic services provided by the app, and the supported services may increase with the upgrade of functions. Therefore, the privacy policy does not disclose the list of all third-party services supported. However, you can learn about the specific situation of the third party through the pop-up prompt in the app before using the related service.”</p>
</blockquote>

<p>That’s pretty good customer service. It was a nice surprise.</p>

<h1 id="the-password-policy">The Password Policy</h1>

<p>After accepting the T&amp;C and Privacy Policy, I had to create an account and choose a password. Here, I had a really bad surprise: they ask for 6-12 chars passwords. Yes. 2020, almost 2021. Maximum 12 characters. The Roborock company ensuring that your password can be cracked without burning too much fuel.</p>

<p><img src="/assets/2020-12-28-roborock-privacy-policy.jpg" alt="roborock-password-policy" /></p>

<p>Obviously, I accepted all of this because I want to use my little robot 🤓🤖. But still a bad experience.</p>

<h1 id="the-robot-experience">The robot experience</h1>

<p>As I write this article, we have used the robot twice: first to create a map while vacuuming our home, and the second day just vacuuming. For 34 square metres, it first took 40 minutes (while creating the map) and the second time it took 30 minutes. We can watch the cleaning history in the app, what trajectory the robot took in each session. All in all, it was really easy to setup. The robot is pretty smart, gentle on the furniture when bumping into it and quite organized when moving in the home.</p>

<h1 id="later-update-2021-10-24">Later update (2021-10-24)</h1>

<p>This blog post does not suggest that your privacy is respected by Roborock. I do not know how my data is being used. Also, it is worth pondering whether these gimmicks are truly necessary or not (because <a href="https://paulkingsnorth.substack.com/p/want-is-the-acid">Want is the Acid</a> consuming our planet). I haven’t used my Roborock in the past 4 months and I don’t necessarily miss it.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[My wife and I decided to buy a robot vacuum cleaner to improve the comfort of our home. After asking my work colleagues on one of our informal slack channels about their experience, we’ve spend a couple of hours reading reviews on digitec.ch of Roomba and Roborock vacuum cleaners. The Roborock S5 Max had lots of positive reviews and an entry-level price, so we ordered one. We’ve unpacked it on the 27th of December, and after setting it up, I had to install the Roborock Android app on my phone.]]></summary></entry></feed>